diff --git a/backend/packagegroups/NuGet.props b/backend/packagegroups/NuGet.props index 82b74f8b1a1..5b7d4b031da 100644 --- a/backend/packagegroups/NuGet.props +++ b/backend/packagegroups/NuGet.props @@ -40,6 +40,7 @@ + diff --git a/backend/src/Designer/Designer.csproj b/backend/src/Designer/Designer.csproj index 5b6b5fd1df5..5c1a057d3e8 100644 --- a/backend/src/Designer/Designer.csproj +++ b/backend/src/Designer/Designer.csproj @@ -26,6 +26,7 @@ + @@ -167,7 +168,7 @@ - + diff --git a/backend/src/Designer/Infrastructure/Models/PostgreSQLSettings.cs b/backend/src/Designer/Infrastructure/Models/PostgreSQLSettings.cs index de0e790dfd7..a89ce3c9ce6 100644 --- a/backend/src/Designer/Infrastructure/Models/PostgreSQLSettings.cs +++ b/backend/src/Designer/Infrastructure/Models/PostgreSQLSettings.cs @@ -16,5 +16,10 @@ public class PostgreSQLSettings : ISettingsMarker /// Password for app user for the postgres db /// public string DesignerDbPwd { get; set; } + + public string FormattedConnectionString() + { + return string.Format(ConnectionString, DesignerDbPwd); + } } } diff --git a/backend/src/Designer/Infrastructure/ServiceRegistration.cs b/backend/src/Designer/Infrastructure/ServiceRegistration.cs index 33dfce06b31..e91ca200073 100644 --- a/backend/src/Designer/Infrastructure/ServiceRegistration.cs +++ b/backend/src/Designer/Infrastructure/ServiceRegistration.cs @@ -48,10 +48,7 @@ public static IServiceCollection RegisterServiceImplementations(this IServiceCol services.AddDbContext(options => { PostgreSQLSettings postgresSettings = configuration.GetSection(nameof(PostgreSQLSettings)).Get(); - string connectionString = string.Format( - postgresSettings.ConnectionString, - postgresSettings.DesignerDbPwd); - options.UseNpgsql(connectionString); + options.UseNpgsql(postgresSettings.FormattedConnectionString()); }); services.AddScoped(); diff --git a/backend/src/Designer/Middleware/UserRequestSynchronization/RequestSyncExtensions.cs b/backend/src/Designer/Middleware/UserRequestSynchronization/RequestSyncExtensions.cs index 25a1acb882a..f02b319d275 100644 --- a/backend/src/Designer/Middleware/UserRequestSynchronization/RequestSyncExtensions.cs +++ b/backend/src/Designer/Middleware/UserRequestSynchronization/RequestSyncExtensions.cs @@ -24,10 +24,7 @@ public static IServiceCollection RegisterSynchronizationServices(this IServiceCo services.AddSingleton(_ => { PostgreSQLSettings postgresSettings = configuration.GetSection(nameof(PostgreSQLSettings)).Get(); - string connectionString = string.Format( - postgresSettings.ConnectionString, - postgresSettings.DesignerDbPwd); - return new PostgresDistributedSynchronizationProvider(connectionString); + return new PostgresDistributedSynchronizationProvider(postgresSettings.FormattedConnectionString()); }); return services; } diff --git a/backend/src/Designer/Migrations/20240409201554_InitMigration.cs b/backend/src/Designer/Migrations/20240409201554_InitMigration.cs index 7ab67f27581..1024e3aa583 100644 --- a/backend/src/Designer/Migrations/20240409201554_InitMigration.cs +++ b/backend/src/Designer/Migrations/20240409201554_InitMigration.cs @@ -1,4 +1,4 @@ -using Altinn.Studio.Designer.Migrations.InitialSqlScripts; +using Altinn.Studio.Designer.Migrations.SqlScripts; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -12,11 +12,11 @@ public partial class InitMigration : Migration protected override void Up(MigrationBuilder migrationBuilder) { // initial sql used in yuniql migration are idempotent so it is safe to execute them as initial ef-core migration - migrationBuilder.Sql(InitialScriptsReadHelper.ReadInitialSqlScript("01-setup-tables.sql")); - migrationBuilder.Sql(InitialScriptsReadHelper.ReadInitialSqlScript("02-setup-deployments.sql")); - migrationBuilder.Sql(InitialScriptsReadHelper.ReadInitialSqlScript("03-setup-releases.sql")); - migrationBuilder.Sql(InitialScriptsReadHelper.ReadInitialSqlScript("04-setup-grants.sql")); - migrationBuilder.Sql(InitialScriptsReadHelper.ReadInitialSqlScript("05-setup-index.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("InitialSqlScripts/01-setup-tables.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("InitialSqlScripts/02-setup-deployments.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("InitialSqlScripts/03-setup-releases.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("InitialSqlScripts/04-setup-grants.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("InitialSqlScripts/05-setup-index.sql")); } /// diff --git a/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.Designer.cs b/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.Designer.cs new file mode 100644 index 00000000000..16fbeefed9c --- /dev/null +++ b/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.Designer.cs @@ -0,0 +1,175 @@ +// +using System; +using Altinn.Studio.Designer.Repository.ORMImplementation.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Altinn.Studio.Designer.Migrations +{ + [DbContext(typeof(DesignerdbContext))] + [Migration("20241111093515_DistributedCacheTable")] + partial class DistributedCacheTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseSerialColumns(modelBuilder); + + modelBuilder.Entity("Altinn.Studio.Designer.Repository.ORMImplementation.Models.AppScopesDbObject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("App") + .IsRequired() + .HasColumnType("character varying") + .HasColumnName("app"); + + b.Property("Created") + .HasColumnType("timestamptz") + .HasColumnName("created"); + + b.Property("CreatedBy") + .HasColumnType("character varying") + .HasColumnName("created_by"); + + b.Property("LastModifiedBy") + .HasColumnType("character varying") + .HasColumnName("last_modified_by"); + + b.Property("Org") + .IsRequired() + .HasColumnType("character varying") + .HasColumnName("org"); + + b.Property("Scopes") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("scopes"); + + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + + b.HasKey("Id") + .HasName("app_scopes_pkey"); + + b.HasIndex(new[] { "Org", "App" }, "idx_app_scopes_org_app") + .IsUnique(); + + b.ToTable("app_scopes", "designer"); + }); + + modelBuilder.Entity("Altinn.Studio.Designer.Repository.ORMImplementation.Models.Deployment", b => + { + b.Property("Sequenceno") + .ValueGeneratedOnAdd() + .HasColumnType("BIGSERIAL") + .HasColumnName("sequenceno"); + + NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Sequenceno")); + + b.Property("App") + .HasColumnType("character varying") + .HasColumnName("app"); + + b.Property("Buildid") + .HasColumnType("character varying") + .HasColumnName("buildid"); + + b.Property("Buildresult") + .HasColumnType("character varying") + .HasColumnName("buildresult"); + + b.Property("Created") + .HasColumnType("timestamptz") + .HasColumnName("created"); + + b.Property("Entity") + .HasColumnType("text") + .HasColumnName("entity"); + + b.Property("Org") + .HasColumnType("character varying") + .HasColumnName("org"); + + b.Property("Tagname") + .HasColumnType("character varying") + .HasColumnName("tagname"); + + b.HasKey("Sequenceno") + .HasName("deployments_pkey"); + + b.HasIndex(new[] { "Org", "App" }, "idx_deployments_org_app"); + + b.ToTable("deployments", "designer"); + }); + + modelBuilder.Entity("Altinn.Studio.Designer.Repository.ORMImplementation.Models.Release", b => + { + b.Property("Sequenceno") + .ValueGeneratedOnAdd() + .HasColumnType("BIGSERIAL") + .HasColumnName("sequenceno"); + + NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Sequenceno")); + + b.Property("App") + .HasColumnType("character varying") + .HasColumnName("app"); + + b.Property("Buildid") + .HasColumnType("character varying") + .HasColumnName("buildid"); + + b.Property("Buildresult") + .HasColumnType("character varying") + .HasColumnName("buildresult"); + + b.Property("Buildstatus") + .HasColumnType("character varying") + .HasColumnName("buildstatus"); + + b.Property("Created") + .HasColumnType("timestamptz") + .HasColumnName("created"); + + b.Property("Entity") + .HasColumnType("text") + .HasColumnName("entity"); + + b.Property("Org") + .HasColumnType("character varying") + .HasColumnName("org"); + + b.Property("Tagname") + .HasColumnType("character varying") + .HasColumnName("tagname"); + + b.HasKey("Sequenceno") + .HasName("releases_pkey"); + + b.HasIndex(new[] { "Org", "App" }, "idx_releases_org_app"); + + b.ToTable("releases", "designer"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.cs b/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.cs new file mode 100644 index 00000000000..a6a7932bb27 --- /dev/null +++ b/backend/src/Designer/Migrations/20241111093515_DistributedCacheTable.cs @@ -0,0 +1,24 @@ +using Altinn.Studio.Designer.Migrations.SqlScripts; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Altinn.Studio.Designer.Migrations +{ + /// + public partial class DistributedCacheTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Up/01-setup-distributedcache-table.sql")); + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Up/02-setup-grants.sql")); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Down/01-drop-distributedcache-table.sql")); + } + } +} diff --git a/backend/src/Designer/Migrations/DesignerdbContextModelSnapshot.cs b/backend/src/Designer/Migrations/DesignerdbContextModelSnapshot.cs index 60df1681b56..2527c498559 100644 --- a/backend/src/Designer/Migrations/DesignerdbContextModelSnapshot.cs +++ b/backend/src/Designer/Migrations/DesignerdbContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("ProductVersion", "8.0.10") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseSerialColumns(modelBuilder); @@ -36,7 +36,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("character varying") .HasColumnName("app"); - b.Property("Created") + b.Property("Created") .HasColumnType("timestamptz") .HasColumnName("created"); @@ -58,6 +58,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("jsonb") .HasColumnName("scopes"); + b.Property("Version") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("xid") + .HasColumnName("xmin"); + b.HasKey("Id") .HasName("app_scopes_pkey"); diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/InitialScriptsReadHelper.cs b/backend/src/Designer/Migrations/InitialSqlScripts/InitialScriptsReadHelper.cs deleted file mode 100644 index e1c41dc3a89..00000000000 --- a/backend/src/Designer/Migrations/InitialSqlScripts/InitialScriptsReadHelper.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.IO; -using System.Linq; - -namespace Altinn.Studio.Designer.Migrations.InitialSqlScripts; - -public class InitialScriptsReadHelper -{ - public static string ReadInitialSqlScript(string scriptName) - { - var assembly = typeof(InitialScriptsReadHelper).Assembly; - string resourceName = assembly.GetManifestResourceNames() - .Single(x => x.EndsWith(scriptName)); - - using Stream stream = assembly.GetManifestResourceStream(resourceName); - using StreamReader reader = new(stream); - return reader.ReadToEnd(); - } -} diff --git a/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Down/01-drop-distributedcache-table.sql b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Down/01-drop-distributedcache-table.sql new file mode 100644 index 00000000000..c0425700d59 --- /dev/null +++ b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Down/01-drop-distributedcache-table.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS designer.distributedcache; diff --git a/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/01-setup-distributedcache-table.sql b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/01-setup-distributedcache-table.sql new file mode 100644 index 00000000000..914c1d83eb0 --- /dev/null +++ b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/01-setup-distributedcache-table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS designer.distributedcache +( + "Id" text COLLATE pg_catalog."default" NOT NULL, + "Value" bytea, + "ExpiresAtTime" timestamp with time zone, + "SlidingExpirationInSeconds" double precision, + "AbsoluteExpiration" timestamp with time zone, + CONSTRAINT "DistCache_pkey" PRIMARY KEY ("Id") +) + +TABLESPACE pg_default; diff --git a/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/02-setup-grants.sql b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/02-setup-grants.sql new file mode 100644 index 00000000000..a0da32232f8 --- /dev/null +++ b/backend/src/Designer/Migrations/SqlScripts/DistributedCache/Up/02-setup-grants.sql @@ -0,0 +1 @@ +GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA designer TO designer; diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/01-setup-tables.sql b/backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/01-setup-tables.sql similarity index 100% rename from backend/src/Designer/Migrations/InitialSqlScripts/01-setup-tables.sql rename to backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/01-setup-tables.sql diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/02-setup-deployments.sql b/backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/02-setup-deployments.sql similarity index 100% rename from backend/src/Designer/Migrations/InitialSqlScripts/02-setup-deployments.sql rename to backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/02-setup-deployments.sql diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/03-setup-releases.sql b/backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/03-setup-releases.sql similarity index 100% rename from backend/src/Designer/Migrations/InitialSqlScripts/03-setup-releases.sql rename to backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/03-setup-releases.sql diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/04-setup-grants.sql b/backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/04-setup-grants.sql similarity index 100% rename from backend/src/Designer/Migrations/InitialSqlScripts/04-setup-grants.sql rename to backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/04-setup-grants.sql diff --git a/backend/src/Designer/Migrations/InitialSqlScripts/05-setup-index.sql b/backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/05-setup-index.sql similarity index 100% rename from backend/src/Designer/Migrations/InitialSqlScripts/05-setup-index.sql rename to backend/src/Designer/Migrations/SqlScripts/InitialSqlScripts/05-setup-index.sql diff --git a/backend/src/Designer/Migrations/SqlScripts/SqlScriptsReadHelper.cs b/backend/src/Designer/Migrations/SqlScripts/SqlScriptsReadHelper.cs new file mode 100644 index 00000000000..7161f134529 --- /dev/null +++ b/backend/src/Designer/Migrations/SqlScripts/SqlScriptsReadHelper.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Linq; + +namespace Altinn.Studio.Designer.Migrations.SqlScripts; + +public class SqlScriptsReadHelper +{ + public static string ReadSqlScript(string scriptName) + { + string resourceNameEnding = scriptName.Replace('/', '.'); + if (!resourceNameEnding.EndsWith(".sql")) + { + throw new ArgumentException("Invalid script name"); + } + + var assembly = typeof(SqlScriptsReadHelper).Assembly; + string resourceName = assembly.GetManifestResourceNames() + .Single(x => x.EndsWith(resourceNameEnding)); + + using Stream stream = assembly.GetManifestResourceStream(resourceName); + using StreamReader reader = new(stream!); + return reader.ReadToEnd(); + } +} diff --git a/backend/src/Designer/Program.cs b/backend/src/Designer/Program.cs index 4ef468a331a..b90669b0706 100644 --- a/backend/src/Designer/Program.cs +++ b/backend/src/Designer/Program.cs @@ -19,6 +19,7 @@ using Altinn.Studio.Designer.Services.Interfaces; using Altinn.Studio.Designer.Tracing; using Altinn.Studio.Designer.TypedHttpClients; +using Community.Microsoft.Extensions.Caching.PostgreSql; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector; using Microsoft.AspNetCore.Builder; @@ -264,6 +265,19 @@ void ConfigureServices(IServiceCollection services, IConfiguration configuration services.AddFeatureManagement(); services.RegisterSynchronizationServices(configuration); + // Override the default distributed cache with a PostgreSQL implementation + services.AddDistributedPostgreSqlCache(setup => + { + PostgreSQLSettings postgresSettings = + configuration.GetSection(nameof(PostgreSQLSettings)).Get(); + + setup.ConnectionString = postgresSettings.FormattedConnectionString(); + setup.SchemaName = "designer"; + setup.TableName = "distributedcache"; + setup.DisableRemoveExpired = false; + setup.CreateInfrastructure = false; + setup.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30); + }); if (!env.IsDevelopment()) { diff --git a/backend/src/Designer/Repository/DeploymentRepository.cs b/backend/src/Designer/Repository/DeploymentRepository.cs index 03e1288b262..bc25f553fff 100644 --- a/backend/src/Designer/Repository/DeploymentRepository.cs +++ b/backend/src/Designer/Repository/DeploymentRepository.cs @@ -32,9 +32,7 @@ public class DeploymentRepository : IDeploymentRepository /// public DeploymentRepository(PostgreSQLSettings postgresSettings, ILogger logger) { - _connectionString = string.Format( - postgresSettings.ConnectionString, - postgresSettings.DesignerDbPwd); + _connectionString = postgresSettings.FormattedConnectionString(); _logger = logger; } diff --git a/backend/src/Designer/Repository/ReleaseRepository.cs b/backend/src/Designer/Repository/ReleaseRepository.cs index 566f1cbd314..5f928eb9b5b 100644 --- a/backend/src/Designer/Repository/ReleaseRepository.cs +++ b/backend/src/Designer/Repository/ReleaseRepository.cs @@ -34,9 +34,7 @@ public class ReleaseRepository : IReleaseRepository /// public ReleaseRepository(PostgreSQLSettings postgresSettings, ILogger logger) { - _connectionString = string.Format( - postgresSettings.ConnectionString, - postgresSettings.DesignerDbPwd); + _connectionString = postgresSettings.FormattedConnectionString(); _logger = logger; } diff --git a/backend/tests/Designer.Tests/Controllers/PreviewController/ApplicationMetadataTests.cs b/backend/tests/Designer.Tests/Controllers/PreviewController/ApplicationMetadataTests.cs index c44e62db89f..3671a2b4747 100644 --- a/backend/tests/Designer.Tests/Controllers/PreviewController/ApplicationMetadataTests.cs +++ b/backend/tests/Designer.Tests/Controllers/PreviewController/ApplicationMetadataTests.cs @@ -51,9 +51,9 @@ public async Task Get_ApplicationMetadata_Ok() Assert.Equal(HttpStatusCode.OK, response.StatusCode); string responseBody = await response.Content.ReadAsStringAsync(); - ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, SerializerOptions); + ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, JsonSerializerOptions); expectedApplicationMetadata.AltinnNugetVersion = string.Empty; - string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, SerializerOptions); + string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, JsonSerializerOptions); JsonUtils.DeepEquals(expectedJson, responseBody).Should().BeTrue(); } @@ -72,9 +72,9 @@ public async Task Get_ApplicationMetadata_With_V8_Altinn_Nuget_Version_Ok() Assert.Equal(HttpStatusCode.OK, response.StatusCode); string responseBody = await response.Content.ReadAsStringAsync(); - ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, SerializerOptions); + ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, JsonSerializerOptions); expectedApplicationMetadata.AltinnNugetVersion = "8.0.0.0"; - string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, SerializerOptions); + string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, JsonSerializerOptions); JsonUtils.DeepEquals(expectedJson, responseBody).Should().BeTrue(); } @@ -93,7 +93,7 @@ public async Task Get_ApplicationMetadata_WithLessDataTypesThanLayoutSetsFile_Ok Assert.Equal(HttpStatusCode.OK, response.StatusCode); string responseBody = await response.Content.ReadAsStringAsync(); - ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, SerializerOptions); + ApplicationMetadata expectedApplicationMetadata = JsonSerializer.Deserialize(expectedApplicationMetadataString, JsonSerializerOptions); expectedApplicationMetadata.AltinnNugetVersion = "8.0.0.0"; // Add the mocked data type to expected app metadata expectedApplicationMetadata.DataTypes.Add(new DataType() @@ -110,7 +110,7 @@ public async Task Get_ApplicationMetadata_WithLessDataTypesThanLayoutSetsFile_Ok expectedApplicationMetadata.PartyTypesAllowed.SubUnit = false; expectedApplicationMetadata.PartyTypesAllowed.BankruptcyEstate = false; - string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, SerializerOptions); + string expectedJson = JsonSerializer.Serialize(expectedApplicationMetadata, JsonSerializerOptions); JsonUtils.DeepEquals(expectedJson, responseBody).Should().BeTrue(); } @@ -118,7 +118,7 @@ public async Task Get_ApplicationMetadata_WithLessDataTypesThanLayoutSetsFile_Ok public async Task Get_ApplicationMetadata_WithAllPartyTypesAllowedSetToFalse() { string originalApplicationMetadataString = TestDataHelper.GetFileFromRepo(Org, AppV4, Developer, "App/config/applicationmetadata.json"); - ApplicationMetadata originalApplicationMetadata = JsonSerializer.Deserialize(originalApplicationMetadataString, SerializerOptions); + ApplicationMetadata originalApplicationMetadata = JsonSerializer.Deserialize(originalApplicationMetadataString, JsonSerializerOptions); originalApplicationMetadata.PartyTypesAllowed.Person.Should().BeTrue(); originalApplicationMetadata.PartyTypesAllowed.Organisation.Should().BeTrue(); originalApplicationMetadata.PartyTypesAllowed.SubUnit.Should().BeTrue(); @@ -137,7 +137,7 @@ public async Task Get_ApplicationMetadata_WithAllPartyTypesAllowedSetToFalse() string responseBody = await response.Content.ReadAsStringAsync(); - ApplicationMetadata responseApplicationMetadata = JsonSerializer.Deserialize(responseBody, SerializerOptions); + ApplicationMetadata responseApplicationMetadata = JsonSerializer.Deserialize(responseBody, JsonSerializerOptions); responseApplicationMetadata.PartyTypesAllowed.Person.Should().BeFalse(); responseApplicationMetadata.PartyTypesAllowed.Organisation.Should().BeFalse(); responseApplicationMetadata.PartyTypesAllowed.SubUnit.Should().BeFalse(); diff --git a/backend/tests/Designer.Tests/Controllers/PreviewController/PreviewControllerTestsBase.cs b/backend/tests/Designer.Tests/Controllers/PreviewController/PreviewControllerTestsBase.cs index de8910dd32c..b0ca17543ea 100644 --- a/backend/tests/Designer.Tests/Controllers/PreviewController/PreviewControllerTestsBase.cs +++ b/backend/tests/Designer.Tests/Controllers/PreviewController/PreviewControllerTestsBase.cs @@ -1,8 +1,11 @@ -using System.Text.Encodings.Web; +using System.Linq; +using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; using Designer.Tests.Controllers.ApiTests; using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; namespace Designer.Tests.Controllers.PreviewController { @@ -22,12 +25,19 @@ public class PreviewControllerTestsBase : DesignerEndpointsTestsBase protected const string InstanceGuId = "f1e23d45-6789-1bcd-8c34-56789abcdef0"; protected const string AttachmentGuId = "f47ac10b-58cc-4372-a567-0e02b2c3d479"; protected const string MockedReferrerUrl = "https://studio-mock-url.no"; - protected readonly JsonSerializerOptions SerializerOptions = new JsonSerializerOptions() + + protected override void ConfigureTestServices(IServiceCollection services) { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - }; + base.ConfigureTestServices(services); + var cacheServices = services.Where( + d => d.ServiceType == typeof(IDistributedCache)).ToList(); + foreach (ServiceDescriptor serviceDescriptor in cacheServices) + { + services.Remove(serviceDescriptor); + } + + services.AddDistributedMemoryCache(); + } public PreviewControllerTestsBase(WebApplicationFactory factory) : base(factory) {