summaryrefslogtreecommitdiff
path: root/spec/controllers/concerns/content_security_policy_patch_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers/concerns/content_security_policy_patch_spec.rb')
-rw-r--r--spec/controllers/concerns/content_security_policy_patch_spec.rb116
1 files changed, 116 insertions, 0 deletions
diff --git a/spec/controllers/concerns/content_security_policy_patch_spec.rb b/spec/controllers/concerns/content_security_policy_patch_spec.rb
new file mode 100644
index 00000000000..6322950977c
--- /dev/null
+++ b/spec/controllers/concerns/content_security_policy_patch_spec.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+# Based on https://github.com/rails/rails/pull/45115/files#diff-35ef6d1bd8b8d3b037ec819a704cd78db55db916a57abfc2859882826fc679b6
+RSpec.describe ContentSecurityPolicyPatch, feature_category: :not_owned do
+ include Rack::Test::Methods
+
+ let(:routes) do
+ ActionDispatch::Routing::RouteSet.new.tap do |routes|
+ routes.draw do
+ # Using Testing module defined below
+ scope module: "testing" do
+ get "/", to: "policy#index"
+ end
+ end
+ end
+ end
+
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src -> { :self }
+ p.script_src -> { :https }
+ end
+ end
+
+ let(:policy_middleware) do
+ Module.new do
+ def self.new(app, policy)
+ ->(env) do
+ env["action_dispatch.content_security_policy"] = policy
+
+ app.call(env)
+ end
+ end
+ end
+ end
+
+ subject(:app) do
+ build_app(routes) do |middleware|
+ middleware.use policy_middleware, csp
+ middleware.use ActionDispatch::ContentSecurityPolicy::Middleware
+ end
+ end
+
+ def setup_controller
+ application_controller = Class.new(ActionController::Base) do # rubocop:disable Rails/ApplicationController
+ helper_method :sky_is_blue?
+ def sky_is_blue?
+ true
+ end
+ end
+
+ policy_controller = Class.new(application_controller) do
+ extend ContentSecurityPolicyPatch
+
+ content_security_policy_with_context do |p|
+ p.default_src "https://example.com"
+ p.script_src "https://example.com" if helpers.sky_is_blue?
+ end
+
+ def index
+ head :ok
+ end
+ end
+
+ stub_const("Testing::ApplicationController", application_controller)
+ stub_const("Testing::PolicyController", policy_controller)
+ end
+
+ def build_app(routes)
+ stack = ActionDispatch::MiddlewareStack.new do |middleware|
+ middleware.use ActionDispatch::DebugExceptions
+ middleware.use ActionDispatch::ActionableExceptions
+ middleware.use ActionDispatch::Callbacks
+ middleware.use ActionDispatch::Cookies
+ middleware.use ActionDispatch::Flash
+ middleware.use Rack::MethodOverride
+ middleware.use Rack::Head
+
+ yield(middleware) if block_given?
+ end
+
+ app = stack.build(routes)
+
+ ->(env) { app.call(env) }
+ end
+
+ it "calls helper method" do
+ setup_controller
+
+ response = get "/"
+
+ csp_header = response.headers["Content-Security-Policy"]
+
+ expect(csp_header).to include "default-src https://example.com"
+ expect(csp_header).to include "script-src https://example.com"
+ end
+
+ it "does not emit any warnings" do
+ expect { setup_controller }.not_to output.to_stderr
+ end
+
+ context "with Rails version 7.2" do
+ before do
+ version = Gem::Version.new("7.2.0")
+ allow(Rails).to receive(:gem_version).and_return(version)
+ end
+
+ it "emits a deprecation warning" do
+ expect { setup_controller }
+ .to output(/Use content_security_policy instead/)
+ .to_stderr
+ end
+ end
+end