Skip to content

Enhancement/write tests#8

Merged
codebyNorthsteep merged 6 commits into
mainfrom
enhancement/write-tests
May 8, 2026
Merged

Enhancement/write tests#8
codebyNorthsteep merged 6 commits into
mainfrom
enhancement/write-tests

Conversation

@codebyNorthsteep

@codebyNorthsteep codebyNorthsteep commented May 8, 2026

Copy link
Copy Markdown
Owner

This pull request improves validation, adds comprehensive unit and integration tests, and clarifies session management in the Bifrost chat service. The main changes include enhanced validation for chat requests, expanded test coverage for both the controller and service layers, and improvements to session storage and cleanup.

Validation Improvements

  • Added custom validation messages for each field in the ChatRequestDTO record to provide clearer error feedback when required fields are missing or empty.

Testing Enhancements

  • Introduced BifrostControllerTest to verify correct HTTP responses for valid and invalid chat requests, including chat history retrieval.
  • Added new tests in ChatServiceTest to cover complete chat flows, empty LLM responses, server errors, and circuit breaker logic, ensuring robust error handling and session management. [1] [2] [3]
  • Added ChatSessionStorageTest to verify session creation, retrieval, and deletion logic in session storage.

Session Management and Cleanup

  • Documented the deleteSession method in ChatSessionStorage and added a note about considering automatic cleanup strategies for production use.

API Adjustments

  • Removed the unused /bifrost GET endpoint from BifrostController to clean up the API surface.

Summary by CodeRabbit

  • Breaking Changes

    • Removed /api/bifrost endpoint; clients must migrate to /api/v1/chat endpoints.
  • Improvements

    • Enhanced validation error messages for chat requests to provide clearer feedback on missing or invalid fields.
    • Improved documentation for session management behavior.
  • Tests

    • Added comprehensive test coverage for chat endpoints, session storage, and service layer interactions.

@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@codebyNorthsteep has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 51 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c74f0cfe-b79d-4bbe-9dcd-c223154cc143

📥 Commits

Reviewing files that changed from the base of the PR and between 669c7fd and fd07a80.

📒 Files selected for processing (2)
  • src/test/java/org/example/projectbifrost/controller/BifrostControllerTest.java
  • src/test/java/org/example/projectbifrost/service/ChatServiceTest.java
📝 Walkthrough

Walkthrough

Removes the legacy GET /api/bifrost endpoint from the controller, adds explicit custom validation messages to ChatRequestDTO, documents storage deletion behavior, and introduces three comprehensive test classes covering controller HTTP flows, service chat operations with error handling, and storage session lifecycle semantics.

Changes

Controller API Refactor and Test Suite

Layer / File(s) Summary
Request Validation Contract
src/main/java/org/example/projectbifrost/dto/ChatRequestDTO.java
ChatRequestDTO record annotations updated with custom messages on @NotNull and @NotBlank constraints for personality, message, and sessionId fields.
Controller Endpoint Changes
src/main/java/org/example/projectbifrost/BifrostController.java
GET /api/bifrost endpoint removed; controller retains only POST /api/v1/chat and GET /api/v1/chat/{sessionId} handlers.
Storage Layer Documentation
src/main/java/org/example/projectbifrost/storage/ChatSessionStorage.java
Javadoc added to deleteSession method documenting the deletion behavior and recommending production-ready cleanup strategies to prevent unbounded memory growth.
Controller Integration Tests
src/test/java/org/example/projectbifrost/controller/BifrostControllerTest.java
New @WebMvcTest test class with MockMvc and mocked ChatService; verifies POST /api/v1/chat returns 200 for valid payload and 400 for missing message, and GET /api/v1/chat/{sessionId} returns 200 for existing sessions.
Service Unit Tests with Error Paths
src/test/java/org/example/projectbifrost/service/ChatServiceTest.java
Enhanced test imports and new test cases: successful chatWithLLM flow verifying session/history persistence, exception handling for empty LLM choices array, HTTP 500 error response handling, and circuit breaker test refactoring with reusable message construction.
Storage Session Lifecycle Tests
src/test/java/org/example/projectbifrost/storage/ChatSessionStorageTest.java
New JUnit 5 test class verifying getOrCreateChatSession creates sessions with non-null ID and history, returns the same instance on repeated calls with the same ID, and deleteSession causes subsequent calls to produce a different instance.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • codebyNorthsteep/ProjectBifrost#5: Both PRs refactor the controller service integration and introduce the chatWithLLM method with retry/circuit-breaker behavior that is now being tested.
  • codebyNorthsteep/ProjectBifrost#1: Both PRs modify the same BifrostController endpoints and the /api/v1/chat request handlers.
  • codebyNorthsteep/ProjectBifrost#3: Both PRs modify the controller request validation surface by updating BifrostController and ChatRequestDTO to enforce and handle request validation constraints.

