using System.Security.Claims; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using TarninaHub.Application.Abstractions; using TarninaHub.Application.Dtos; using TarninaHub.Controllers; namespace TarninaHub.Tests.Controllers; public class SubmissionsControllerTests { private static SubmissionsController CreateController(ISubmissionService service, string role = "operator") { var controller = new SubmissionsController(service); var identity = new ClaimsIdentity( [new Claim("sub", "user:tester"), new Claim("role", role)], authenticationType: "test"); controller.ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal(identity) }, }; return controller; } private static SubmissionResponse SampleSubmission(string status) => new( "submission:abc", "problem:xyz", "Title", "Description", "social_challenge:seniorzy", "location:krakow", "user:tester", status, ["seniorzy"], DateTimeOffset.UtcNow, null); [Fact] public async Task UpdateStatus_RejectsInvalidTransition() { var service = new StubSubmissionService { Current = SampleSubmission("new") }; var controller = CreateController(service); var result = await controller.UpdateStatus( "submission:abc", new UpdateSubmissionStatusRequest("matched"), CancellationToken.None); Assert.IsType(result.Result); Assert.Null(service.LastRequestedStatus); } [Fact] public async Task UpdateStatus_AcceptsValidTransition() { var service = new StubSubmissionService { Current = SampleSubmission("new"), UpdateResult = SampleSubmission("triaged"), }; var controller = CreateController(service); var result = await controller.UpdateStatus( "submission:abc", new UpdateSubmissionStatusRequest("triaged"), CancellationToken.None); Assert.IsType(result.Result); Assert.Equal("triaged", service.LastRequestedStatus); } [Fact] public async Task GetById_ReturnsNotFoundWhenMissing() { var controller = CreateController(new StubSubmissionService()); var result = await controller.GetById("submission:missing", CancellationToken.None); Assert.IsType(result.Result); } private sealed class StubSubmissionService : ISubmissionService { public SubmissionResponse? Current { get; set; } public SubmissionResponse? UpdateResult { get; set; } public string? LastRequestedStatus { get; private set; } public Task CreateAsync( string authorId, CreateSubmissionRequest request, CancellationToken cancellationToken) => Task.FromResult(SampleSubmission("new")); public Task> ListAsync( string viewerId, bool isStaff, string? status, int page, int pageSize, CancellationToken cancellationToken) => Task.FromResult( new PagedResponse([], page, pageSize, 0)); public Task GetAsync(string submissionId, CancellationToken cancellationToken) => Task.FromResult(Current); public Task UpdateStatusAsync( string submissionId, string newStatus, CancellationToken cancellationToken) { LastRequestedStatus = newStatus; return Task.FromResult(UpdateResult); } } }