Skip to content

Add DeleteCategoryHandler and DeleteStatusHandler with full test coverage#132

Merged
mpaulosky merged 5 commits intomainfrom
copilot/add-unit-integration-tests-delete-handlers
Apr 15, 2026
Merged

Add DeleteCategoryHandler and DeleteStatusHandler with full test coverage#132
mpaulosky merged 5 commits intomainfrom
copilot/add-unit-integration-tests-delete-handlers

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

Implements soft-delete (archive) handlers for Category and Status domains, along with complete unit, endpoint, and integration test coverage across all layers.

New Implementation

  • DeleteCategoryCommand / DeleteCategoryValidator and DeleteStatusCommand / DeleteStatusValidator in Shared.Contracts
  • DeleteCategoryHandler and DeleteStatusHandler — follow existing soft-delete pattern: validate → get → skip if already archived → ArchiveAsync
  • DELETE /api/v1/categories/{id} and DELETE /api/v1/statuses/{id} endpoints — returns 204 NoContent or 404 NotFound, require authorization
  • Registered new handlers/validators in ServiceCollectionExtensions

Tests

  • Unit (handler): valid, not-found, already-archived idempotent, empty-ID validation, archive failure, cancellation token propagation — for both domains
  • Unit (endpoint): 204, 401, 404 paths for both DELETE /categories/{id} and DELETE /statuses/{id}
  • Integration: full round-trip against real MongoDB via TestContainers — create, delete, verify Archived=true in DB and excluded from paginated list
// Handler follows the same soft-delete pattern as DeleteIssueHandler / DeleteCommentHandler
var archiveResult = await _repository.ArchiveAsync(command.Id, cancellationToken);
return archiveResult.Success ? Result.Ok(true) : Result.Fail<bool>(archiveResult.Error!, archiveResult.ErrorCode);

Copilot AI changed the title [WIP] Add unit and integration tests for DeleteCategoryHandler and DeleteStatusHandler Add DeleteCategoryHandler and DeleteStatusHandler with full test coverage Apr 15, 2026
Copilot AI requested a review from mpaulosky April 15, 2026 03:09
@mpaulosky mpaulosky force-pushed the copilot/add-unit-integration-tests-delete-handlers branch from 9f6978d to f00799c Compare April 15, 2026 17:33
@mpaulosky mpaulosky marked this pull request as ready for review April 15, 2026 17:33
Copilot AI review requested due to automatic review settings April 15, 2026 17:33
@mpaulosky mpaulosky enabled auto-merge (squash) April 15, 2026 17:33
@github-actions github-actions Bot added the squad Squad triage inbox — Lead will assign to a member label Apr 15, 2026
@github-actions
Copy link
Copy Markdown

🏗️ PR Added to Squad Triage Queue

This PR has been labeled with squad and added to the triage queue.

Next steps:

  • The squad Lead will review and assign to an appropriate team member
  • A squad:member label will be added after triage

If you know which squad member should handle this, you can add the appropriate squad:member label yourself.

@github-actions
Copy link
Copy Markdown

Test Results Summary

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

Results for commit f00799c.

@github-actions
Copy link
Copy Markdown

Test Results Summary

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

Results for commit f00799c.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds soft-delete (archive) coverage for Category and Status by introducing new unit and integration tests, plus updating DI registration tests and endpoint tests to cover the new DELETE routes.

Changes:

  • Added unit tests for DeleteCategoryHandler and DeleteStatusHandler.
  • Added endpoint tests for DELETE /api/v1/categories/{id} and DELETE /api/v1/statuses/{id} (204/401/404 paths).
  • Added integration tests that validate archived records are updated in MongoDB and excluded from paginated lists.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/Api.Tests.Unit/Handlers/Statuses/DeleteStatusHandlerTests.cs New unit tests for delete-status handler behavior.
tests/Api.Tests.Unit/Handlers/Categories/DeleteCategoryHandlerTests.cs New unit tests for delete-category handler behavior.
tests/Api.Tests.Unit/Extensions/ServiceCollectionExtensionsTests.cs Ensures new delete handlers are registered in DI.
tests/Api.Tests.Unit/Endpoints/StatusEndpointsTests.cs Adds endpoint-level DELETE status coverage (204/401/404).
tests/Api.Tests.Unit/Endpoints/CategoryEndpointsTests.cs Adds endpoint-level DELETE category coverage (204/401/404).
tests/Api.Tests.Integration/Handlers/DeleteStatusHandlerIntegrationTests.cs New MongoDB-backed integration coverage for status archiving/list exclusion.
tests/Api.Tests.Integration/Handlers/DeleteCategoryHandlerIntegrationTests.cs New MongoDB-backed integration coverage for category archiving/list exclusion.

