Skip to content

Commit

Permalink
fix: limit data model fetching to models folder (#14625)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomas Engebretsen <[email protected]>
  • Loading branch information
ErlingHauan and TomasEng authored Feb 13, 2025
1 parent f2a6c5c commit 9b93ad0
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ public class AltinnAppGitRepository : AltinnGitRepository
private static string ProcessDefinitionFilePath => Path.Combine(ProcessDefinitionFolderPath, ProcessDefinitionFilename);

private const string LayoutSettingsSchemaUrl = "https://altinncdn.no/schemas/json/layout/layoutSettings.schema.v1.json";

private const string LayoutSchemaUrl = "https://altinncdn.no/schemas/json/layout/layout.schema.v1.json";

private const string TextResourceFileNamePattern = "resource.??.json";
private const string SchemaFilePatternJson = "*.schema.json";
private const string SchemaFilePatternXsd = "*.xsd";

public static readonly string InitialLayoutFileName = "Side1.json";

Expand Down Expand Up @@ -976,6 +977,41 @@ public List<string> GetAllImageFileNames()
return allFilePaths;
}

/// <summary>
/// Finds all schema files in App/models directory.
/// </summary>
public IList<AltinnCoreFile> GetSchemaFiles(bool xsd = false)
{
string schemaFilesPattern = xsd ? SchemaFilePatternXsd : SchemaFilePatternJson;
string schemaFilesPath = Path.Combine(ModelFolderPath, schemaFilesPattern);
IEnumerable<string> schemaFiles;

try
{
schemaFiles = FindFiles(new[] { schemaFilesPath });
}
catch (DirectoryNotFoundException)
{
schemaFiles = new List<string>();
}

var altinnCoreSchemaFiles = MapFilesToAltinnCoreFiles(schemaFiles);

return altinnCoreSchemaFiles;
}

private List<AltinnCoreFile> MapFilesToAltinnCoreFiles(IEnumerable<string> schemaFiles)
{
List<AltinnCoreFile> altinnCoreSchemaFiles = new();

foreach (string file in schemaFiles)
{
altinnCoreSchemaFiles.Add(AltinnCoreFile.CreateFromPath(file, RepositoryDirectory));
}

return altinnCoreSchemaFiles;
}

/// <summary>
/// Gets the relative path to a json schema model.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
Expand All @@ -23,10 +22,7 @@ namespace Altinn.Studio.Designer.Infrastructure.GitRepository
/// and not any methods that are specific to App or Datamodels repositories.</remarks>
public class AltinnGitRepository : GitRepository, IAltinnGitRepository
{
private const string SCHEMA_FILES_PATTERN_JSON = "*.schema.json";
private const string SCHEMA_FILES_PATTERN_XSD = "*.xsd";
private const string STUDIO_SETTINGS_FILEPATH = ".altinnstudio/settings.json";
private const string TEXT_FILES_PATTERN_JSON = "*.texts.json";

private AltinnStudioSettings _altinnStudioSettings;

Expand Down Expand Up @@ -80,19 +76,6 @@ public async Task SaveAltinnStudioSettings(AltinnStudioSettings altinnStudioSett
await WriteObjectByRelativePathAsync(STUDIO_SETTINGS_FILEPATH, altinnStudioSettings, true);
}

/// <summary>
/// Finds all schema files regardless of location in repository.
/// </summary>
public IList<AltinnCoreFile> GetSchemaFiles(bool xsd = false)
{
string schemaFilesPattern = xsd ? SCHEMA_FILES_PATTERN_XSD : SCHEMA_FILES_PATTERN_JSON;
var schemaFiles = FindFiles(new[] { schemaFilesPattern });

var altinnCoreSchemaFiles = MapFilesToAltinnCoreFiles(schemaFiles);

return altinnCoreSchemaFiles;
}

/// <summary>
/// Parses the filename and extracts the logical schema name.
/// </summary>
Expand Down Expand Up @@ -242,17 +225,5 @@ private bool IsDatamodelsRepo()
{
return Repository.Contains("-datamodels");
}

private List<AltinnCoreFile> MapFilesToAltinnCoreFiles(IEnumerable<string> schemaFiles)
{
List<AltinnCoreFile> altinnCoreSchemaFiles = new();

foreach (string file in schemaFiles)
{
altinnCoreSchemaFiles.Add(AltinnCoreFile.CreateFromPath(file, RepositoryDirectory));
}

return altinnCoreSchemaFiles;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ public SchemaModelService(
/// <inheritdoc/>
public IList<AltinnCoreFile> GetSchemaFiles(AltinnRepoEditingContext altinnRepoEditingContext, bool xsd = false)
{
var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer);
var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer);

return altinnGitRepository.GetSchemaFiles(xsd);
return altinnAppGitRepository.GetSchemaFiles(xsd);
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,54 @@ public async Task CreateOrOverwriteOptions_WithAppThatHasOptionLists_ShouldOverw
Assert.Equal(newOptionsListString, savedOptionsList);
}

[Theory]
[InlineData("ttd", "apps-test", "testUser", 0)]
[InlineData("ttd", "ttd-datamodels", "testUser", 0)]
[InlineData("ttd", "hvem-er-hvem", "testUser", 7)]
public async Task GetSchemaFiles_FilesExist_ShouldReturnFiles(string org, string repository, string developer, int expectedSchemaFiles)
{
string targetRepository = TestDataHelper.GenerateTestRepoName();
await TestDataHelper.CopyRepositoryForTest(org, repository, developer, targetRepository);
AltinnAppGitRepository altinnAppGitRepository = PrepareRepositoryForTest(org, targetRepository, developer);

var files = altinnAppGitRepository.GetSchemaFiles();

Assert.Equal(expectedSchemaFiles, files.Count);
}

[Fact]
public async Task GetSchemaFiles_FilesExist_ShouldReturnFilesWithCorrectProperties()
{
string org = "ttd";
string repository = "hvem-er-hvem";
string developer = "testUser";
string targetRepository = TestDataHelper.GenerateTestRepoName();

await TestDataHelper.CopyRepositoryForTest(org, repository, developer, targetRepository);
AltinnAppGitRepository altinnAppGitRepository = PrepareRepositoryForTest(org, targetRepository, developer);

var file = altinnAppGitRepository.GetSchemaFiles().First(f => f.FileName == "HvemErHvem_ExternalTypes.schema.json");

Assert.Equal(".json", file.FileType);
Assert.Equal(@"/App/models/HvemErHvem_ExternalTypes.schema.json", file.RepositoryRelativeUrl);
}

[Fact]
public async Task GetSchemaFiles_FilesExistOutsideModelsFolder_ShouldNotReturnFiles()
{
string org = "ttd";
string repository = "app-with-misplaced-datamodels";
string developer = "testUser";
string targetRepository = TestDataHelper.GenerateTestRepoName();

await TestDataHelper.CopyRepositoryForTest(org, repository, developer, targetRepository);
AltinnAppGitRepository altinnAppGitRepository = PrepareRepositoryForTest(org, targetRepository, developer);

var files = altinnAppGitRepository.GetSchemaFiles();

Assert.Empty(files);
}

private static AltinnAppGitRepository PrepareRepositoryForTest(string org, string repository, string developer)
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,6 @@ public void Constructor_InvalidPathParameters_ShouldThrowException()
Assert.Throws<ArgumentException>(() => new AltinnGitRepository("ttd", "hvem-er-hvem", "testUser", repositoriesRootDirectory, repositoryDirectory));
}

