feat(api): support task deadlines

This commit is contained in:
aj
2026-08-13 16:43:20 -04:00
parent cc63c456bf
commit 5c90a6dd76
3 changed files with 97 additions and 0 deletions
@@ -0,0 +1,91 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using TaskTracker.Api.Controllers;
using TaskTracker.Core.DTOs;
using TaskTracker.Core.Entities;
using TaskTracker.Infrastructure.Data;
using TaskTracker.Infrastructure.Repositories;
using Xunit;
namespace TaskTracker.Tests;
public class TasksControllerDeadlineTests
{
[Fact]
public async Task Create_copies_due_at_including_offset_to_created_task()
{
await using var db = CreateDbContext();
var controller = CreateController(db);
var dueAt = DateTimeOffset.Parse("2026-08-14T11:00:00-04:00");
var result = await controller.Create(new CreateTaskRequest { Title = "deadline", DueAt = dueAt });
var created = Assert.IsType<CreatedAtActionResult>(result);
var response = Assert.IsType<ApiResponse<WorkTask>>(created.Value);
Assert.Equal(dueAt, response.Data!.DueAt);
}
[Fact]
public async Task Update_changes_due_at_when_value_is_supplied()
{
await using var db = CreateDbContext();
var task = await AddTaskAsync(db, DateTimeOffset.Parse("2026-08-14T11:00:00-04:00"));
var controller = CreateController(db);
var dueAt = DateTimeOffset.Parse("2026-08-15T09:30:00+02:00");
var result = await controller.Update(task.Id, new UpdateTaskRequest { DueAt = dueAt });
var ok = Assert.IsType<OkObjectResult>(result);
var response = Assert.IsType<ApiResponse<WorkTask>>(ok.Value);
Assert.Equal(dueAt, response.Data!.DueAt);
}
[Fact]
public async Task Update_clears_due_at_only_when_clear_due_at_is_true()
{
await using var db = CreateDbContext();
var task = await AddTaskAsync(db, DateTimeOffset.Parse("2026-08-14T11:00:00-04:00"));
var controller = CreateController(db);
var result = await controller.Update(task.Id, new UpdateTaskRequest { ClearDueAt = true });
var ok = Assert.IsType<OkObjectResult>(result);
var response = Assert.IsType<ApiResponse<WorkTask>>(ok.Value);
Assert.Null(response.Data!.DueAt);
}
[Fact]
public async Task Update_with_omitted_due_at_preserves_existing_due_at()
{
await using var db = CreateDbContext();
var dueAt = DateTimeOffset.Parse("2026-08-14T11:00:00-04:00");
var task = await AddTaskAsync(db, dueAt);
var controller = CreateController(db);
var result = await controller.Update(task.Id, new UpdateTaskRequest { Title = "renamed" });
var ok = Assert.IsType<OkObjectResult>(result);
var response = Assert.IsType<ApiResponse<WorkTask>>(ok.Value);
Assert.Equal(dueAt, response.Data!.DueAt);
}
private static TaskTrackerDbContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<TaskTrackerDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
return new TaskTrackerDbContext(options);
}
private static TasksController CreateController(TaskTrackerDbContext db) =>
new(new TaskRepository(db), NullLogger<TasksController>.Instance);
private static async Task<WorkTask> AddTaskAsync(TaskTrackerDbContext db, DateTimeOffset dueAt)
{
var task = new WorkTask { Title = "existing", DueAt = dueAt };
db.Tasks.Add(task);
await db.SaveChangesAsync();
return task;
}
}