Skip to content

[test-improver] Add @WebMvcTest tests for ProjectController (16 tests, 2 bug pins)#54

Draft
github-actions[bot] wants to merge 1 commit into
mainfrom
test-assist/projectcontroller-webmvctest-81366ef8ab8ab740
Draft

[test-improver] Add @WebMvcTest tests for ProjectController (16 tests, 2 bug pins)#54
github-actions[bot] wants to merge 1 commit into
mainfrom
test-assist/projectcontroller-webmvctest-81366ef8ab8ab740

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

🤖 Test Improver — automated AI assistant focused on improving tests.

Goal & Rationale

ProjectController had zero effective test coverage — the HTTP layer was completely untested. This PR adds 16 @WebMvcTest tests covering all 8 endpoints and documents two real bugs as bug-pin tests.

Approach

Used @WebMvcTest(ProjectController.class) with @MockBean ProjectRepository and @MockBean TaskService. Tests the HTTP layer in isolation (fast, no full Spring context, no database).

Tests added

Test Endpoint What it verifies
getAllProjects_returnsJsonList GET /api/projects 200 + JSON array with correct fields
getAllProjects_emptyList_returnsEmptyArray GET /api/projects 200 + empty array
getProject_existingId_returns200WithBody GET /api/projects/1 200 + correct project in body
getProject_missingId_returns404 GET /api/projects/9999 Correctly returns 404 (unlike TaskController.getTask — see PR #52)
getProjectByCode_found_returns200 GET /api/projects/code/TEST 200 + project in body
getProjectByCode_notFound_returns404 GET /api/projects/code/NOPE 404
createProject_setsStatusZeroAndReturnsBody_BUG_returns200InsteadOf201 POST /api/projects Bug-pin: 200 (should be 201)
updateProject_existingId_returns200 PUT /api/projects/1 200 + updated project
updateProject_missingId_returns404 PUT /api/projects/9999 404
deleteProject_returns204 DELETE /api/projects/1 204 No Content
getProjectDashboard_notFound_returns404 GET /api/projects/9999/dashboard 404
getProjectDashboard_found_returns200WithCompositeData GET /api/projects/1/dashboard 200 + composite {project, tasks, stats, progress}
getProjectDashboard_zeroTasks_BUG_progressIsNaN GET /api/projects/2/dashboard Bug-pin: body contains literal NaN
addMember_projectNotFound_returns404 POST /api/projects/9999/members 404
addMember_emptyMembersList_setsUserId POST /api/projects/1/members 200 + members set to user ID
addMember_existingMembers_appendsUserId_BUG_noDuplicateCheck POST /api/projects/1/members 200 + userId appended; documents no-duplicate-check bug

Bug-pin tests

1. POST /api/projects returns 200 instead of 201 Created

ProjectController.createProject() uses ResponseEntity.ok(saved) — the code even has a comment: "Should be 201 Created". When fixed, change isOk() to isCreated() in the test.

2. GET /api/projects/{id}/dashboard with taskCount=0 returns NaN in JSON

Project.getProgress() computes (double)completedTaskCount / taskCount * 100. When taskCount=0, Java floating-point division returns NaN. Jackson 2.13 serializes this as the literal token NaN in the response body (not valid JSON — RFC 8259 §6 requires finite numbers). This causes client-side JSON parsers to fail.

Fix: return taskCount == 0 ? 0.0 : (double) completedTaskCount / taskCount * 100;

When fixed, replace the content().string(containsString("NaN")) assertion with jsonPath("$.progress").value(0.0).

Note on getMemberIds() NPE: Project.getMemberIds() throws NullPointerException when members is null. Jackson calls all public getters during serialization, so any GET endpoint returning a project with members=null would return 500 in production. Test data in this PR sets members to a valid value to avoid masking other bugs; this secondary bug is documented in test comments.

Coverage Impact

Metric Before After
Tests run 38 54 (+16)
New failures 0
Pre-existing failures 2 2 (unchanged)
ProjectController line coverage ~0% ~85% (all endpoints exercised)

Trade-offs

  • Bug-pin tests assert current (wrong) behavior with clear comments explaining what to change on fix.
  • @WebMvcTest keeps tests fast (~0.7s total run time) with no DB or full context.
  • addMember duplicate-userId bug is documented in a comment rather than a dedicated test (requires the same request twice — out of scope for controller layer tests).

Test Status

Tests run: 54, Failures: 1, Errors: 1, Skipped: 7
New tests (ProjectControllerTest): 16 run, 0 failures, 0 errors

Pre-existing failures (not caused by this PR):

Reproducibility

mvn test -B
# New tests in ProjectControllerTest

Generated by Test Improver · 166.6 AIC · ⌖ 15.3 AIC · ⊞ 10.9K ·
Comment /test-assist to run again

Add this agentic workflows to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/test-improver.md@1c6668b751c51af8571f01204ceffb19362e0f66

- Tests for all 8 endpoints: GET /api/projects, GET /{id},
  GET /code/{code}, POST, PUT /{id}, DELETE /{id},
  GET /{id}/dashboard, POST /{id}/members
- Bug-pin: POST /api/projects returns 200 instead of 201 Created
- Bug-pin: GET /{id}/dashboard with taskCount=0 returns NaN in JSON
  body (Project.getProgress() returns NaN, which Jackson serializes
  as the literal token 'NaN' - not valid JSON)
- Documents getMemberIds() NPE when members is null (test data sets
  members to avoid triggering separate bug during serialization)

Tests run: 54 (+16), Failures: 1, Errors: 1, Skipped: 7
Pre-existing failures unchanged (DateUtilsTest#6, TaskServiceTest#3)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants