using System.Text.Json; using Cleanuparr.Api.Contracts.Responses; using Cleanuparr.Api.Controllers; using Cleanuparr.Api.Features.Events.Contracts.Responses; using Cleanuparr.Api.Tests.TestHelpers; using Cleanuparr.Domain.Enums; using Cleanuparr.Persistence; using Cleanuparr.Persistence.Models.Events; using Microsoft.AspNetCore.Mvc; using Shouldly; using Xunit; namespace Cleanuparr.Api.Tests.Controllers; /// /// Pins the manual event response shape. /// public class ManualEventsResponseContractTests : IDisposable { private readonly EventsContext _context; private readonly ManualEventsController _controller; public ManualEventsResponseContractTests() { _context = ConfigControllerTestDataFactory.CreateEventsContext(); _controller = new ManualEventsController(_context, TimeProvider.System); } public void Dispose() { _context.Dispose(); GC.SuppressFinalize(this); } private async Task SeedEventAsync() { ManualEvent manualEvent = new() { Type = ManualEventType.RecurringDownload, Message = "a recurring download", Severity = EventSeverity.Warning, Timestamp = DateTimeOffset.UtcNow, ItemTitle = "Some.Item", ItemHash = "abc123", StrikeCount = 1, }; _context.ManualEvents.Add(manualEvent); await _context.SaveChangesAsync(); return manualEvent; } [Fact] public async Task GetManualEvents_ReturnsTheDocumentedPaginationWrapperKeys() { await SeedEventAsync(); ActionResult> result = await _controller.GetManualEvents(); ResponseContract.Keys(result.Result!).ShouldBe( [ "items", "page", "pageSize", "totalCount", "totalPages", ]); } [Fact] public async Task GetManualEvents_ReturnsTheDocumentedItemKeys() { await SeedEventAsync(); ActionResult> result = await _controller.GetManualEvents(); FirstItemKeys(result.Result!).ShouldBe(ResponseKeys); } [Fact] public async Task GetManualEvent_ReturnsTheSameKeysAsTheListItems() { ManualEvent seeded = await SeedEventAsync(); ActionResult result = await _controller.GetManualEvent(seeded.Id); ResponseContract.Keys(result.Result!).ShouldBe(ResponseKeys); } [Fact] public async Task GetManualEvent_ReturnsNotFound_ForAnUnknownId() { ActionResult result = await _controller.GetManualEvent(Guid.NewGuid()); result.Result.ShouldBeOfType(); } /// /// Every column of the entity, all of them persisted. /// private static readonly string[] ResponseKeys = [ "downloadClientName", "downloadClientType", "id", "instanceType", "instanceUrl", "isDryRun", "isResolved", "itemHash", "itemTitle", "jobRunId", "message", "resolvedAt", "severity", "strikeCount", "timestamp", "type", ]; private static IReadOnlyList FirstItemKeys(IActionResult result) { JsonElement items = ResponseContract.Body(result).GetProperty("items"); return ResponseContract.Keys(items.EnumerateArray().First()); } }