Skip to content

Add Unit Tests for SecurityHeadersFilter - #141

Merged
johanbriger merged 6 commits into
mainfrom
138-add-unit-tests-for-securityheadersfilter
Feb 27, 2026
Merged

Add Unit Tests for SecurityHeadersFilter#141
johanbriger merged 6 commits into
mainfrom
138-add-unit-tests-for-securityheadersfilter

Conversation

@johanbriger

@johanbriger johanbriger commented Feb 26, 2026

Copy link
Copy Markdown

The tests should verify that security headers are correctly appended to the HttpResponse and that the filter handles various scenarios, such as exceptions in the filter chain.

Currently, the filter is implemented but lacks automated verification, making it difficult to detect if changes in the Pipeline or HttpResponse classes break our security configurations.

Summary by CodeRabbit

  • Bug Fixes
    • Security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy) are now added only when missing, preserving existing values.
  • Refactor
    • Header application centralized via a helper to ensure consistent, non-destructive behavior.
  • Tests
    • Added tests covering normal flow, error/exception flow (ensuring exceptions propagate), and preservation of pre-existing security headers.

@johanbriger johanbriger self-assigned this Feb 26, 2026
@johanbriger johanbriger linked an issue Feb 26, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e99836c and 6ef919e.

📒 Files selected for processing (1)
  • src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java

📝 Walkthrough

Walkthrough

Adds tests for SecurityHeadersFilter and changes the filter to set four security headers only when missing, preserving existing header values and still applying defaults even if the delegated FilterChain throws an IOException.

Changes

Cohort / File(s) Summary
SecurityHeadersFilter Tests
src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java
Adds JUnit 5 + Mockito tests covering normal flow, exception flow (delegated FilterChain throws IOException), and preservation of existing headers; asserts presence of X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy.
SecurityHeadersFilter Implementation
src/main/java/org/juv25d/filter/SecurityHeadersFilter.java
Adds private applyDefaultHeader(HttpServletResponse, String, String) and changes header assignments to conditionally set defaults only when absent (preserves pre-existing headers); defaults are applied in a finally block so they run even if the chain throws.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    rect rgba(200,200,255,0.5)
    participant Filter as SecurityHeadersFilter
    end
    rect rgba(200,255,200,0.5)
    participant Chain as FilterChain
    end
    participant Response as HttpServletResponse

    Client->>Filter: HTTP request
    Filter->>Chain: chain.doFilter(request, response)
    alt Chain succeeds
        Chain-->>Filter: returns
    else Chain throws IOException
        Chain-->>Filter: throws IOException
    end
    Note over Filter,Response: finally block calls applyDefaultHeader for each header if missing
    Filter->>Response: set default headers only when absent
    Filter-->>Client: continue or propagate exception
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • met4lk1tty
  • mattknatt
  • lindaeskilsson

Poem

🐇 I hop through headers, soft and quick,
I leave what's set and patch the trick.
DENY and nosniff, XSS to none,
No-referrer stays when day is done.
If chains trip, I still finish the run. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding unit tests for SecurityHeadersFilter. It is specific, clear, and directly reflects the primary purpose of the changeset.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 138-add-unit-tests-for-securityheadersfilter

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: 1

🧹 Nitpick comments (1)
src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java (1)

37-40: Prefer response.getHeader(...) for assertions.

Line 37–40 and Line 55 bypass HttpResponse’s case-insensitive header lookup by calling response.headers().get(...) directly. Using getHeader(...) makes the tests more robust.

Also applies to: 55-55

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java` around lines
37 - 40, In SecurityHeadersFilterTest update the assertions that currently call
response.headers().get(...) to use HttpResponse's case-insensitive lookup method
response.getHeader(...); replace each assertEquals(...,
response.headers().get("Header-Name")) with assertEquals(...,
response.getHeader("Header-Name")) for the X-Content-Type-Options,
X-Frame-Options, X-XSS-Protection, Referrer-Policy assertions (and the other
occurrence near the end of the test) so the tests use the intended
case-insensitive header accessor.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java`:
- Around line 44-56: The test should not swallow the IOException and should
validate all security headers on the exception path: replace the try/catch
around filter.doFilter(mockRequest, response, mockChain) with an assertion that
the call throws (e.g., use assertThrows against IOException for
filter.doFilter(...)) so failures propagate, and after capturing the exception
assert that response.headers() contains the expected security headers (not just
"X-Frame-Options") — update should reference the existing test method
shouldAddHeadersEvenIfChainThrowsException, mockChain, filter.doFilter, and
response.headers() to locate and modify the assertions.

---

Nitpick comments:
In `@src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java`:
- Around line 37-40: In SecurityHeadersFilterTest update the assertions that
currently call response.headers().get(...) to use HttpResponse's
case-insensitive lookup method response.getHeader(...); replace each
assertEquals(..., response.headers().get("Header-Name")) with assertEquals(...,
response.getHeader("Header-Name")) for the X-Content-Type-Options,
X-Frame-Options, X-XSS-Protection, Referrer-Policy assertions (and the other
occurrence near the end of the test) so the tests use the intended
case-insensitive header accessor.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e46bb6b and c4d345c.

📒 Files selected for processing (1)
  • src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java

Comment thread src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java

@DennSel DennSel 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.

Great tests already! One addition could be a test case for when headers already exist in the response? Should the filter overwrite existing headers or preserve them? This could be relevant if other filters in the chain set similar security headers.

Tyreviel
Tyreviel previously approved these changes Feb 27, 2026

@Tyreviel Tyreviel 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.

Good work! found a small bug that could lead to duplicate headers, (that would require this test suite to have another test if adressed), but maybe that should be a separate issue and PR?

Added a new test case 'shouldPreserveExistingHeaders

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/org/juv25d/filter/SecurityHeadersFilter.java`:
- Around line 30-35: The comment for applyDefaultHeader says it checks for
missing or empty headers but the code only checks for null; update
applyDefaultHeader to treat empty strings as missing by checking if
res.getHeader(headerName) is null or empty (e.g., trim().isEmpty()) before
calling res.setHeader(headerName, defaultValue), or if empty values are
intentional, change the comment to only mention "missing (null)" to keep them
consistent; refer to the applyDefaultHeader(HttpResponse res, String headerName,
String defaultValue) method and the res.getHeader(headerName) call when making
the change.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd4a3dc and d56b86d.

📒 Files selected for processing (2)
  • src/main/java/org/juv25d/filter/SecurityHeadersFilter.java
  • src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java

Comment thread src/main/java/org/juv25d/filter/SecurityHeadersFilter.java
DennSel
DennSel previously approved these changes Feb 27, 2026

@DennSel DennSel 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.

Great additions, maybe remove the comments made in swedish. Approved.

Comment thread src/test/java/org/juv25d/filter/SecurityHeadersFilterTest.java Outdated
Tyreviel
Tyreviel previously approved these changes Feb 27, 2026

@Tyreviel Tyreviel 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.

looks good, approved

@johanbriger
johanbriger dismissed stale reviews from Tyreviel and DennSel via 6ef919e February 27, 2026 11:24

@Tyreviel Tyreviel 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.

👍

@eafalkens eafalkens 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.

I think it looks good, great job. Approved.

@johanbriger
johanbriger merged commit d46787e into main Feb 27, 2026
2 checks 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.

Add Unit Tests for SecurityHeadersFilter

4 participants