-
Notifications
You must be signed in to change notification settings - Fork 5
AIML-231: Phase 2 code quality improvements [STACKED] #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR completes Phase 2 of code quality improvements by adopting modern Java testing best practices. Following Phase 1's formatting and style standards (PR #29), this phase focuses on enhancing test code with AssertJ library adoption, proper logging, and documentation of simplified Mockito syntax.
Key Changes:
- Migrated all 894 JUnit assertions across 20 test files to AssertJ's fluent API for improved readability
- Replaced System.out/System.err with SLF4J logging in integration tests
- Documented Mockito 5.x+ simplified mock() syntax in coding standards
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| pom.xml | Added assertj-core 3.27.6 test dependency |
| CLAUDE.md | Added coding standards for AssertJ and simplified mock() syntax |
| 20 test files | Converted all assertions from JUnit to AssertJ fluent API |
| 4 integration test files | Added @slf4j annotation and replaced System.out/err with logging |
| VulnerabilityMapperTest.java, SCAServiceTest.java, RouteCoverageServiceTest.java, ADRServiceTest.java | Applied simplified mock() syntax |
Comments suppressed due to low confidence (1)
src/test/java/com/contrast/labs/ai/mcp/contrast/utils/PaginationHandlerTest.java:1
- Consider using
assertThat(params.warnings()).isEmpty()instead ofassertThat(params.warnings().isEmpty()).isTrue(). AssertJ provides direct collection assertions that are more idiomatic and produce better error messages.
/*
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/test/java/com/contrast/labs/ai/mcp/contrast/PaginationParamsTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/PaginationParamsTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/SCAServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/SCAServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/SCAServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/RouteCoverageServiceIntegrationTest.java
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/ADRServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/ADRServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/com/contrast/labs/ai/mcp/contrast/ADRServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
1f197f5 to
92062a4
Compare
5321490 to
eee2440
Compare
92062a4 to
ac20aba
Compare
…231) - Add @slf4j annotation to 3 integration test classes - Convert all System.out.println() calls to log.info() - Convert all System.err.println() calls to log.error() - Use parameterized logging where appropriate for performance - Apply Spotless formatting This improves test logging consistency and enables better log management. Child bead: mcp-f7r 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Document simplified mock() standard in CLAUDE.md - Convert all 34 mock(Class.class) calls to mock() - Update 5 test files to use type-explicit mock syntax - Follow Mockito 5.x+ best practices Examples: Before: var mock = mock(ClassName.class) After: ClassName mock = mock() Before: ClassName mock = mock(ClassName.class) After: ClassName mock = mock() Files updated: - ADRServiceTest.java (1 change) - SCAServiceTest.java (5 changes) - VulnerabilityMapperTest.java (18 changes) - AssessServiceTest.java (8 changes) - RouteCoverageServiceTest.java (2 changes) All tests pass with simplified mock() syntax. Child bead: mcp-ea6 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added assertj-core 3.27.6 dependency to pom.xml with test scope - Converted ~894 JUnit assertions to AssertJ fluent API across 20 test files - Updated imports from org.junit.jupiter.api.Assertions to org.assertj.core.api.Assertions - Applied conversion patterns: * assertEquals(expected, actual) → assertThat(actual).isEqualTo(expected) * assertTrue(condition) → assertThat(condition).isTrue() * assertFalse(condition) → assertThat(condition).isFalse() * assertNull(value) → assertThat(value).isNull() * assertNotNull(value) → assertThat(value).isNotNull() * assertThrows() → assertThatThrownBy().isInstanceOf() - Documented AssertJ usage standard in CLAUDE.md Coding Standards section - All 250 tests pass successfully Benefits: - More readable, fluent assertion syntax - Better error messages when tests fail - Richer assertion API (isEmpty(), hasSize(), contains(), etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive "Time Tracking for AI Cost Optimization" section to CLAUDE.md documenting the complete workflow for tracking time spent on beads to optimize AI development spend. Key features: - Comment-based time tracking with ⏱️ START/END markers - Label-based categorization for duration buckets and AI effectiveness - Parent vs child bead tracking strategies - Rating workflow with AI calculation and user confirmation - Analysis framework for identifying AI value patterns Workflow tracks: - Duration buckets: 0-15min, 15-30min, 30-60min, 1-2hr, 2hr+ - AI effectiveness: ai-multiplier, ai-helpful, ai-neutral, ai-friction - When to track: Parent beads (in_progress → PR), Child beads (start → close) Purpose: Identify which code change types benefit most from AI assistance and where AI adds friction vs value to optimize AI spend decisions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…rationTest (AIML-231) - Add @slf4j annotation to AssessServiceIntegrationTest - Convert all 62 remaining System.out.println() calls to log.info() - Apply Spotless formatting This completes the logging standardization work started in mcp-f7r, now covering all 4 integration test classes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Use direct collection assertions (isEmpty() instead of .isEmpty().isTrue()) - Fix string concatenation in log statements (use SLF4J placeholders) - Use direct comparison methods (isNotNegative() instead of >= 0 .isTrue()) - Improves test readability and follows AssertJ/SLF4J best practices All 250 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed remaining string concatenation issues in: - ADRServiceIntegrationTest (7 locations) - RouteCoverageServiceIntegrationTest (2 locations) All 250 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…IML-231) Address PR review feedback: 1. Convert string concatenation to parameterized logging in ADRServiceIntegrationTest - Line 190: Use log.error with parameter instead of string concatenation - Lines 284-287: Use log.info with parameters for rule count and app name 2. Remove tautological assertion at line 331 (assertThat(true).isTrue()) - Keep explanatory comment about test logic All 250 tests passing after changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…L-231)
Replace all string concatenation in log statements with SLF4J placeholders
for better performance. String concatenation in logs is inefficient because
the concatenation happens before checking if the log level is enabled.
Changes:
- Replace log.info("text " + var) with log.info("text {}", var)
- Apply to all test methods: testEnvironmentsAndTagsArePopulated,
testSessionMetadataIsPopulated, testVulnTagsWithSpacesHandledBySDK,
testListVulnsByAppIdWithSessionMetadata, and
testListVulnsByAppIdForLatestSession
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
0b45e7c to
0a9469c
Compare
Clarify the critical rebase step when promoting stacked PRs to avoid replaying commits that are already merged to main. This prevents conflicts and makes the promotion process smoother. Key improvements: - Emphasize using git rebase --onto instead of git rebase - Provide clear example with commit hashes - Explain how to identify the base commit - Add troubleshooting guidance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove two committed results-*.md files that should not be tracked. These are test result files similar to test-plan files and should remain local artifacts. Changes: - Removed results-list_vulns_by_app_and_metadata.md from tracking - Removed results-list_vulns_by_app_latest_session.md from tracking - Added results-*.md pattern to .gitignore 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove stale backup test plan file that should not be committed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| <dependency> | ||
| <groupId>org.assertj</groupId> | ||
| <artifactId>assertj-core</artifactId> | ||
| <version>3.27.6</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use the <properties></properties> element to specify versions
example:
Line 30 in 2601c03
| <spring-ai.version>1.0.1</spring-ai.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is up next for fixing. https://contrast.atlassian.net/browse/AIML-237
| import static org.junit.jupiter.api.Assertions.*; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.mockito.ArgumentMatchers.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are still wildcard imports defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Crap. I wonder if they came back in the merge issues I had. i'll address those too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added that to the same ticket https://contrast.atlassian.net/browse/AIML-237
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added that to the same ticket https://contrast.atlassian.net/browse/AIML-237
| <dependency> | ||
| <groupId>org.assertj</groupId> | ||
| <artifactId>assertj-core</artifactId> | ||
| <version>3.27.6</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we typically use the <properties></properties> element to specify versions.
example:
Line 30 in 2601c03
| <spring-ai.version>1.0.1</spring-ai.version> |
| import static org.junit.jupiter.api.Assertions.*; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.mockito.ArgumentMatchers.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are still wildcard imports here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be addressed in https://contrast.atlassian.net/browse/AIML-237
| import static org.junit.jupiter.api.Assertions.*; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.mockito.ArgumentMatchers.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wildcard import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be addressed in https://contrast.atlassian.net/browse/AIML-237
✅ Rebased onto main after PR #29 merged (2025-11-14 15:28:06 UTC)
Why
This PR continues the code quality initiative started in AIML-230 (PR #29), focusing on test quality improvements. After establishing core coding standards (Spotless, var usage, explicit imports), this phase addresses test maintainability through modern testing best practices.
Problem Statement:
What
This PR delivers three key test quality improvements:
All changes maintain 100% test coverage with 250 passing tests (unit + integration).
Note: This PR also includes documentation updates to CLAUDE.md for internal AI-assisted development workflow tracking. These workflow additions are internal development process documentation and not part of the MCP server product itself.
How
1. AssertJ Library Integration (mcp-a9j)
Implementation:
assertj-core:3.27.6dependency to pom.xml (test scope)assertEquals(expected, actual)→assertThat(actual).isEqualTo(expected)assertTrue(condition)→assertThat(condition).isTrue()assertNull(value)→assertThat(value).isNull()assertThrows()→assertThatThrownBy().isInstanceOf()Benefits:
assertThat(vulns).hasSize(10).allMatch(v -> v.severity() != null)isEmpty(),contains(),hasSize(),extracting()for complex validationsExample transformation:
2. Test Logging Standardization (mcp-f7r)
Implementation:
@Slf4jannotation to 3 integration test classesSystem.out.println()tolog.info()System.err.println()tolog.error()log.info("Found {} vulns", count)Benefits:
Files updated:
AssessServiceIntegrationTest.javaSCAServiceIntegrationTest.javaRouteCoverageServiceIntegrationTest.java3. Mock Syntax Modernization (mcp-ea6)
Implementation:
ClassName mock = mock();instead ofClassName mock = mock(ClassName.class);Why this matters:
ContrastSDK sdk = mock();vsContrastSDK sdk = mock(ContrastSDK.class);ClassName mock = mock();(explicit type) vsvar mock = mock(ClassName.class);Files updated:
4. Internal Development Workflow Documentation
Added AI-assisted development time tracking workflow to CLAUDE.md for internal use. This tracks development time and AI effectiveness to optimize development processes. This is internal tooling documentation only - not part of the MCP server product.
Step-by-Step Walkthrough
Phase 1: AssertJ Migration
org.junit.jupiter.api.Assertionstoorg.assertj.core.api.AssertionsPhase 2: Test Logging
@Slf4jto gain access tologfieldlog.info()with parameterized messageslog.error()with exception contextsPhase 3: Mock Modernization
Phase 4: Internal Workflow Documentation
Testing
Test Results:
Verification performed:
mvn clean verify✅mvn spotless:check✅Test coverage maintained:
Benefits Achieved
Related Work
Builds on AIML-230 (PR #29):
Branch:
AIML-231-phase-2-qualityBeads completed: mcp-a9j, mcp-f7r, mcp-ea6
Build status: ✅ All tests passing, code properly formatted
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com