feat(board): edit task deadlines
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TaskTracker.Api.Pages;
|
||||
using TaskTracker.Core.Entities;
|
||||
using TaskTracker.Core.Enums;
|
||||
using TaskTracker.Core.Interfaces;
|
||||
using Xunit;
|
||||
|
||||
namespace TaskTracker.Tests;
|
||||
|
||||
public class TaskDeadlineConversionTests
|
||||
{
|
||||
[Fact]
|
||||
public void FromLocalInput_uses_the_supplied_time_zone_offset_for_an_unspecified_value()
|
||||
{
|
||||
var timeZone = TimeZoneInfo.CreateCustomTimeZone("TestZone", TimeSpan.FromHours(-4), "Test", "Test");
|
||||
var localValue = new DateTime(2026, 8, 14, 11, 30, 0, DateTimeKind.Utc);
|
||||
|
||||
var dueAt = TaskDeadline.FromLocalInput(localValue, timeZone);
|
||||
|
||||
Assert.Equal(new DateTimeOffset(2026, 8, 14, 11, 30, 0, TimeSpan.FromHours(-4)), dueAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromLocalInput_returns_null_for_a_blank_local_deadline()
|
||||
{
|
||||
var timeZone = TimeZoneInfo.CreateCustomTimeZone("TestZone", TimeSpan.FromHours(2), "Test", "Test");
|
||||
|
||||
var dueAt = TaskDeadline.FromLocalInput(null, timeZone);
|
||||
|
||||
Assert.Null(dueAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Board_create_assigns_due_at_from_local_deadline()
|
||||
{
|
||||
var repository = new InMemoryTaskRepository();
|
||||
var board = CreateBoard(repository);
|
||||
var localDeadline = new DateTime(2026, 8, 14, 11, 30, 0);
|
||||
|
||||
await board.OnPostCreateTaskAsync("deadline", null, localDeadline);
|
||||
|
||||
var created = Assert.Single(repository.Created);
|
||||
var expected = TaskDeadline.FromLocalInput(localDeadline, TimeZoneInfo.Local);
|
||||
Assert.Equal(expected, created.DueAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Board_update_explicit_clear_takes_precedence_over_a_supplied_deadline()
|
||||
{
|
||||
var existing = new WorkTask
|
||||
{
|
||||
Id = 1,
|
||||
Title = "existing",
|
||||
Status = WorkTaskStatus.Pending,
|
||||
DueAt = new DateTimeOffset(2026, 8, 14, 11, 30, 0, TimeSpan.FromHours(-4)),
|
||||
};
|
||||
var repository = new InMemoryTaskRepository(existing);
|
||||
var board = CreateBoard(repository);
|
||||
|
||||
var result = await board.OnPutUpdateTaskAsync(1, null, null, null, null, new DateTime(2026, 8, 15, 9, 0, 0), true);
|
||||
|
||||
Assert.IsType<PartialViewResult>(result);
|
||||
Assert.Null(existing.DueAt);
|
||||
}
|
||||
|
||||
private static BoardModel CreateBoard(ITaskRepository repository)
|
||||
{
|
||||
var board = new BoardModel(repository);
|
||||
var services = new ServiceCollection()
|
||||
.AddLogging()
|
||||
.AddMvcCore()
|
||||
.AddViews()
|
||||
.Services
|
||||
.BuildServiceProvider();
|
||||
var httpContext = new DefaultHttpContext { RequestServices = services };
|
||||
var provider = services.GetRequiredService<IModelMetadataProvider>();
|
||||
board.PageContext = new PageContext
|
||||
{
|
||||
HttpContext = httpContext,
|
||||
ViewData = new ViewDataDictionary(provider, new ModelStateDictionary()),
|
||||
};
|
||||
return board;
|
||||
}
|
||||
|
||||
private sealed class InMemoryTaskRepository(params WorkTask[] tasks) : ITaskRepository
|
||||
{
|
||||
private readonly List<WorkTask> _tasks = [.. tasks];
|
||||
public List<WorkTask> Created { get; } = [];
|
||||
|
||||
public Task<List<WorkTask>> GetAllAsync(WorkTaskStatus? status = null, int? parentId = null, bool includeSubTasks = false) =>
|
||||
Task.FromResult(_tasks);
|
||||
public Task<WorkTask?> GetByIdAsync(int id) => Task.FromResult(_tasks.SingleOrDefault(task => task.Id == id));
|
||||
public Task<WorkTask?> GetActiveTaskAsync() => Task.FromResult(_tasks.SingleOrDefault(task => task.Status == WorkTaskStatus.Active));
|
||||
public Task<List<WorkTask>> GetSubTasksAsync(int parentId) => Task.FromResult(_tasks.Where(task => task.ParentTaskId == parentId).ToList());
|
||||
public Task<WorkTask> CreateAsync(WorkTask task)
|
||||
{
|
||||
Created.Add(task);
|
||||
_tasks.Add(task);
|
||||
return Task.FromResult(task);
|
||||
}
|
||||
public Task UpdateAsync(WorkTask task) => Task.CompletedTask;
|
||||
public Task DeleteAsync(int id) => Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user