Skip to content

Test/authenticated endpoints#84

Open
Emilyempa wants to merge 6 commits intomainfrom
test/authenticated-endpoints
Open

Test/authenticated endpoints#84
Emilyempa wants to merge 6 commits intomainfrom
test/authenticated-endpoints

Conversation

@Emilyempa
Copy link
Contributor

@Emilyempa Emilyempa commented Dec 11, 2025

Description

  • A test exists that attempts to call POST /api/reports without authentication and expects a 3xx.

  • A test exists that calls POST /api/reports with valid authentication and expects a successful response (201 Created or appropriate status).

Made by
@Emilyempa
@alfredbrannare
@Klumpish

Summary by CodeRabbit

  • Refactor

    • Improved OAuth2 user identification to more reliably handle different token attribute formats, increasing robustness of authentication flows.
  • Tests

    • Added end-to-end test coverage for secured report creation, verifying both unauthenticated rejection and authenticated report creation to ensure correct authorization behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@Emilyempa Emilyempa linked an issue Dec 11, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Dec 11, 2025

Walkthrough

Introduced a private helper to centralize OAuth2 user ID extraction (checks sub, id, user_id) and updated getUserId to use it; added Javadoc. Added a new MockMvc integration test class with two tests for the secured report creation endpoint (unauthenticated redirect and authenticated 201 Created).

Changes

Cohort / File(s) Change Summary
OAuth2 User ID Extraction Refactor
backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java
Added private helper extractOAuth2UserId(OAuth2User) that returns sub, then id, then user_id, or throws if none found. getUserId(Authentication) now delegates OAuth2 principal handling to this helper. Added Javadoc to both methods.
Secured Report Controller Tests
backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java
New test class using Spring Boot Test & MockMvc (imports TestcontainersConfiguration). Adds createReportWithoutAuthorization expecting a 3xx redirect and createReportWithAuthorization using an OAuth2 login mock (provides name, email, sub) expecting 201 Created. Uses Jackson with JavaTimeModule for Instant serialization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Pay attention to:
    • The attribute lookup order and exception path in extractOAuth2UserId.
    • Test setup for MockMvc and the OAuth2 login mock to ensure it matches security configuration and attribute names.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test/authenticated-endpoints

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.

@jenkins-cd-for-zipp
Copy link

