# frozen_string_literal: true module ResponseCacheStoreTests include HTTPX def test_store_cache request = make_request("GET", "http://store-cache/") response = cached_response(request) cached_response = store.get(request) assert cached_response.headers == response.headers assert cached_response.body == response.body assert store.get(request) request2 = make_request("GET", "http://store-cache/") cached_response2 = store.get(request2) assert cached_response2 assert cached_response2.headers == response.headers assert cached_response2.body == response.body request3 = make_request("POST", "http://store-cache/") assert store.get(request3).nil? request4 = make_request("GET", "http://store-cache/", params: { "foo" => "bar" }) assert store.get(request4).nil? end def test_store_cache_compressed body = "a" * 8012 gzip_body = Zlib.gzip(body) request = make_request("GET", "http://store-gzip/", headers: { "accept-encoding" => "gzip" }) response = cached_response( request, extra_headers: { "content-encoding" => "gzip", "content-length" => gzip_body.size.to_s }, body: gzip_body ) cached_response = store.get(request) assert cached_response.headers == response.headers assert cached_response.body == body assert store.get(request) end def test_store_prepare_maxage request = make_request("GET", "http://prepare-maxage/") response = cached_response(request, extra_headers: { "cache-control" => "max-age=2" }) assert request.response.nil? prepare(request) assert request.response assert request.response.headers == response.headers assert request.response.body == response.body assert request.cached_response.nil? request.instance_variable_set(:@response, nil) sleep(3) prepare(request) assert request.cached_response assert request.cached_response.headers == response.headers assert request.cached_response.body == response.body assert request.response.nil? request2 = make_request("GET", "http://prepare-cache-2.com/") cached_response(request2, extra_headers: { "cache-control" => "no-cache, max-age=2" }) prepare(request2) assert request2.response.nil? end def test_store_prepare_expires request = make_request("GET", "http://prepare-expires/") response = cached_response(request, extra_headers: { "expires" => (Time.now + 5).httpdate }) assert request.response.nil? prepare(request) assert request.response assert request.response.headers == response.headers assert request.response.body == response.body assert request.cached_response.nil? request.instance_variable_set(:@response, nil) sleep(6) prepare(request) assert request.cached_response assert request.cached_response.headers == response.headers assert request.cached_response.body == response.body assert request.response.nil? request2 = make_request("GET", "http://prepare-expires-2/") cached_response(request2, extra_headers: { "cache-control" => "no-cache", "expires" => (Time.now + 2).httpdate }) prepare(request2) assert request2.response.nil? request_invalid_expires = make_request("GET", "http://prepare-expires-3/") _invalid_expires_response = cached_response(request_invalid_expires, extra_headers: { "expires" => "smthsmth" }) prepare(request_invalid_expires) assert request_invalid_expires.response.nil? end def test_store_prepare_invalid_date request_invalid_age = make_request("GET", "http://prepare-expires-4/") response_invalid_age = cached_response(request_invalid_age, extra_headers: { "cache-control" => "max-age=2", "date" => "smthsmth" }) prepare(request_invalid_age) assert request_invalid_age.response assert request_invalid_age.response.headers == response_invalid_age.headers assert request_invalid_age.response.body == response_invalid_age.body end def test_prepare_vary request = make_request("GET", "http://prepare-vary/", headers: { "accept" => "text/plain" }) response = cached_response(request, extra_headers: { "vary" => "Accept" }) request2 = make_request("GET", "http://prepare-vary/", headers: { "accept" => "text/html" }) prepare(request2) assert !request2.headers.key?("if-none-match") assert request2.cached_response.nil? request3 = make_request("GET", "http://prepare-vary/", headers: { "accept" => "text/plain" }) prepare(request3) assert request3.cached_response assert request3.cached_response.headers == response.headers assert request3.cached_response.body == response.body assert request3.headers.key?("if-none-match") request4 = make_request("GET", "http://prepare-vary/", headers: { "accept" => "text/plain", "user-agent" => "Linux Bowser" }) prepare(request4) assert request4.cached_response assert request4.cached_response.headers == response.headers assert request4.cached_response.body == response.body assert request4.headers.key?("if-none-match") end def test_prepare_vary_asterisk request = make_request("GET", "http://prepare-vary-asterisk/", headers: { "accept" => "text/plain" }) response = cached_response(request, extra_headers: { "vary" => "*" }) request2 = make_request("GET", "http://prepare-vary-asterisk/", headers: { "accept" => "text/html" }) prepare(request2) assert request.cached_response.nil? assert !request2.headers.key?("if-none-match") request3 = make_request("GET", "http://prepare-vary-asterisk/", headers: { "accept" => "text/plain" }) prepare(request3) assert request3.cached_response assert request3.cached_response.headers == response.headers assert request3.cached_response.body == response.body assert request3.headers.key?("if-none-match") request4 = make_request("GET", "http://prepare-vary-asterisk/", headers: { "accept" => "text/plain", "accept-language" => "en" }) prepare(request4) assert request4.cached_response.nil? assert !request4.headers.key?("if-none-match") end private def teardown response_cache_session.clear_response_cache end def request_class @request_class ||= response_cache_session_options.request_class end def response_class @response_class ||= response_cache_session_options.response_class end def options_class @options_class ||= response_cache_session_optionsoptions_class end def response_cache_session_options @response_cache_session_options ||= response_cache_session.class.default_options end def response_cache_session @response_cache_session ||= HTTPX.plugin(:response_cache, response_cache_store: init_store) end def make_request(meth, uri, *args) response_cache_session.build_request(meth, uri, *args) end def init_store raise NotImplementedError, "must define a `init_store` method returning the cache store to use" end def store response_cache_session.class.default_options.response_cache_store end def cached_response(request, status: 200, extra_headers: {}, body: "test") response = response_class.new(request, status, "2.0", { "date" => Time.now.httpdate, "etag" => "ETAG" }.merge(extra_headers)) response.body.write(body) store.set(request, response) response end def prepare(request) response_cache_session.send(:prepare_cache, request) end end