diff --git a/spec/components/middleware/anonymous_cache_spec.rb b/spec/components/middleware/anonymous_cache_spec.rb index d76def01d4..2eb18825d9 100644 --- a/spec/components/middleware/anonymous_cache_spec.rb +++ b/spec/components/middleware/anonymous_cache_spec.rb @@ -2,47 +2,102 @@ require "rails_helper" -describe Middleware::AnonymousCache::Helper do +describe Middleware::AnonymousCache do + let(:middleware) { Middleware::AnonymousCache.new(lambda { |_| [200, {}, []] }) } def env(opts = {}) - { - "HTTP_HOST" => "http://test.com", - "REQUEST_URI" => "/path?bla=1", - "REQUEST_METHOD" => "GET", - "rack.input" => "" - }.merge(opts) + Rack::MockRequest.env_for("http://test.com/path?bla=1").merge(opts) end - def new_helper(opts = {}) - Middleware::AnonymousCache::Helper.new(env(opts)) - end - - context "cachable?" do - it "true by default" do - expect(new_helper.cacheable?).to eq(true) + describe Middleware::AnonymousCache::Helper do + def new_helper(opts = {}) + Middleware::AnonymousCache::Helper.new(env(opts)) end - it "is false for non GET" do - expect(new_helper("ANON_CACHE_DURATION" => 10, "REQUEST_METHOD" => "POST").cacheable?).to eq(false) + context "cachable?" do + it "true by default" do + expect(new_helper.cacheable?).to eq(true) + end + + it "is false for non GET" do + expect(new_helper("ANON_CACHE_DURATION" => 10, "REQUEST_METHOD" => "POST").cacheable?).to eq(false) + end + + it "is false if it has an auth cookie" do + expect(new_helper("HTTP_COOKIE" => "jack=1; _t=#{"1" * 32}; jill=2").cacheable?).to eq(false) + end end - it "is false if it has an auth cookie" do - expect(new_helper("HTTP_COOKIE" => "jack=1; _t=#{"1" * 32}; jill=2").cacheable?).to eq(false) + context "per theme cache" do + it "handles theme keys" do + theme = Fabricate(:theme, user_selectable: true) + + with_bad_theme_key = new_helper("HTTP_COOKIE" => "theme_ids=abc").cache_key + with_no_theme_key = new_helper().cache_key + + expect(with_bad_theme_key).to eq(with_no_theme_key) + + with_good_theme_key = new_helper("HTTP_COOKIE" => "theme_ids=#{theme.id}").cache_key + + expect(with_good_theme_key).not_to eq(with_no_theme_key) + end end - end - context "per theme cache" do - it "handles theme keys" do - theme = Fabricate(:theme, user_selectable: true) + context "cached" do + let!(:helper) do + new_helper("ANON_CACHE_DURATION" => 10) + end - with_bad_theme_key = new_helper("HTTP_COOKIE" => "theme_ids=abc").cache_key - with_no_theme_key = new_helper().cache_key + let!(:crawler) do + new_helper("ANON_CACHE_DURATION" => 10, "HTTP_USER_AGENT" => "AdsBot-Google (+http://www.google.com/adsbot.html)") + end - expect(with_bad_theme_key).to eq(with_no_theme_key) + after do + helper.clear_cache + crawler.clear_cache + end - with_good_theme_key = new_helper("HTTP_COOKIE" => "theme_ids=#{theme.id}").cache_key + before do + global_setting :anon_cache_store_threshold, 1 + end - expect(with_good_theme_key).not_to eq(with_no_theme_key) + it "compresses body on demand" do + global_setting :compress_anon_cache, true + + payload = "x" * 1000 + helper.cache([200, { "HELLO" => "WORLD" }, [payload]]) + + helper = new_helper("ANON_CACHE_DURATION" => 10) + expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, [payload]]) + + # depends on i7z implementation, but lets assume it is stable unless we discover + # otherwise + expect(Discourse.redis.get(helper.cache_key_body).length).to eq(16) + end + + it "handles brotli switching" do + helper.cache([200, { "HELLO" => "WORLD" }, ["hello ", "my world"]]) + + helper = new_helper("ANON_CACHE_DURATION" => 10) + expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello my world"]]) + + helper = new_helper("ANON_CACHE_DURATION" => 10, "HTTP_ACCEPT_ENCODING" => "gz, br") + expect(helper.cached).to eq(nil) + end + + it "returns cached data for cached requests" do + helper.is_mobile = true + expect(helper.cached).to eq(nil) + helper.cache([200, { "HELLO" => "WORLD" }, ["hello ", "my world"]]) + + helper = new_helper("ANON_CACHE_DURATION" => 10) + helper.is_mobile = true + expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello my world"]]) + + expect(crawler.cached).to eq(nil) + crawler.cache([200, { "HELLO" => "WORLD" }, ["hello ", "world"]]) + expect(crawler.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello world"]]) + end end end @@ -114,63 +169,6 @@ describe Middleware::AnonymousCache::Helper do end end - context "cached" do - let!(:helper) do - new_helper("ANON_CACHE_DURATION" => 10) - end - - let!(:crawler) do - new_helper("ANON_CACHE_DURATION" => 10, "HTTP_USER_AGENT" => "AdsBot-Google (+http://www.google.com/adsbot.html)") - end - - after do - helper.clear_cache - crawler.clear_cache - end - - before do - global_setting :anon_cache_store_threshold, 1 - end - - it "compresses body on demand" do - global_setting :compress_anon_cache, true - - payload = "x" * 1000 - helper.cache([200, { "HELLO" => "WORLD" }, [payload]]) - - helper = new_helper("ANON_CACHE_DURATION" => 10) - expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, [payload]]) - - # depends on i7z implementation, but lets assume it is stable unless we discover - # otherwise - expect(Discourse.redis.get(helper.cache_key_body).length).to eq(16) - end - - it "handles brotli switching" do - helper.cache([200, { "HELLO" => "WORLD" }, ["hello ", "my world"]]) - - helper = new_helper("ANON_CACHE_DURATION" => 10) - expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello my world"]]) - - helper = new_helper("ANON_CACHE_DURATION" => 10, "HTTP_ACCEPT_ENCODING" => "gz, br") - expect(helper.cached).to eq(nil) - end - - it "returns cached data for cached requests" do - helper.is_mobile = true - expect(helper.cached).to eq(nil) - helper.cache([200, { "HELLO" => "WORLD" }, ["hello ", "my world"]]) - - helper = new_helper("ANON_CACHE_DURATION" => 10) - helper.is_mobile = true - expect(helper.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello my world"]]) - - expect(crawler.cached).to eq(nil) - crawler.cache([200, { "HELLO" => "WORLD" }, ["hello ", "world"]]) - expect(crawler.cached).to eq([200, { "X-Discourse-Cached" => "true", "HELLO" => "WORLD" }, ["hello world"]]) - end - end - context "crawler blocking" do let :non_crawler do { @@ -180,7 +178,6 @@ describe Middleware::AnonymousCache::Helper do end def get(path, options) - middleware = Middleware::AnonymousCache.new(lambda { |_| [200, {}, []] }) @env = env({ "REQUEST_URI" => path, "PATH_INFO" => path,