[Theory]
[InlineData("ttd", "apps-test", "testUser", 0)]
[InlineData("ttd", "ttd-datamodels", "testUser", 0)]
[InlineData("ttd", "hvem-er-hvem", "testUser", 7)]
public void GetSchemaFiles_FilesExist_ShouldReturnFiles(string org, string repository, string developer, int expectedSchemaFiles)
{
var repositoriesRootDirectory = TestDataHelper.GetTestDataRepositoriesRootDirectory();
var altinnGitRepositoryFactory = new AltinnGitRepositoryFactory(repositoriesRootDirectory);

var altinnGitRepository = altinnGitRepositoryFactory.GetAltinnGitRepository(org, repository, developer);
var files = altinnGitRepository.GetSchemaFiles();

Assert.Equal(expectedSchemaFiles, files.Count);
}

[Fact]
public void GetSchemaFiles_FilesExist_ShouldReturnFilesWithCorrectProperties()
{
var altinnGitRepository = GetTestRepository("ttd", "hvem-er-hvem", "testUser");
var file = altinnGitRepository.GetSchemaFiles().First(f => f.FileName == "HvemErHvem_ExternalTypes.schema.json");

Assert.Equal(".json", file.FileType);
Assert.Equal(@"/App/models/HvemErHvem_ExternalTypes.schema.json", file.RepositoryRelativeUrl);
}

[Fact]
public async Task RepositoryType_SettingsExists_ShouldUseThat()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public async Task DeleteSchema_ModelsRepo_ShouldDelete()
{
// Arrange
var org = "ttd";
var sourceRepository = "xyz-datamodels";
var sourceRepository = "hvem-er-hvem";
var developer = "testUser";
var targetRepository = TestDataHelper.GenerateTestRepoName();
var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, targetRepository, developer);
Expand All @@ -125,15 +125,15 @@ public async Task DeleteSchema_ModelsRepo_ShouldDelete()
{

var schemaFiles = _schemaModelService.GetSchemaFiles(editingContext);
Assert.Equal(6, schemaFiles.Count);
Assert.Equal(7, schemaFiles.Count);

// Act
var schemaToDelete = schemaFiles.First(s => s.FileName == "Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES.schema.json");
await _schemaModelService.DeleteSchema(editingContext, schemaToDelete.RepositoryRelativeUrl);

// Assert
schemaFiles = _schemaModelService.GetSchemaFiles(editingContext);
Assert.Equal(5, schemaFiles.Count);
Assert.Equal(6, schemaFiles.Count);
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"repotype": "datamodels",
"datamodelling.preference": "jsonSchema"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "http://altinn-repositories:3000/bjosttveit/v4-data/App/models/model.schema.json",
"info": {
"rootNode": ""
},
"@xsdNamespaces": {
"xsd": "http://www.w3.org/2001/XMLSchema",
"xsi": "http://www.w3.org/2001/XMLSchema-instance",
"seres": "http://seres.no/xsd/forvaltningsdata"
},
"@xsdSchemaAttributes": {
"AttributeFormDefault": "Unqualified",
"ElementFormDefault": "Qualified",
"BlockDefault": "None",
"FinalDefault": "None"
},
"@xsdRootElement": "model",
"type": "object",
"required": [
"property1",
"property2"
],
"properties": {
"property1": {
"type": "string"
},
"property2": {
"type": "string"
},
"property3": {
"type": "string"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:seres="http://seres.no/xsd/forvaltningsdata" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:documentation>
<xsd:attribute name="rootNode" fixed="" />
</xs:documentation>
</xs:annotation>
<xs:element name="model">
<xs:complexType>
<xs:sequence>
<xs:element name="property1" type="xs:string" />
<xs:element name="property2" type="xs:string" />
<xs:element minOccurs="0" name="property3" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xsd:schema>

0 comments on commit 9b93ad0

Please sign in to comment.