|
3 | 3 | require 'test_helper' |
4 | 4 |
|
5 | 5 | class DeveloperPortal::ContentSecurityPolicyTest < ActionDispatch::IntegrationTest |
6 | | - def setup |
7 | | - @provider = FactoryBot.create(:provider_account) |
8 | | - @buyer = FactoryBot.create(:buyer_account, provider_account: @provider) |
9 | | - login_buyer @buyer |
10 | | - end |
11 | 6 |
|
12 | | - test 'applies CSP header to developer portal HTML responses' do |
13 | | - get '/admin' |
| 7 | + class TestController < ApplicationController |
| 8 | + def html |
| 9 | + render html: '<html><body>Test</body></html>'.html_safe |
| 10 | + end |
14 | 11 |
|
15 | | - assert_response :success |
16 | | - assert_not_nil response.headers['Content-Security-Policy'] |
| 12 | + def json |
| 13 | + render json: { test: true } |
| 14 | + end |
17 | 15 |
|
18 | | - csp_header = response.headers['Content-Security-Policy'] |
19 | | - # Verify permissive policy for developer portal |
20 | | - assert_includes csp_header, "*" |
21 | | - assert_includes csp_header, "'unsafe-eval'" |
| 16 | + def not_modified |
| 17 | + head :not_modified |
| 18 | + end |
22 | 19 | end |
23 | 20 |
|
24 | | - test 'CSP header is applied to authenticated pages' do |
25 | | - get '/admin/account/edit' |
26 | | - |
27 | | - assert_response :success |
28 | | - assert_not_nil response.headers['Content-Security-Policy'] |
| 21 | + def with_test_routes |
| 22 | + DeveloperPortal::Engine.routes.draw do |
| 23 | + get '/test/csp/html' => 'content_security_policy_test/test#html' |
| 24 | + get '/test/csp/json' => 'content_security_policy_test/test#json' |
| 25 | + get '/test/csp/304' => 'content_security_policy_test/test#not_modified' |
| 26 | + end |
| 27 | + yield |
| 28 | + ensure |
| 29 | + Rails.application.routes_reloader.reload! |
29 | 30 | end |
30 | 31 |
|
31 | | - test 'middleware handles 304 Not Modified responses correctly' do |
32 | | - # The middleware has special handling for 304 responses to avoid |
33 | | - # nonce mismatches with cached content. This test verifies the middleware |
34 | | - # returns early for 304 responses. |
35 | | - |
36 | | - # Make a request |
37 | | - get '/admin' |
38 | | - first_csp = response.headers['Content-Security-Policy'] |
39 | | - |
40 | | - assert_response :success |
41 | | - assert_not_nil first_csp |
42 | | - |
43 | | - # NOTE: The 304 handling is tested at the middleware level in unit tests. |
44 | | - # Integration tests can't easily simulate the exact conditions where |
45 | | - # Rails returns a 304 before middleware runs. |
| 32 | + def setup |
| 33 | + @provider = FactoryBot.create(:provider_account) |
| 34 | + @buyer = FactoryBot.create(:buyer_account, provider_account: @provider) |
| 35 | + host! @provider.internal_domain |
46 | 36 | end |
47 | 37 |
|
48 | 38 | test 'includes configured directives from YAML' do |
49 | | - get '/admin' |
50 | | - |
51 | | - assert_response :success |
52 | | - csp_header = response.headers['Content-Security-Policy'] |
53 | | - |
54 | | - # Verify it contains the permissive default_src directive from developer_portal_policy |
55 | | - assert_includes csp_header, "default-src" |
56 | | - assert_includes csp_header, "*" |
57 | | - assert_includes csp_header, "'unsafe-eval'" |
58 | | - assert_includes csp_header, "'unsafe-inline'" |
| 39 | + with_test_routes do |
| 40 | + get '/test/csp/html' |
| 41 | + |
| 42 | + assert_response :success |
| 43 | + csp_header = response.headers['Content-Security-Policy'] |
| 44 | + |
| 45 | + # Verify it contains the permissive default_src directive from developer_portal_policy |
| 46 | + assert_includes csp_header, "default-src" |
| 47 | + assert_includes csp_header, "*" |
| 48 | + assert_includes csp_header, "'unsafe-eval'" |
| 49 | + assert_includes csp_header, "'unsafe-inline'" |
| 50 | + end |
59 | 51 | end |
60 | 52 |
|
61 | 53 | test 'does not apply CSP headers to non-HTML responses' do |
62 | | - # Test JSON response |
63 | | - get '/admin.json' |
| 54 | + with_test_routes do |
| 55 | + get '/test/csp/json', params: { format: :json } |
| 56 | + |
| 57 | + assert_response :success |
| 58 | + # JSON responses should not have CSP headers |
| 59 | + assert_nil response.headers['Content-Security-Policy'] |
| 60 | + assert_nil response.headers['Content-Security-Policy-Report-Only'] |
| 61 | + end |
| 62 | + end |
| 63 | + |
| 64 | + test 'middleware handles 304 Not Modified responses correctly' do |
| 65 | + # The middleware has special handling for 304 responses to avoid |
| 66 | + # nonce mismatches with cached content. This test verifies the middleware |
| 67 | + # returns early for 304 responses and does not add CSP headers. |
| 68 | + |
| 69 | + with_test_routes do |
| 70 | + get '/test/csp/304' |
64 | 71 |
|
65 | | - # JSON responses should not have CSP headers |
66 | | - assert_nil response.headers['Content-Security-Policy'] |
67 | | - assert_nil response.headers['Content-Security-Policy-Report-Only'] |
| 72 | + assert_response :not_modified |
| 73 | + # CSP middleware should not add headers to 304 responses |
| 74 | + assert_nil response.headers['Content-Security-Policy'] |
| 75 | + assert_nil response.headers['Content-Security-Policy-Report-Only'] |
| 76 | + end |
68 | 77 | end |
69 | 78 | end |
0 commit comments