diff --git a/backend/src/Designer/Controllers/DatamodelsController.cs b/backend/src/Designer/Controllers/DatamodelsController.cs index bb115cc0d57..f7c57a88525 100644 --- a/backend/src/Designer/Controllers/DatamodelsController.cs +++ b/backend/src/Designer/Controllers/DatamodelsController.cs @@ -163,17 +163,17 @@ public async Task AddXsd(string org, string repository, [FromForm Request.EnableBuffering(); Guard.AssertArgumentNotNull(theFile, nameof(theFile)); - string fileName = GetFileNameFromUploadedFile(theFile); - Guard.AssertFileExtensionIsOfType(fileName, ".xsd"); + string fileNameWithExtension = GetFileNameFromUploadedFile(theFile); + Guard.AssertFileExtensionIsOfType(fileNameWithExtension, ".xsd"); string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, repository, developer); var fileStream = theFile.OpenReadStream(); - await _modelNameValidator.ValidateModelNameForNewXsdSchemaAsync(fileStream, fileName, editingContext); - string jsonSchema = await _schemaModelService.BuildSchemaFromXsd(editingContext, fileName, theFile.OpenReadStream(), cancellationToken); + await _modelNameValidator.ValidateModelNameForNewXsdSchemaAsync(fileStream, fileNameWithExtension, editingContext); + string jsonSchema = await _schemaModelService.BuildSchemaFromXsd(editingContext, fileNameWithExtension, theFile.OpenReadStream(), cancellationToken); - return Created(Uri.EscapeDataString(fileName), jsonSchema); + return Created(Uri.EscapeDataString(fileNameWithExtension), jsonSchema); } /// diff --git a/backend/src/Designer/Services/Implementation/SchemaModelService.cs b/backend/src/Designer/Services/Implementation/SchemaModelService.cs index 574bcaa4da2..3067a31d98d 100644 --- a/backend/src/Designer/Services/Implementation/SchemaModelService.cs +++ b/backend/src/Designer/Services/Implementation/SchemaModelService.cs @@ -21,7 +21,7 @@ using Altinn.Studio.Designer.Models; using Altinn.Studio.Designer.Models.App; using Altinn.Studio.Designer.Services.Interfaces; - +using Json.Schema; using Microsoft.Extensions.Logging; namespace Altinn.Studio.Designer.Services.Implementation @@ -97,9 +97,14 @@ public async Task UpdateSchema(AltinnRepoEditingContext altinnRepoEditingContext { cancellationToken.ThrowIfCancellationRequested(); var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); - var jsonSchema = Json.Schema.JsonSchema.FromText(jsonContent); + var schemaFileName = altinnAppGitRepository.GetSchemaName(relativeFilePath); + var jsonSchema = JsonSchema.FromText(jsonContent); var serializedJsonContent = SerializeJson(jsonSchema); + + await altinnAppGitRepository.SaveJsonSchema(serializedJsonContent, schemaFileName); + altinnAppGitRepository.DeleteModelMetadata(relativeFilePath.Replace(".schema.json", ".metadata.json")); + if (saveOnly) { // Only save updated JSON schema - no model file generation @@ -111,40 +116,30 @@ public async Task UpdateSchema(AltinnRepoEditingContext altinnRepoEditingContext if (repositoryType == AltinnRepositoryType.Datamodels) { - // Datamodels repository - save JSON and update XSD + // Data models repository - save JSON and update XSD await altinnAppGitRepository.WriteTextByRelativePathAsync(relativeFilePath, serializedJsonContent, true, cancellationToken); - XmlSchema xsd = _jsonSchemaToXmlSchemaConverter.Convert(jsonSchema); - await altinnAppGitRepository.SaveXsd(xsd, relativeFilePath.Replace(".schema.json", ".xsd")); + await UpdateXsdFromJsonSchema(altinnAppGitRepository, jsonSchema, schemaFileName); return; } - await UpdateModelFilesFromJsonSchema(altinnRepoEditingContext, relativeFilePath, serializedJsonContent, cancellationToken); + ModelMetadata modelMetadata = GetModelMetadataForCsharpGeneration(serializedJsonContent, jsonSchema); + string csharpModelName = modelMetadata.GetRootElement().TypeName; + await UpdateCSharpClasses(altinnAppGitRepository, modelMetadata, schemaFileName); + await UpdateApplicationMetadata(altinnAppGitRepository, schemaFileName, csharpModelName); + await UpdateXsdFromJsonSchema(altinnAppGitRepository, jsonSchema, schemaFileName); } - /// - public async Task UpdateModelFilesFromJsonSchema(AltinnRepoEditingContext altinnRepoEditingContext, string relativeFilePath, string jsonContent, CancellationToken cancellationToken = default) + private async Task UpdateXsdFromJsonSchema(AltinnAppGitRepository altinnAppGitRepository, JsonSchema jsonSchema, string schemaFileName) { - cancellationToken.ThrowIfCancellationRequested(); - var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); - var schemaName = altinnAppGitRepository.GetSchemaName(relativeFilePath); - - var jsonSchema = Json.Schema.JsonSchema.FromText(jsonContent); - var serializedJsonContent = SerializeJson(jsonSchema); - await altinnAppGitRepository.SaveJsonSchema(serializedJsonContent, schemaName); - var jsonSchemaConverterStrategy = JsonSchemaConverterStrategyFactory.SelectStrategy(jsonSchema); - XmlSchema xsd = _jsonSchemaToXmlSchemaConverter.Convert(jsonSchema); + await altinnAppGitRepository.SaveXsd(xsd, Path.ChangeExtension(schemaFileName, "xsd")); + } - await altinnAppGitRepository.SaveXsd(xsd, Path.ChangeExtension(schemaName, "xsd")); - + private ModelMetadata GetModelMetadataForCsharpGeneration(string jsonContent, JsonSchema jsonSchema) + { + var jsonSchemaConverterStrategy = JsonSchemaConverterStrategyFactory.SelectStrategy(jsonSchema); var metamodelConverter = new JsonSchemaToMetamodelConverter(jsonSchemaConverterStrategy.GetAnalyzer()); - ModelMetadata modelMetadata = metamodelConverter.Convert(jsonContent); - - string fullTypeName = await UpdateCSharpClasses(altinnAppGitRepository, modelMetadata, schemaName); - - await UpdateApplicationMetadata(altinnAppGitRepository, schemaName, fullTypeName); - - return jsonContent; + return metamodelConverter.Convert(jsonContent); } public async Task GenerateModelMetadataFromJsonSchema(AltinnRepoEditingContext altinnRepoEditingContext, string relativeFilePath, CancellationToken cancellationToken = default) @@ -152,10 +147,8 @@ public async Task GenerateModelMetadataFromJsonSchema(AltinnRepoE cancellationToken.ThrowIfCancellationRequested(); var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); var jsonContent = await altinnAppGitRepository.ReadTextByRelativePathAsync(relativeFilePath, cancellationToken); - var jsonSchema = Json.Schema.JsonSchema.FromText(jsonContent); - var jsonSchemaConverterStrategy = JsonSchemaConverterStrategyFactory.SelectStrategy(jsonSchema); - var metamodelConverter = new JsonSchemaToMetamodelConverter(jsonSchemaConverterStrategy.GetAnalyzer()); - return metamodelConverter.Convert(jsonContent); + var jsonSchema = JsonSchema.FromText(jsonContent); + return GetModelMetadataForCsharpGeneration(jsonContent, jsonSchema); } /// @@ -165,40 +158,48 @@ public async Task GenerateModelMetadataFromJsonSchema(AltinnRepoE /// This operation is using the new data modelling library. /// /// An . - /// The name of the file being uploaded. + /// The name of the file being uploaded. /// Stream representing the XSD. /// An that observes if operation is cancelled. - public async Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepoEditingContext, string modelName, Stream xsdStream, CancellationToken cancellationToken = default) + public async Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepoEditingContext, + string fileNameWithExtension, Stream xsdStream, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); - using MemoryStream xsdMemoryStream = new MemoryStream(); - xsdStream.CopyTo(xsdMemoryStream); - string jsonContent; - AltinnRepositoryType altinnRepositoryType = await altinnAppGitRepository.GetRepositoryType(); + MemoryStream xsdMemoryStream = GetXsdMemoryStream(xsdStream); + JsonSchema jsonSchema = GenerateJsonSchemaFromXsd(xsdMemoryStream); + string serializedJsonContent = SerializeJson(jsonSchema); + AltinnRepositoryType altinnRepositoryType = await altinnAppGitRepository.GetRepositoryType(); if (altinnRepositoryType == AltinnRepositoryType.Datamodels) { - xsdMemoryStream.Position = 0; - Json.Schema.JsonSchema jsonSchema = GenerateJsonSchemaFromXsd(xsdMemoryStream); - jsonContent = SerializeJson(jsonSchema); - - await altinnAppGitRepository.WriteTextByRelativePathAsync(Path.ChangeExtension(modelName, "schema.json"), jsonContent, true, cancellationToken); - - return jsonContent; + await altinnAppGitRepository.WriteTextByRelativePathAsync(Path.ChangeExtension(fileNameWithExtension, "schema.json"), serializedJsonContent, true, cancellationToken); + return serializedJsonContent; } /* From here repository is assumed to be for an app. Validate with a Directory.Exist check? */ - await altinnAppGitRepository.SaveXsd(xsdMemoryStream, modelName); - - jsonContent = await ProcessNewXsd(altinnAppGitRepository, xsdMemoryStream, modelName); + var schemaFileName = altinnAppGitRepository.GetSchemaName(fileNameWithExtension); + await altinnAppGitRepository.SaveXsd(xsdMemoryStream, fileNameWithExtension); + await altinnAppGitRepository.SaveJsonSchema(serializedJsonContent, schemaFileName); + ModelMetadata modelMetadata = GetModelMetadataForCsharpGeneration(serializedJsonContent, jsonSchema); + string csharpModelName = modelMetadata.GetRootElement().TypeName; + await UpdateCSharpClasses(altinnAppGitRepository, modelMetadata, schemaFileName); + await UpdateApplicationMetadata(altinnAppGitRepository, schemaFileName, csharpModelName); + + return serializedJsonContent; + } - return jsonContent; + private MemoryStream GetXsdMemoryStream(Stream xsdStream) + { + MemoryStream xsdMemoryStream = new MemoryStream(); + xsdStream.CopyTo(xsdMemoryStream); + xsdMemoryStream.Position = 0; + return xsdMemoryStream; } /// - public async Task<(string RelativePath, string JsonSchema)> CreateSchemaFromTemplate(AltinnRepoEditingContext altinnRepoEditingContext, string schemaName, string relativeDirectory = "", bool altinn2Compatible = false, CancellationToken cancellationToken = default) + public async Task<(string RelativePath, string JsonSchema)> CreateSchemaFromTemplate(AltinnRepoEditingContext altinnRepoEditingContext, string schemaAndModelName, string relativeDirectory = "", bool altinn2Compatible = false, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var altinnGitRepository = _altinnGitRepositoryFactory.GetAltinnGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); @@ -209,12 +210,12 @@ public async Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepo if (await altinnGitRepository.GetRepositoryType() == AltinnRepositoryType.Datamodels) { - var uri = GetSchemaUri(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, schemaName, relativeDirectory); - JsonTemplate jsonTemplate = altinn2Compatible ? new SeresJsonTemplate(uri, schemaName) : new GeneralJsonTemplate(uri, schemaName); + var uri = GetSchemaUri(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, schemaAndModelName, relativeDirectory); + JsonTemplate jsonTemplate = altinn2Compatible ? new SeresJsonTemplate(uri, schemaAndModelName) : new GeneralJsonTemplate(uri, schemaAndModelName); var jsonSchema = jsonTemplate.GetJsonString(); - var relativeFilePath = Path.ChangeExtension(Path.Combine(relativeDirectory, schemaName), ".schema.json"); + var relativeFilePath = Path.ChangeExtension(Path.Combine(relativeDirectory, schemaAndModelName), ".schema.json"); await altinnGitRepository.WriteTextByRelativePathAsync(relativeFilePath, jsonSchema, true, cancellationToken); return (relativeFilePath, jsonSchema); @@ -224,12 +225,14 @@ public async Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepo var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); var modelFolder = altinnAppGitRepository.GetRelativeModelFolder(); - var uri = GetSchemaUri(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, schemaName, modelFolder); - JsonTemplate jsonTemplate = altinn2Compatible ? new SeresJsonTemplate(uri, schemaName) : new GeneralJsonTemplate(uri, schemaName); + var uri = GetSchemaUri(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, schemaAndModelName, modelFolder); + JsonTemplate jsonTemplate = altinn2Compatible ? new SeresJsonTemplate(uri, schemaAndModelName) : new GeneralJsonTemplate(uri, schemaAndModelName); var jsonSchema = jsonTemplate.GetJsonString(); - var relativePath = await altinnAppGitRepository.SaveJsonSchema(jsonSchema, schemaName); + var relativePath = await altinnAppGitRepository.SaveJsonSchema(jsonSchema, schemaAndModelName); + + await UpdateApplicationMetadata(altinnAppGitRepository, schemaAndModelName, schemaAndModelName); return (relativePath, jsonSchema); } @@ -244,11 +247,11 @@ public async Task DeleteSchema(AltinnRepoEditingContext altinnRepoEditingContext if (await altinnGitRepository.GetRepositoryType() == AltinnRepositoryType.App) { var altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(altinnRepoEditingContext.Org, altinnRepoEditingContext.Repo, altinnRepoEditingContext.Developer); - var altinnCoreFile = altinnGitRepository.GetAltinnCoreFileByRelativePath(relativeFilePath); - var schemaName = altinnGitRepository.GetSchemaName(relativeFilePath); + var altinnCoreFile = altinnAppGitRepository.GetAltinnCoreFileByRelativePath(relativeFilePath); + var schemaFileName = altinnAppGitRepository.GetSchemaName(relativeFilePath); - await DeleteDatatypeFromApplicationMetadataAndLayoutSets(altinnAppGitRepository, schemaName); - DeleteRelatedSchemaFiles(altinnAppGitRepository, schemaName, altinnCoreFile.Directory); + await DeleteDatatypeFromApplicationMetadataAndLayoutSets(altinnAppGitRepository, schemaFileName); + DeleteRelatedSchemaFiles(altinnAppGitRepository, schemaFileName, altinnCoreFile.Directory); } else { @@ -261,10 +264,10 @@ public async Task DeleteSchema(AltinnRepoEditingContext altinnRepoEditingContext /// /// Organization owning the repository identified by it's short name. /// Repository name to search for schema files. - /// The logical name of the schema ie. filename without extension. + /// The logical name of the schema ie. filename without extension. /// The relative path (from repository root) to where the schema should be stored. /// Returns a resolvable uri to the location of the schema. - public Uri GetSchemaUri(string org, string repository, string schemaName, string relativePath = "") + public Uri GetSchemaUri(string org, string repository, string schemaFileName, string relativePath = "") { var baseUrl = _serviceRepositorySettings.RepositoryBaseURL; baseUrl = baseUrl.TrimEnd("/".ToCharArray()); @@ -273,19 +276,19 @@ public Uri GetSchemaUri(string org, string repository, string schemaName, string if (string.IsNullOrEmpty(relativePath)) { - schemaUri = new Uri($"{baseUrl}/{org}/{repository}/{schemaName}.schema.json"); + schemaUri = new Uri($"{baseUrl}/{org}/{repository}/{schemaFileName}.schema.json"); } else { relativePath = relativePath.TrimEnd('/'); relativePath = relativePath.TrimStart('/'); - schemaUri = new Uri($"{baseUrl}/{org}/{repository}/{relativePath}/{schemaName}.schema.json"); + schemaUri = new Uri($"{baseUrl}/{org}/{repository}/{relativePath}/{schemaFileName}.schema.json"); } return schemaUri; } - private Json.Schema.JsonSchema GenerateJsonSchemaFromXsd(Stream xsdStream) + private JsonSchema GenerateJsonSchemaFromXsd(Stream xsdStream) { XmlSchema originalXsd; try @@ -298,28 +301,28 @@ private Json.Schema.JsonSchema GenerateJsonSchemaFromXsd(Stream xsdStream) List customErrorMessages = new() { ex.Message }; throw new InvalidXmlException("Could not read invalid xml", customErrorMessages); } - Json.Schema.JsonSchema convertedJsonSchema = _xmlSchemaToJsonSchemaConverter.Convert(originalXsd); + JsonSchema convertedJsonSchema = _xmlSchemaToJsonSchemaConverter.Convert(originalXsd); return convertedJsonSchema; } - private async Task UpdateCSharpClasses(AltinnAppGitRepository altinnAppGitRepository, ModelMetadata modelMetadata, string schemaName) + private async Task UpdateCSharpClasses(AltinnAppGitRepository altinnAppGitRepository, ModelMetadata modelMetadata, string schemaFileName) { ApplicationMetadata application = await altinnAppGitRepository.GetApplicationMetadata(); - string modelName = modelMetadata.GetRootElement().TypeName; - bool separateNamespace = !application.DataTypes.Any(d => d.AppLogic?.ClassRef == $"Altinn.App.Models.{modelName}"); - - string csharpClasses = _modelMetadataToCsharpConverter.CreateModelFromMetadata(modelMetadata, separateNamespace, useNullableReferenceTypes: false); - await altinnAppGitRepository.SaveCSharpClasses(csharpClasses, schemaName); - return separateNamespace ? $"Altinn.App.Models.{modelName}.{modelName}" : $"Altinn.App.Models.{modelName}"; + string csharpModelName = modelMetadata.GetRootElement().TypeName; + bool separateNamespace = NamespaceNeedsToBeSeparated(application, csharpModelName); + string csharpClasses = _modelMetadataToCsharpConverter.CreateModelFromMetadata(modelMetadata, + separateNamespace, useNullableReferenceTypes: false); + await altinnAppGitRepository.SaveCSharpClasses(csharpClasses, schemaFileName); } - private static async Task UpdateApplicationMetadata(AltinnAppGitRepository altinnAppGitRepository, string schemaName, string fullTypeName) + private async Task UpdateApplicationMetadata(AltinnAppGitRepository altinnAppGitRepository, string schemaFileName, string csharpModelName) { ApplicationMetadata application = await altinnAppGitRepository.GetApplicationMetadata(); - UpdateApplicationWithAppLogicModel(application, schemaName, fullTypeName); + string fullTypeName = GetFullTypeName(application, csharpModelName); + UpdateApplicationWithAppLogicModel(application, schemaFileName, fullTypeName); await altinnAppGitRepository.SaveApplicationMetadata(application); } @@ -365,7 +368,7 @@ private static void UpdateApplicationWithAppLogicModel(ApplicationMetadata appli } } - private static string SerializeJson(Json.Schema.JsonSchema jsonSchema) + private static string SerializeJson(JsonSchema jsonSchema) { return JsonSerializer.Serialize( jsonSchema, @@ -376,34 +379,22 @@ private static string SerializeJson(Json.Schema.JsonSchema jsonSchema) }); } - private static string SerializeModelMetadata(ModelMetadata modelMetadata) + private static void DeleteRelatedSchemaFiles(AltinnAppGitRepository altinnAppGitRepository, string schemaFileName, string directory) { - return JsonSerializer.Serialize( - modelMetadata, - new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Latin1Supplement), - WriteIndented = true - }); - } - - private static void DeleteRelatedSchemaFiles(AltinnAppGitRepository altinnAppGitRepository, string schemaName, string directory) - { - var files = GetRelatedSchemaFiles(schemaName, directory); + var files = GetRelatedSchemaFiles(schemaFileName, directory); foreach (var file in files) { altinnAppGitRepository.DeleteFileByAbsolutePath(file); } } - private static IEnumerable GetRelatedSchemaFiles(string schemaName, string directory) + private static IEnumerable GetRelatedSchemaFiles(string schemaFileName, string directory) { - var xsdFile = Path.Combine(directory, $"{schemaName}.xsd"); - var jsonSchemaFile = Path.Combine(directory, $"{schemaName}.schema.json"); - var jsonMetadataFile = Path.Combine(directory, $"{schemaName}.metadata.json"); - var csharpModelFile = Path.Combine(directory, $"{schemaName}.cs"); + var xsdFile = Path.Combine(directory, $"{schemaFileName}.xsd"); + var jsonSchemaFile = Path.Combine(directory, $"{schemaFileName}.schema.json"); + var csharpModelFile = Path.Combine(directory, $"{schemaFileName}.cs"); - return new List() { jsonSchemaFile, xsdFile, jsonMetadataFile, csharpModelFile }; + return new List() { jsonSchemaFile, xsdFile, csharpModelFile }; } private static async Task DeleteDatatypeFromApplicationMetadataAndLayoutSets(AltinnAppGitRepository altinnAppGitRepository, string id) @@ -428,23 +419,17 @@ private static async Task DeleteDatatypeFromApplicationMetadataAndLayoutSets(Alt } } - private async Task ProcessNewXsd(AltinnAppGitRepository altinnAppGitRepository, MemoryStream xsdMemoryStream, string filePath) + private string GetFullTypeName(ApplicationMetadata application, + string csharpModelName) { - var schemaName = altinnAppGitRepository.GetSchemaName(filePath); - - Json.Schema.JsonSchema jsonSchema = GenerateJsonSchemaFromXsd(xsdMemoryStream); - var jsonContent = SerializeJson(jsonSchema); - await altinnAppGitRepository.SaveJsonSchema(jsonContent, schemaName); - - var jsonSchemaConverterStrategy = JsonSchemaConverterStrategyFactory.SelectStrategy(jsonSchema); - var metamodelConverter = new JsonSchemaToMetamodelConverter(jsonSchemaConverterStrategy.GetAnalyzer()); - var modelMetadata = metamodelConverter.Convert(jsonContent); - - string fullTypeName = await UpdateCSharpClasses(altinnAppGitRepository, modelMetadata, schemaName); - - await UpdateApplicationMetadata(altinnAppGitRepository, schemaName, fullTypeName); + bool separateNamespace = NamespaceNeedsToBeSeparated(application, csharpModelName); + return separateNamespace ? $"Altinn.App.Models.{csharpModelName}.{csharpModelName}" : $"Altinn.App.Models.{csharpModelName}"; + } - return jsonContent; + private bool NamespaceNeedsToBeSeparated(ApplicationMetadata application, + string csharpModelName) + { + return application.DataTypes.All(d => d.AppLogic?.ClassRef != $"Altinn.App.Models.{csharpModelName}"); } } } diff --git a/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs b/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs index 6d1bcb77833..c043f7fa8cd 100644 --- a/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs +++ b/backend/src/Designer/Services/Interfaces/ISchemaModelService.cs @@ -48,22 +48,22 @@ public interface ISchemaModelService /// Builds a JSON schema based on the uploaded XSD. /// /// An . - /// The name of the new model. + /// The name of the new file. /// Stream representing the XSD. /// An that observes if operation is cancelled. - Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepoEditingContext, string modelName, Stream xsdStream, CancellationToken cancellationToken = default); + Task BuildSchemaFromXsd(AltinnRepoEditingContext altinnRepoEditingContext, string fileNameWithExtension, Stream xsdStream, CancellationToken cancellationToken = default); /// /// Creates a JSON schema based on a template. /// /// An . - /// The name of the schema/model (no extension). + /// The name of the schema/model (no extension). /// The directory where the schema should be created. Applies only for schemas /// created in a data models repository. For app repositories the directory is determined by the app and the parameter is ignored. /// True if the schema should be Altinn 2 compatible when generating XSD. False (default) creates a Altinn 3 schema. /// An that observes if operation is cancelled. /// Returns a tuple where the first string is the relative path to the file and the second is the Json Schema created. - Task<(string RelativePath, string JsonSchema)> CreateSchemaFromTemplate(AltinnRepoEditingContext altinnRepoEditingContext, string schemaName, string relativeDirectory = "", bool altinn2Compatible = false, CancellationToken cancellationToken = default); + Task<(string RelativePath, string JsonSchema)> CreateSchemaFromTemplate(AltinnRepoEditingContext altinnRepoEditingContext, string schemaAndModelName, string relativeDirectory = "", bool altinn2Compatible = false, CancellationToken cancellationToken = default); /// /// Deletes a schema based on the relative path to the JSON Schema within the repository. diff --git a/backend/tests/Designer.Tests/Controllers/DataModelsController/PostTests.cs b/backend/tests/Designer.Tests/Controllers/DataModelsController/PostTests.cs index 69afecad8f6..2ab1b27af7d 100644 --- a/backend/tests/Designer.Tests/Controllers/DataModelsController/PostTests.cs +++ b/backend/tests/Designer.Tests/Controllers/DataModelsController/PostTests.cs @@ -3,6 +3,7 @@ using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; +using Altinn.Studio.Designer.Models.App; using Altinn.Studio.Designer.ViewModels.Request; using Designer.Tests.Controllers.ApiTests; using Designer.Tests.Utils; @@ -15,6 +16,10 @@ namespace Designer.Tests.Controllers.DataModelsController; public class PostTests : DesignerEndpointsTestsBase, IClassFixture> { private static string VersionPrefix(string org, string repository) => $"/designer/api/{org}/{repository}/datamodels"; + private static readonly string Org = "ttd"; + private static readonly string Repo = "empty-app"; + private static readonly string Developer = "testUser"; + public PostTests(WebApplicationFactory factory) : base(factory) { } @@ -58,6 +63,32 @@ public async Task PostDatamodel_FromFormPost_ShouldReturnCreatedFromTemplate(str Assert.Equal(postContent, getContent); } + [Fact] + public async Task PostDatamodel_CreateNew_ShouldAddDataTypeWithModelIdToAppMetadata() + { + string targetRepository = TestDataHelper.GenerateTestRepoName(); + + await CopyRepositoryForTest(Org, Repo, Developer, targetRepository); + string url = $"{VersionPrefix(Org, targetRepository)}/new"; + + string modelAndSchemaName = "modelAndSchemaName"; + var createViewModel = new CreateModelViewModel() + { ModelName = modelAndSchemaName, RelativeDirectory = "", Altinn2Compatible = false }; + + using var postRequestMessage = new HttpRequestMessage(HttpMethod.Post, url) + { + Content = JsonContent.Create(createViewModel, null, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }) + }; + + using var postResponse = await HttpClient.SendAsync(postRequestMessage); + Assert.Equal(HttpStatusCode.Created, postResponse.StatusCode); + + var applicationMetadata = + TestDataHelper.GetFileFromRepo(Org, targetRepository, Developer, "App/config/applicationmetadata.json"); + ApplicationMetadata deserializedApplicationMetadata = JsonSerializer.Deserialize(applicationMetadata, JsonSerializerOptions); + Assert.True(deserializedApplicationMetadata.DataTypes.Exists(dataType => dataType.Id == modelAndSchemaName)); + } + [Theory] [InlineData("", "ServiceA", true)] [InlineData("test<", "", false)] diff --git a/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs b/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs index 4dce13dce17..0ee22606477 100644 --- a/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs +++ b/backend/tests/Designer.Tests/Controllers/DataModelsController/PutDatamodelTests.cs @@ -149,7 +149,6 @@ private async Task FilesWithCorrectNameAndContentShouldBeCreated(string modelNam var location = Path.GetFullPath(Path.Combine(TestRepoPath, "App", "models")); var jsonSchemaLocation = Path.Combine(location, $"{modelName}.schema.json"); var xsdSchemaLocation = Path.Combine(location, $"{modelName}.xsd"); - var metamodelLocation = Path.Combine(location, $"{modelName}.metadata.json"); Assert.True(File.Exists(xsdSchemaLocation)); Assert.True(File.Exists(jsonSchemaLocation));