Comment on lines +1 to +8
// =======================================================
// Copyright (c) 2026. All rights reserved.
// File Name : DeleteStatusHandlerIntegrationTests.cs
// Company : mpaulosky
// Author : Matthew Paulosky
// Solution Name : IssueManager
// Project Name : Api.Tests.Integration
// =======================================================
Comment on lines +1 to +8
// =======================================================
// Copyright (c) 2026. All rights reserved.
// File Name : DeleteCategoryHandlerIntegrationTests.cs
// Company : mpaulosky
// Author : Matthew Paulosky
// Solution Name : IssueManager
// Project Name : Api.Tests.Integration
// =======================================================
Comment on lines +1 to +8
// =======================================================
// Copyright (c) 2026. All rights reserved.
// File Name : DeleteStatusHandlerTests.cs
// Company : mpaulosky
// Author : Matthew Paulosky
// Solution Name : IssueManager
// Project Name : Api.Tests.Unit
// =======================================================
Comment on lines +153 to +180
public async Task Handle_ValidStatus_PassesCancellationToken()
{
// Arrange
var statusId = ObjectId.GenerateNewId();
var cancellationToken = new CancellationToken();
var status = new StatusDto(
statusId,
"Test Status",
"Test Description",
DateTime.UtcNow,
null,
false,
UserDto.Empty);

var command = new DeleteStatusCommand { Id = statusId };

_repository.GetByIdAsync(statusId, Arg.Any<CancellationToken>())
.Returns(Result<StatusDto>.Ok(status));

_repository.ArchiveAsync(statusId, Arg.Any<CancellationToken>())
.Returns(Result.Ok());

// Act
await _handler.Handle(command, cancellationToken);

// Assert
await _repository.Received(1).GetByIdAsync(statusId, Arg.Any<CancellationToken>());
await _repository.Received(1).ArchiveAsync(statusId, Arg.Any<CancellationToken>());
Comment on lines +1 to +8
// =======================================================
// Copyright (c) 2026. All rights reserved.
// File Name : DeleteCategoryHandlerTests.cs
// Company : mpaulosky
// Author : Matthew Paulosky
// Solution Name : IssueManager
// Project Name : Api.Tests.Unit
// =======================================================
Comment on lines +153 to +180
public async Task Handle_ValidCategory_PassesCancellationToken()
{
// Arrange
var categoryId = ObjectId.GenerateNewId();
var cancellationToken = new CancellationToken();
var category = new CategoryDto(
categoryId,
"Test Category",
"Test Description",
DateTime.UtcNow,
null,
false,
UserDto.Empty);

var command = new DeleteCategoryCommand { Id = categoryId };

_repository.GetByIdAsync(categoryId, Arg.Any<CancellationToken>())
.Returns(Result<CategoryDto>.Ok(category));

_repository.ArchiveAsync(categoryId, Arg.Any<CancellationToken>())
.Returns(Result.Ok());

// Act
await _handler.Handle(command, cancellationToken);

// Assert
await _repository.Received(1).GetByIdAsync(categoryId, Arg.Any<CancellationToken>());
await _repository.Received(1).ArchiveAsync(categoryId, Arg.Any<CancellationToken>());
{
fixture.ThrowIfUnavailable();
_repository = new StatusRepository(fixture.ConnectionString, $"T{Guid.NewGuid():N}");
_handler = new DeleteStatusHandler(_repository, new DeleteStatusValidator());
{
fixture.ThrowIfUnavailable();
_repository = new CategoryRepository(fixture.ConnectionString, $"T{Guid.NewGuid():N}");
_handler = new DeleteCategoryHandler(_repository, new DeleteCategoryValidator());
Copilot AI and others added 4 commits April 15, 2026 11:07
…rage

- Add DeleteCategoryCommand and DeleteCategoryValidator in Shared
- Add DeleteStatusCommand and DeleteStatusValidator in Shared
- Add DeleteCategoryHandler for soft-delete/archive of categories
- Add DeleteStatusHandler for soft-delete/archive of statuses
- Add DELETE routes to CategoryEndpoints and StatusEndpoints
- Register new handlers and validators in ServiceCollectionExtensions
- Add unit tests: DeleteCategoryHandlerTests and DeleteStatusHandlerTests
- Add endpoint tests for delete to CategoryEndpointsTests and StatusEndpointsTests
- Add integration tests: DeleteCategoryHandlerIntegrationTests and DeleteStatusHandlerIntegrationTests
- Update ServiceCollectionExtensions tests to include new handlers/validators

Closes #122

Agent-Logs-Url: https://github.com/mpaulosky/IssueManager/sessions/d979c7cf-da30-47e8-9ea3-9727c87db432

Co-authored-by: mpaulosky <60372079+mpaulosky@users.noreply.github.com>
…rences — handlers use inline validation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ructors

DeleteCategoryHandler and DeleteStatusHandler use inline validation
and take only IRepository in their constructors — no validator class
exists. Matches the pattern already fixed in the unit test project.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mpaulosky mpaulosky force-pushed the copilot/add-unit-integration-tests-delete-handlers branch from f00799c to 2120436 Compare April 15, 2026 18:11
…d statuses found

GetAllAsync paginated was returning Result.Fail when count=0, causing the
integration test to receive a null Items collection. Now consistent with
CategoryRepository which always returns Result.Ok with an empty list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mpaulosky mpaulosky merged commit ca713bd into main Apr 15, 2026
19 checks passed
@mpaulosky mpaulosky deleted the copilot/add-unit-integration-tests-delete-handlers branch April 15, 2026 18:20
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.81%. Comparing base (007abe4) to head (4a97025).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/Api/Data/StatusRepository.cs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #132      +/-   ##
==========================================
+ Coverage   54.52%   55.81%   +1.29%     
==========================================
  Files         128      128              
  Lines        2986     2985       -1     
  Branches      339      338       -1     
==========================================
+ Hits         1628     1666      +38     
+ Misses       1108     1078      -30     
+ Partials      250      241       -9     
Files with missing lines Coverage Δ
src/Api/Data/StatusRepository.cs 23.40% <0.00%> (+0.48%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

squad Squad triage inbox — Lead will assign to a member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants