diff --git a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs index 4de4269e5..200da2638 100644 --- a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs +++ b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs @@ -32,6 +32,8 @@ namespace Squidex.Extensions.APM.Otlp builder.AddOtlpExporter(options => { config.GetSection("logging:otlp").Bind(options); + + }); } } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Contents/Json/WorkflowStepSurrogate.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Contents/Json/WorkflowStepSurrogate.cs index 8fc27a389..0f3f6b4e9 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Contents/Json/WorkflowStepSurrogate.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Contents/Json/WorkflowStepSurrogate.cs @@ -16,11 +16,13 @@ namespace Squidex.Domain.Apps.Core.Contents.Json { public Dictionary Transitions { get; set; } + [JsonPropertyName("noUpdateRules")] + public NoUpdate? NoUpdate { get; set; } + [JsonPropertyName("noUpdate")] public bool NoUpdateFlag { get; set; } - [JsonPropertyName("noUpdateRules")] - public NoUpdate? NoUpdate { get; set; } + public bool Validate { get; set; } public string? Color { get; set; } @@ -52,7 +54,7 @@ namespace Squidex.Domain.Apps.Core.Contents.Json x => x.Key, x => x.Value.ToSource()); - return new WorkflowStep(transitions, Color, noUpdate); + return new WorkflowStep(transitions, Color, noUpdate, Validate); } } } diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj index 439726aac..b0b4bf921 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj @@ -28,7 +28,7 @@ - + diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs index dabb7d7fe..afbb766f9 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs @@ -19,7 +19,7 @@ namespace Squidex.Domain.Apps.Entities.Comments.Commands public abstract class CommentsCommand : CommentsCommandBase { - public static readonly NamedId NoApp = NamedId.Of(DomainId.NewGuid(), "none"); + public static readonly NamedId NoApp = NamedId.Of(DomainId.Empty, "none"); public DomainId CommentsId { get; set; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Commands/BulkUpdateContents.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Commands/BulkUpdateContents.cs index 7d6868ef0..bf4576feb 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Commands/BulkUpdateContents.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Commands/BulkUpdateContents.cs @@ -11,6 +11,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.Commands { public sealed class BulkUpdateContents : SquidexCommand, IAppCommand, ISchemaCommand { + public static readonly NamedId NoSchema = NamedId.Of(DomainId.Empty, "none"); + public NamedId AppId { get; set; } public NamedId SchemaId { get; set; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs index 886f4afda..126e09e1f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentsBulkUpdateCommandMiddleware.cs @@ -175,7 +175,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject } // The bulk command can be invoke in a schema controller or without a schema controller, therefore the name might be null. - if (task.SchemaId == null) + if (task.SchemaId == null || task.SchemaId.Id == default) { throw new DomainObjectNotFoundException("undefined"); } diff --git a/backend/src/Squidex.Infrastructure/Diagnostics/Diagnoser.cs b/backend/src/Squidex.Infrastructure/Diagnostics/Diagnoser.cs index 904d4dbcc..e50d36866 100644 --- a/backend/src/Squidex.Infrastructure/Diagnostics/Diagnoser.cs +++ b/backend/src/Squidex.Infrastructure/Diagnostics/Diagnoser.cs @@ -107,8 +107,7 @@ namespace Squidex.Infrastructure.Diagnostics return false; } - using var cts = new CancellationTokenSource(DefaultTimeout); - using var combined = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct); + using var combined = CancellationTokenSource.CreateLinkedTokenSource(ct); // Enforce a hard timeout. combined.CancelAfter(DefaultTimeout); diff --git a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj index c2f78a254..671068360 100644 --- a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj +++ b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj @@ -24,12 +24,12 @@ - - - - - - + + + + + + diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs index df41260ba..9d4c938a9 100644 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs @@ -33,7 +33,7 @@ namespace Squidex.Areas.Api.Config.OpenApi if (description != null) { - tag.Description ??= string.Empty; + tag.Description ??= string.Empty; if (!tag.Description.Contains(description, StringComparison.Ordinal)) { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index ee36fe8c2..d9865c2eb 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -331,7 +331,7 @@ namespace Squidex.Areas.Api.Controllers.Contents [ApiCosts(5)] public async Task BulkUpdateContents(string app, string schema, [FromBody] BulkUpdateContentsDto request) { - var command = request.ToCommand(); + var command = request.ToCommand(false); var context = await CommandBus.PublishAsync(command, HttpContext.RequestAborted); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs index a8d433ae7..c2ec9c737 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs @@ -135,7 +135,7 @@ namespace Squidex.Areas.Api.Controllers.Contents [ApiCosts(5)] public async Task BulkUpdateContents(string app, string schema, [FromBody] BulkUpdateContentsDto request) { - var command = request.ToCommand(); + var command = request.ToCommand(true); var context = await CommandBus.PublishAsync(command, HttpContext.RequestAborted); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs index 15faeb851..c3e8d3e93 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs @@ -100,6 +100,14 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator .HasQuery("ids", JsonObjectType.String, "Comma-separated list of content IDs.") .Responds(200, "Content items retrieved.", builder.ContentsSchema) .Responds(400, "Query not valid."); + + builder.AddOperation(OpenApiOperationMethod.Post, "/bulk") + .RequirePermission(PermissionIds.AppContentsReadOwn) + .Operation("Bulk") + .OperationSummary("Bulk update content items across all schemas.") + .HasBody("request", builder.Parent.BulkRequestSchema, null) + .Responds(200, "Contents created, update or delete.", builder.Parent.BulkResponseSchema) + .Responds(400, "Contents request not valid."); } private static void GenerateSchemaOperations(OperationsBuilder builder) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs index 90fb3e458..c42e7d8d6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs @@ -51,25 +51,29 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// public bool OptimizeValidation { get; set; } = true; - public BulkUpdateContents ToCommand() + public BulkUpdateContents ToCommand(bool setSchema) { var result = SimpleMapper.Map(this, new BulkUpdateContents()); - result.Jobs = Jobs?.Select(x => x.ToJob())?.ToArray(); + result.Jobs = Jobs?.Select(x => + { + var job = x.ToJob(); #pragma warning disable CS0618 // Type or member is obsolete - if (result.Jobs != null && Publish) - { - foreach (var job in result.Jobs) + if (Publish) { - if (job != null) - { - job.Status = Status.Published; - } + job.Status = Status.Published; } - } #pragma warning restore CS0618 // Type or member is obsolete + return job; + }).ToArray(); + + if (setSchema) + { + result.SchemaId = BulkUpdateContents.NoSchema; + } + return result; } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs index f30ba560c..b9144d3f4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs @@ -40,21 +40,24 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models { var result = SimpleMapper.Map(this, new BulkUpdateContents()); - result.Jobs = Datas?.Select(x => new BulkUpdateJob { Type = BulkUpdateContentType.Create, Data = x }).ToArray(); + result.Jobs = Datas?.Select(x => + { + var job = new BulkUpdateJob + { + Type = BulkUpdateContentType.Create, + Data = x + }; #pragma warning disable CS0618 // Type or member is obsolete - if (result.Jobs != null && Publish) - { - foreach (var job in result.Jobs) + if (Publish) { - if (job != null) - { - job.Status = Status.Published; - } + job.Status = Status.Published; } - } #pragma warning restore CS0618 // Type or member is obsolete + return job; + }).ToArray(); + return result; } } diff --git a/backend/src/Squidex/Config/Domain/TelemetryServices.cs b/backend/src/Squidex/Config/Domain/TelemetryServices.cs index a0af5b05c..24f3c3c12 100644 --- a/backend/src/Squidex/Config/Domain/TelemetryServices.cs +++ b/backend/src/Squidex/Config/Domain/TelemetryServices.cs @@ -35,6 +35,15 @@ namespace Squidex.Config.Domain builder.AddHttpClientInstrumentation(); builder.AddMongoDBInstrumentation(); + var sampling = config.GetValue("logging:otlp:sampling"); + + if (sampling > 0 && sampling < 1) + { + builder.SetSampler( + new ParentBasedSampler( + new TraceIdRatioBasedSampler(sampling))); + } + foreach (var configurator in serviceProvider.GetRequiredService>()) { configurator.Configure(builder); diff --git a/backend/src/Squidex/Config/Messaging/MessagingServices.cs b/backend/src/Squidex/Config/Messaging/MessagingServices.cs index 4886b0b27..891ca883f 100644 --- a/backend/src/Squidex/Config/Messaging/MessagingServices.cs +++ b/backend/src/Squidex/Config/Messaging/MessagingServices.cs @@ -63,7 +63,7 @@ namespace Squidex.Config.Messaging } services.AddSingleton(c => - new SystemTextJsonTransportSerializer(c.GetRequiredService())); + new SystemTextJsonMessagingSerializer(c.GetRequiredService())); services.AddSingletonAs() .As(); diff --git a/backend/src/Squidex/Squidex.csproj b/backend/src/Squidex/Squidex.csproj index 318ad5390..83f6b6df4 100644 --- a/backend/src/Squidex/Squidex.csproj +++ b/backend/src/Squidex/Squidex.csproj @@ -69,19 +69,19 @@ - - - - - - - - + + + + + + + + - - - - + + + + diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index 87378abba..4748e41c7 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -337,7 +337,10 @@ "enabled": false, // The endpoint to the agent. - "endpoint": "" + "endpoint": "", + + // The sample rate as double. 0.5 writes every second trace. + "sampling": 1.0 }, "applicationInsights": { diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/WorkflowJsonTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/WorkflowJsonTests.cs index a10be6f1b..836de411d 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/WorkflowJsonTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/WorkflowJsonTests.cs @@ -29,7 +29,8 @@ namespace Squidex.Domain.Apps.Core.Model.Contents [Status.Published] = WorkflowTransition.When("Expression", "Role1", "Role2") }.ToReadonlyDictionary(), "#00ff00", - NoUpdate.When("Expression", "Role1", "Role2")) + NoUpdate.When("Expression", "Role1", "Role2"), + true) }.ToReadonlyDictionary(), ReadonlyList.Create(DomainId.NewGuid()), "MyName"); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppState.json b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppState.json index 5a998bbd4..511d67952 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppState.json +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppState.json @@ -87,10 +87,9 @@ } }, + "noUpdateRules": {}, "noUpdate": false, - "noUpdateRules": { - - }, + "validate": true, "color": "#eb3142" }, "Draft": { @@ -103,6 +102,7 @@ } }, "noUpdate": false, + "validate": false, "color": "#8091a5" }, "Published": { @@ -115,6 +115,7 @@ } }, "noUpdate": false, + "validate": false, "color": "#4bb958" } }, diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs index d1eed6b93..073d1dd42 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs @@ -46,9 +46,28 @@ namespace TestSuite.ApiTests { var q = new ContentQuery { OrderBy = "data/number/iv asc" }; - var items = await _.Contents.GetAsync(q); + var itemsByQ = await _.Contents.GetAsync(q); + var itemsIds = itemsByQ.Items.Take(3).Select(x => x.Id).ToHashSet(); + var itemsById = await _.Contents.GetAsync(new ContentQuery { Ids = itemsIds }); + + Assert.Equal(3, itemsById.Items.Count); + Assert.Equal(3, itemsById.Total); + + foreach (var item in itemsById.Items) + { + Assert.Equal(_.AppName, item.AppName); + Assert.Equal(_.SchemaName, item.SchemaName); + } + } - var itemsById = await _.Contents.GetAsync(new HashSet(items.Items.Take(3).Select(x => x.Id))); + [Fact] + public async Task Should_query_by_ids_across_schemas() + { + var q = new ContentQuery { OrderBy = "data/number/iv asc" }; + + var itemsByQ = await _.Contents.GetAsync(q); + var itemsIds = itemsByQ.Items.Take(3).Select(x => x.Id).ToHashSet(); + var itemsById = await _.SharedContents.GetAsync(itemsIds); Assert.Equal(3, itemsById.Items.Count); Assert.Equal(3, itemsById.Total); @@ -418,7 +437,7 @@ namespace TestSuite.ApiTests }" }; - var result = await _.Contents.GraphQlAsync(query); + var result = await _.SharedContents.GraphQlAsync(query); var value = result["createMyReadsContent"]["data"]["number"]["iv"].Value(); @@ -489,7 +508,7 @@ namespace TestSuite.ApiTests } }; - var result = await _.Contents.GraphQlAsync(query); + var result = await _.SharedContents.GraphQlAsync(query); var value = result["createMyReadsContent"]["data"]["number"]["iv"].Value(); @@ -537,7 +556,7 @@ namespace TestSuite.ApiTests } }; - var results = await _.Contents.GraphQlAsync(new[] { query1, query2 }); + var results = await _.SharedContents.GraphQlAsync(new[] { query1, query2 }); var items1 = results.ElementAt(0).Data.Items; var items2 = results.ElementAt(1).Data.Items; @@ -568,8 +587,7 @@ namespace TestSuite.ApiTests } }; - var result = await _.Contents.GraphQlAsync(query); - + var result = await _.SharedContents.GraphQlAsync(query); var items = result.Items; Assert.Equal(items.Select(x => x.Data.Number).ToArray(), new[] { 4, 5, 6 }); @@ -597,8 +615,7 @@ namespace TestSuite.ApiTests } }; - var result = await _.Contents.GraphQlGetAsync(query); - + var result = await _.SharedContents.GraphQlGetAsync(query); var items = result.Items; Assert.Equal(items.Select(x => x.Data.Number).ToArray(), new[] { 4, 5, 6 }); @@ -622,8 +639,7 @@ namespace TestSuite.ApiTests }" }; - var result = await _.Contents.GraphQlAsync(query); - + var result = await _.SharedContents.GraphQlAsync(query); var items = result["queryMyReadsContents"]; Assert.Equal(items.Select(x => x["data"]["number"]["iv"].Value()).ToArray(), new[] { 4, 5, 6 }); @@ -651,7 +667,7 @@ namespace TestSuite.ApiTests } }; - await _.Contents.GraphQlAsync(query); + await _.SharedContents.GraphQlAsync(query); } [Fact] diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs index acb3b63f1..7b615a07f 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs @@ -915,6 +915,88 @@ namespace TestSuite.ApiTests } } + [Fact] + public async Task Should_update_content_with_bulk_and_shared_client() + { + TestEntity content = null; + try + { + var schemaName = $"schema-{Guid.NewGuid()}"; + + // STEP 0: Create dummy schema. + var createSchema = new CreateSchemaDto + { + Name = schemaName, + + // Publish it to avoid validations issues. + IsPublished = true + }; + + await _.Schemas.PostSchemaAsync(_.AppName, createSchema); + + + + // STEP 1: Create a new item. + content = await _.Contents.CreateAsync(new TestEntityData + { + String = "test" + }, ContentCreateOptions.AsPublish); + + + // STEP 2: Patch an item. + await _.SharedContents.BulkUpdateAsync(new BulkUpdate + { + Jobs = new List + { + new BulkUpdateJob + { + Id = content.Id, + Data = new + { + number = new + { + iv = 1 + } + }, + Schema = _.SchemaName + } + } + }); + + + // STEP 3: Update the item and ensure that the data has changed. + await _.SharedContents.BulkUpdateAsync(new BulkUpdate + { + Jobs = new List + { + new BulkUpdateJob + { + Id = content.Id, + Data = new + { + number = new + { + iv = 2 + } + }, + Schema = _.SchemaName + } + } + }); + + var updated = await _.Contents.GetAsync(content.Id); + + Assert.Equal(2, updated.Data.Number); + } + finally + { + if (content != null) + { + await _.Contents.DeleteAsync(content.Id); + } + } + } + [Fact] public async Task Should_create_draft_version() { diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs index f299ad454..ad80217e2 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs @@ -92,7 +92,7 @@ namespace TestSuite.ApiTests }".Replace("", content_0.Id, StringComparison.Ordinal) }; - var result1 = await _.Contents.GraphQlAsync(query); + var result1 = await _.SharedContents.GraphQlAsync(query); Assert.Equal(1, result1["findMyWritesContent"]["flatData"]["json"]["value"].Value()); Assert.Equal(2, result1["findMyWritesContent"]["flatData"]["json"]["obj"]["value"].Value()); @@ -119,8 +119,6 @@ namespace TestSuite.ApiTests // Do nothing } - var countriesClient = _.ClientManager.CreateContentsClient("countries"); - var query = new { query = @" @@ -143,7 +141,7 @@ namespace TestSuite.ApiTests }" }; - var result1 = await countriesClient.GraphQlAsync(query); + var result1 = await _.SharedContents.GraphQlAsync(query); var typed = result1["queryCountriesContents"].ToObject>(); diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj index 3b5c30ccf..9bd31c758 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj +++ b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj @@ -22,7 +22,7 @@ - + diff --git a/backend/tools/TestSuite/TestSuite.Shared/Fixtures/ClientFixture.cs b/backend/tools/TestSuite/TestSuite.Shared/Fixtures/ClientFixture.cs index 8029ebeab..d8e40e7c8 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/Fixtures/ClientFixture.cs +++ b/backend/tools/TestSuite/TestSuite.Shared/Fixtures/ClientFixture.cs @@ -100,6 +100,11 @@ namespace TestSuite.Fixtures get => ClientManager.CreateUserManagementClient(); } + public IContentsSharedClient SharedContents + { + get => ClientManager.CreateSharedDynamicContentsClient(); + } + static ClientFixture() { VerifierSettings.IgnoreMember("AppName"); diff --git a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj index fed01e6d1..ba0b66893 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj +++ b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/frontend/src/app/features/settings/pages/workflows/workflow-step.component.html b/frontend/src/app/features/settings/pages/workflows/workflow-step.component.html index e40ae9f60..0bf8fa525 100644 --- a/frontend/src/app/features/settings/pages/workflows/workflow-step.component.html +++ b/frontend/src/app/features/settings/pages/workflows/workflow-step.component.html @@ -1,7 +1,7 @@
-