Jenkins Build #1 Summary (for PR #84)

  • Status: SUCCESS
  • Duration: 1 min 31 sec
  • Branch: PR-84
  • Commit: e37162b
  • Docker Image: 192.168.0.82:5000/zipp:e37162b (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Passed
  • Push: Successful

All stages passed—no issues detected.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java (1)

43-58: Tighten success assertion and align OAuth2 attributes with ID extraction

  • The PR description mentions expecting a created response; if POST /api/reports returns 201, consider asserting status().isCreated() instead of the broader is2xxSuccessful() so the test locks in the intended contract.
  • Your mocked OAuth2 principal only explicitly sets name, email, and role. Since UserIdentityService.extractOAuth2UserId looks for sub, id, or user_id, it’s safer to ensure one of those attributes is present in this mock (e.g., user.put("sub", "test-user-id");) so the test mirrors real authentication data and avoids unexpected IllegalStateException if that service is used in the report flow.
  • Both tests duplicate the Report creation and ObjectMapper + JavaTimeModule setup; you could factor these into helper methods or a @BeforeEach to keep the tests DRY (optional).
backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java (1)

20-65: OAuth2 ID extraction is clear; consider a security-specific exception type

The new getUserId / extractOAuth2UserId logic is straightforward and covers common OAuth2 ID attributes (sub, id, user_id). The main behavioral change is throwing IllegalStateException when no ID can be derived (or when authentication is null). Unless you already translate these exceptions, this is likely to bubble up as a 500 response rather than a 401/403.

Consider using a Spring Security–specific exception (e.g., AuthenticationCredentialsNotFoundException or another appropriate AuthenticationException/AccessDeniedException) or handling this case closer to the web layer so clients receive an auth-related status instead of a generic server error.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8708758 and e37162b.

📒 Files selected for processing (3)
  • backend/pom.xml (1 hunks)
  • backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java (2 hunks)
  • backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: PR Build
  • GitHub Check: Jenkins
  • GitHub Check: Build, Test & Analyze
🔇 Additional comments (1)
backend/pom.xml (1)

120-123: Jackson JavaTime module dependency fits the new test usage

Adding jackson-datatype-jsr310 is consistent with your use of JavaTimeModule for Instant serialization and will help ensure runtime JSON handling of Java time types works as expected. No issues from a build/config perspective.

@jenkins-cd-for-zipp
Copy link

Jenkins Build #2 Summary (for PR #84)

  • Status: SUCCESS
  • Duration: 1 min 45 sec
  • Branch: PR-84
  • Commit: 35782f8
  • Docker Image: 192.168.0.82:5000/zipp:35782f8 (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Passed
  • Push: Successful

All stages passed—no issues detected.

# Conflicts:
#	backend/pom.xml
#	backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java
@jenkins-cd-for-zipp
Copy link

Jenkins Build #4 Summary (for PR #84)

  • Status: FAILURE
  • Duration: 1 min 3 sec
  • Branch: PR-84
  • Commit: 78fe42d
  • Docker Image: 192.168.0.82:5000/zipp:78fe42d (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Failed (check logs below)
  • Push: Skipped (due to earlier failure)

Error Logs (truncated):
For full logs, contact the Jenkins admin.

@jenkins-cd-for-zipp
Copy link

Jenkins Build #5 Summary (for PR #84)

  • Status: FAILURE
  • Duration: 50 min
  • Branch: PR-84
  • Commit: fa1307e
  • Docker Image: 192.168.0.82:5000/zipp:fa1307e (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Failed (check logs below)
  • Push: Skipped (due to earlier failure)

Error Logs (truncated):
For full logs, contact the Jenkins admin.

…d run:

- ./mvnw verify
- ./mvnw spotless:apply
- ./mvnw spotless:check
- ./mvnw checkstyle:check

# Conflicts:
#	backend/pom.xml
#	backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java
…gover/zipp into test/authenticated-endpoints

# Conflicts:
#	backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java
#	backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java
@jenkins-cd-for-zipp
Copy link

Jenkins Build #6 Summary (for PR #84)

  • Status: SUCCESS
  • Duration: 1 min 37 sec
  • Branch: PR-84
  • Commit: a88dbcb
  • Docker Image: 192.168.0.82:5000/zipp:a88dbcb (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Passed
  • Push: Successful

All stages passed—no issues detected.

@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78fe42d and 82a8397.

📒 Files selected for processing (2)
  • backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java (2 hunks)
  • backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/main/java/org/fungover/zipp/service/UserIdentityService.java
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java (1)
backend/src/test/java/org/fungover/zipp/authtest/AuthenticationIntegrationTest.java (1)
  • SpringBootTest (24-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: PR Build
  • GitHub Check: Jenkins
  • GitHub Check: Build, Test & Analyze
🔇 Additional comments (2)
backend/src/test/java/org/fungover/zipp/controller/SecuredReportControllerTest.java (2)

1-40: LGTM!

The imports and class setup are appropriate for integration testing with MockMvc, OAuth2, and Testcontainers.


57-72: LGTM!

The setup correctly prepares the test user, configures Jackson to handle Instant serialization, and mocks Kafka to prevent actual message publishing.

Copy link
Contributor

@Jorlindstrom Jorlindstrom left a comment

Choose a reason for hiding this comment

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

The implementation shows a solid understanding of Spring Security, OAuth2 authentication, and integration testing with MockMvc. The code is generally well structured, readable, and defensive, especially in how authentication and principal extraction are handled. The test coverage demonstrates that both authenticated and unauthenticated flows have been considered, which is an important strength from a security perspective.

That said, there are a few architectural and maintainability concerns worth addressing before this is merged.

SecuredReportControllerTest

Lines ~32–35
@SpringBootTest
@AutoConfigureMockMvc

This test loads the full application context even though the test scope is limited to controller + security behavior.

Action: Consider replacing with @WebMvcTest(ReportController.class), Mock required collaborators instead of starting the full context

Keep @SpringBootTest only if database + Kafka wiring is intentionally under test

Lines ~44–50
@MockitoBean
private KafkaTemplate<String, ReportResponse> kafkaTemplate;

@MockitoBean
private KafkaAdmin kafkaAdmin;

Kafka infrastructure is mocked, but the test still implicitly depends on messaging configuration being present.

Action: Verify whether Kafka is actually required for this controller test
If not, exclude Kafka auto-configuration or move Kafka behavior into a separate integration test

Lines ~58–66
@beforeeach
void setup() {
user = new User();
user.setName("Test User");
...
}

The test manually constructs a User entity with multiple fields.

Action: Introduce a test fixture or builder (e.g. TestUserFactory.createUser()), Avoid coupling tests to entity internals that may change

Lines ~76–83
Report firstReport = new Report(
user,
"Candy paper",
ReportType.DEBRIS,
...
);

The test constructs a domain object with fields (status, timestamps) that are not directly relevant to authorization.

Action: Use a minimal request DTO instead of the domain entity

Focus the test on authorization behavior, not entity completeness

Lines ~87–89
.andExpect(status().is3xxRedirection());

The test asserts only that the user is redirected.

Action: Also assert the redirect target if possible (e.g. /login), This makes the intent of the test clearer

Lines ~94–104
.with(oauth2Login().attributes(u -> {
u.put("name", "Test User");
u.put("email", "test@gmail.com");
u.put("sub", user.getProviderId());
}))

OAuth2 attributes are defined inline.

Action: Extract OAuth2 user creation into a helper method, This avoids duplication and improves readability across tests

UserIdentityService

Lines ~24–26
public String getUserId(Authentication authentication)

This method mixes identity extraction and authentication validation.

Action: Extract identity resolution into a separate private or dedicated class, Keep this method focused on delegation rather than logic branching

Lines ~37–45
if (principal instanceof OAuth2User oAuth2User) {
return extractOAuth2UserId(oAuth2User);
}

OAuth2 user handling is correct, but the method returns a raw String without context.

Action: Document whether this ID is guaranteed to be a provider ID, Consider returning a value object instead of a raw string

Lines ~55–72
public User getCurrentUser(Authentication authentication)

This method handles: authentication validation, identity extraction, repository lookups, error handling

Action:
Split into: resolveProviderId(Authentication) and loadUserByProviderId(String)
This improves testability and readability

Lines ~61–68
String email = oauth.getAttribute("email");
if (email != null && !email.isBlank()) {
return userRepository.findByEmail(email)

User lookup prioritizes email over provider ID.

Action (important): Use provider ID as the primary lookup key, Treat email as metadata only
This prevents account duplication and login inconsistencies

Lines ~96–99
throw new IllegalStateException(
"Unsupported principal type: " + principal.getClass().getName()
);

The error message is clear, but the exception type is very generic.

Action: Replace with a more specific exception (e.g., AuthenticationCredentialsNotFoundException)

This improves error handling and security clarity

Lines ~109–128
private String extractOAuth2UserId(OAuth2User oAuth2User)

The method correctly checks multiple attribute names.

Action: Consider externalizing supported attribute names into a constant list, This makes future extensions simpler and safer

@alfredbrannare
Copy link
Contributor

alfredbrannare commented Dec 17, 2025

Thanks for the feedback @Jorlindstrom !

Action: Verify whether Kafka is actually required for this controller test

Haven't gotten it to work without Kafka. It's mocked with @MockitoBean so it doesn't actually run, but Spring Boot needs the dependency since the controller uses it.

Action: Use a minimal request DTO instead of the domain entity

We are using the Report DTO not the ReportEntity Entity. This is required since it is the DTO used to make Report request. The test itself is not regarding that but for ensuring you are authenticated when posting, and in order to do that we had to simulate a real post.

About using @WebMvcTest instead of @SpringBootTest

This is an integration test for the security/authentication flow, not a unit test. We need the actual security config, database, and OAuth2 setup running. @WebMvcTest would mock too much and we wouldn't actually be testing authentication.

About the User field in the DTO
The User submittedBy field was initially removed in #74 but got added back by someone else, I have no idea why though. I agree it shouldn't be there since the controller already extracts the user from authentication. But that's a separate API design issue, not something wrong with the test I think.

Copy link
Contributor

@viktornoskire viktornoskire left a comment

Choose a reason for hiding this comment

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

From what I can see the tests work as intended. The code is clean and easy to read. Good job in working with so many different things but still keeping it clean. I'd say this is ready to be merged into main.

Copy link
Contributor

@LolloGro LolloGro left a comment

Choose a reason for hiding this comment

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

The test is valide, the code is easy to read and its clear what the test tests. Good work!

@LolloGro LolloGro enabled auto-merge December 18, 2025 13:50
@Emilyempa Emilyempa dismissed Jorlindstrom’s stale review December 18, 2025 14:17

@alfred gave good answer in this PR about why

@LolloGro LolloGro added this pull request to the merge queue Dec 18, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 18, 2025
@Emilyempa Emilyempa added this pull request to the merge queue Dec 18, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 18, 2025
@Klumpish Klumpish added this pull request to the merge queue Dec 18, 2025
github-merge-queue bot pushed a commit that referenced this pull request Dec 18, 2025
* Add test for redirect if not logged in and test for logged in POSTs to REST API

* Write a simple SecuredReportControllerTest to test report creation with and without authorization

* Run the maven commands

---------

Co-authored-by: Alfred Brännare <alfred-brannare@hotmail.com>
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 18, 2025
@Klumpish Klumpish added this pull request to the merge queue Dec 19, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 19, 2025
@jenkins-cd-for-zipp
Copy link

Jenkins Build #7 Summary (for PR #84)

  • Status: SUCCESS
  • Duration: 1 min 39 sec
  • Branch: PR-84
  • Commit: 9030efe
  • Docker Image: 192.168.0.82:5000/zipp:9030efe (pushed to registry)

Details:

  • Checkout: Successful
  • Build & Scan: Passed
  • Push: Successful

All stages passed—no issues detected.

@Tarupotter Tarupotter self-requested a review December 19, 2025 22:20
Copy link
Contributor

@Tarupotter Tarupotter left a comment

Choose a reason for hiding this comment

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

the tests are clear and structured, and I am really impressed by your dedication and contribution to this project :))

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.

Add test to check authentication for POST

7 participants