Poem

A bifrost once spanned from /bifrost to chat,
But now we validate with messages, flat and slat.
Tests multiply like rabbits in a burrow deep,
Controller, service, storage—no stone left to heap! 🐰✨
The API hops forward, cleaner and bright.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Enhancement/write tests' is vague and generic, using non-descriptive terms that fail to convey the specific nature of changes beyond a general reference to tests. Refine the title to specify the main focus, such as 'Add comprehensive test coverage for chat service and controller' or 'Improve validation messages and expand test suite.'
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enhancement/write-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/test/java/org/example/projectbifrost/service/ChatServiceTest.java (1)

168-168: 💤 Low value

Inconsistent: new List.of(...) instead of the already-defined messages variable.

The messages variable defined on line 132 was explicitly introduced to be reused — yet line 168 constructs an identical new list instead.

✨ Proposed fix
-        String result = chatService.fetchResponseFromLLM(List.of(new OpenRouterRequestDTO.Message("user", "Hello")));
+        String result = chatService.fetchResponseFromLLM(messages);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/example/projectbifrost/service/ChatServiceTest.java` at
line 168, Replace the ad-hoc list construction in the test with the existing
messages variable: in ChatServiceTest, change the argument passed to
chatService.fetchResponseFromLLM(...) (currently List.of(new
OpenRouterRequestDTO.Message("user", "Hello"))) to use the previously defined
messages variable so the test reuses the setup and avoids duplicating the
message list used in other assertions.
src/test/java/org/example/projectbifrost/storage/ChatSessionStorageTest.java (1)

43-58: ⚡ Quick win

shouldDeleteSession is misleadingly written — oldSession is not the pre-deletion session.

The variable named oldSession (line 53) is actually a new session created after the first deleteSession call, not the original session from line 48. The comment // this session was removed is also wrong — S2 is freshly created at that point.

The test is functionally correct (a no-op deleteSession would cause oldSession == newSession, failing the assertion), but the misleading naming creates a false impression that the original instance is being compared.

A simpler and clearer expression of the same intent:

♻️ Proposed refactor
     `@Test`
     `@DisplayName`("Should delete session")
     void shouldDeleteSession() {
         String sessionId = "goodbye-session";

-        storage.getOrCreateChatSession(sessionId);
-
+        ChatSession original = storage.getOrCreateChatSession(sessionId);
         storage.deleteSession(sessionId);
-
-        // After delete, when calling getOrCreate it should create a new session, so we can check that it's different from the old one
-        ChatSession oldSession = storage.getOrCreateChatSession(sessionId); // this session was removed
-        storage.deleteSession(sessionId);
-        ChatSession newSession = storage.getOrCreateChatSession(sessionId);
-
-        assertThat(newSession).isNotSameAs(oldSession);
+        ChatSession recreated = storage.getOrCreateChatSession(sessionId);
+
+        assertThat(recreated).isNotSameAs(original);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/example/projectbifrost/storage/ChatSessionStorageTest.java`
around lines 43 - 58, The test should capture the pre-deletion session, then
delete it, then create a new session to compare; change the sequence in
shouldDeleteSession so you call ChatSession originalSession =
storage.getOrCreateChatSession(sessionId) first, then call
storage.deleteSession(sessionId), then call ChatSession newSession =
storage.getOrCreateChatSession(sessionId) and
assertThat(newSession).isNotSameAs(originalSession); also rename variables
(originalSession/newSession) and update the incorrect comment that claimed the
post-delete session was the removed one, referencing the test method
shouldDeleteSession and calls to storage.getOrCreateChatSession and
storage.deleteSession.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/test/java/org/example/projectbifrost/controller/BifrostControllerTest.java`:
- Line 16: The import for the get request builder in BifrostControllerTest is
using org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
replace that import so the static get comes from
org.springframework.test.web.servlet.request.MockMvcRequestBuilders (to match
the existing post import and standard MockMvc usage) — update the static import
for get in the BifrostControllerTest class to MockMvcRequestBuilders.get
wherever it currently references RestDocumentationRequestBuilders.get.

In `@src/test/java/org/example/projectbifrost/service/ChatServiceTest.java`:
- Line 69: The two tests in ChatServiceTest (testEmptyAnswerFromLLM and
testServerErrorThrowsException) share the same ChatRequestDTO session id
"session-123" which can leak state via chatWithLLM; update each test to use
distinct session ids (e.g., "session-empty-<unique>" and
"session-servererror-<unique>") when constructing ChatRequestDTO so session
state cannot be shared across tests and rerun in the shared Spring context.

---

Nitpick comments:
In `@src/test/java/org/example/projectbifrost/service/ChatServiceTest.java`:
- Line 168: Replace the ad-hoc list construction in the test with the existing
messages variable: in ChatServiceTest, change the argument passed to
chatService.fetchResponseFromLLM(...) (currently List.of(new
OpenRouterRequestDTO.Message("user", "Hello"))) to use the previously defined
messages variable so the test reuses the setup and avoids duplicating the
message list used in other assertions.

In
`@src/test/java/org/example/projectbifrost/storage/ChatSessionStorageTest.java`:
- Around line 43-58: The test should capture the pre-deletion session, then
delete it, then create a new session to compare; change the sequence in
shouldDeleteSession so you call ChatSession originalSession =
storage.getOrCreateChatSession(sessionId) first, then call
storage.deleteSession(sessionId), then call ChatSession newSession =
storage.getOrCreateChatSession(sessionId) and
assertThat(newSession).isNotSameAs(originalSession); also rename variables
(originalSession/newSession) and update the incorrect comment that claimed the
post-delete session was the removed one, referencing the test method
shouldDeleteSession and calls to storage.getOrCreateChatSession and
storage.deleteSession.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 878b93e9-c641-40a5-bdfb-f275bc253d43

📥 Commits

Reviewing files that changed from the base of the PR and between 818b5e4 and 669c7fd.

📒 Files selected for processing (6)
  • src/main/java/org/example/projectbifrost/BifrostController.java
  • src/main/java/org/example/projectbifrost/dto/ChatRequestDTO.java
  • src/main/java/org/example/projectbifrost/storage/ChatSessionStorage.java
  • src/test/java/org/example/projectbifrost/controller/BifrostControllerTest.java
  • src/test/java/org/example/projectbifrost/service/ChatServiceTest.java
  • src/test/java/org/example/projectbifrost/storage/ChatSessionStorageTest.java
💤 Files with no reviewable changes (1)
  • src/main/java/org/example/projectbifrost/BifrostController.java

Comment thread src/test/java/org/example/projectbifrost/controller/BifrostControllerTest.java Outdated
Comment thread src/test/java/org/example/projectbifrost/service/ChatServiceTest.java Outdated
@codebyNorthsteep
codebyNorthsteep merged commit 20fbef2 into main May 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant