Files
hrynco-notification-service/HrynCo.NotificationService.Web.IntegrationTests/EditorLayoutTests.cs
T
agrynco 81654c0d33 feat(templates): add service language template management
Add normalized service and template catalogs, scoped administration, migration, validation, and regression coverage.

Ref: IT-1601
2026-10-17 22:02:43 +03:00

69 lines
3.8 KiB
C#

using System.Text.RegularExpressions;
using HrynCo.NotificationService.DAL.Abstract.Repositories;
using HrynCo.NotificationService.DAL.Abstract.Templates;
using Microsoft.Extensions.DependencyInjection;
namespace HrynCo.NotificationService.Web.IntegrationTests;
public sealed class EditorLayoutTests(TemplateDatabaseFixture fixture) : IClassFixture<TemplateDatabaseFixture>
{
[Fact]
public async Task ServiceAndTemplateEditorsRenderOneBreadcrumbBeforeTheCard_IncludingValidationErrors()
{
var connection = await fixture.CreateDatabaseAsync();
await using var app = new TemplateWebApplicationFactory(connection);
using var client = app.CreateClient();
using var scope = app.Services.CreateScope();
var service = (await scope.ServiceProvider.GetRequiredService<INotificationServiceRepository>().GetAllAsync()).Single();
var definition = new EmailTemplateDefinition { ServiceName = service.Name, Key = "Layout" };
await scope.ServiceProvider.GetRequiredService<IEmailTemplateDefinitionRepository>().SaveDefinitionAsync(definition, true);
var root = $"/admin/services/{service.Id}";
var editors = new[]
{
(Url: "/admin/services/create", Title: "Create Service", Form: "serviceForm"),
(Url: root + "/edit", Title: "Edit Service", Form: "serviceForm"),
(Url: root + "/templates/create", Title: "Create Email Template", Form: "templateForm"),
(Url: root + "/templates/" + definition.Id, Title: "Edit Email Template", Form: "templateForm")
};
foreach (var editor in editors)
AssertEditorLayout(await client.GetStringAsync(editor.Url), editor.Title, editor.Form);
var fields = TemplateEditorTestFields.Read(await client.GetStringAsync(root + "/templates/create"));
fields["Key"] = "InvalidDraft";
fields["VariablesJson"] = "{invalid";
var errorHtml = await (await client.PostAsync(root + "/templates/save", new FormUrlEncodedContent(fields))).Content.ReadAsStringAsync();
Assert.Contains("Invalid variables JSON", errorHtml);
AssertEditorLayout(errorHtml, "Create Email Template", "templateForm");
Assert.Contains("<dl class=\"template-service-context\">", errorHtml);
Assert.Contains("<dt>Service</dt>", errorHtml);
Assert.Contains("<dd>TestService</dd>", errorHtml);
Assert.DoesNotContain("form-control-plaintext", errorHtml);
Assert.Equal(service.Name, TemplateEditorTestFields.Read(errorHtml)["ServiceName"]);
}
[Fact]
public async Task ChannelEditorWorksWithoutTheOptionalBreadcrumbSection()
{
var connection = await fixture.CreateDatabaseAsync();
await using var app = new TemplateWebApplicationFactory(connection);
using var client = app.CreateClient();
var html = await client.GetStringAsync("/admin/channels/create");
Assert.Contains("<h1 class=\"editor-card-title\">", html);
Assert.Contains("<span>Create Channel</span>", html);
Assert.Contains("id=\"channelForm\"", html);
Assert.DoesNotContain("aria-label=\"Breadcrumb\"", html);
}
private static void AssertEditorLayout(string html, string title, string form)
{
Assert.Single(Regex.Matches(html, "aria-label=\"Breadcrumb\""));
var breadcrumb = html.IndexOf("<nav aria-label=\"Breadcrumb\"", StringComparison.Ordinal);
var card = html.IndexOf("<div class=\"card editor-card\">", StringComparison.Ordinal);
Assert.True(breadcrumb >= 0 && breadcrumb < card);
Assert.Single(Regex.Matches(html, "<h1 class=\"editor-card-title\">"));
Assert.Contains("aria-hidden=\"true\"", html);
Assert.Contains("<span>" + title + "</span>", html);
Assert.Contains("id=\"" + form + "\"", html);
Assert.Contains("aria-current=\"page\"", html);
}
}