def test_put_invalid_body(self, get_config, body): """ If the body of a ``PUT`` to ``VoucherCollection`` does not consist of an object with a single *voucher* property then the response is *BAD REQUEST*. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO(body), cooperator=uncooperator(), ) requesting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
def test_put_voucher(self, get_config, voucher): """ When a voucher is ``PUT`` to ``VoucherCollection`` it is passed in to the redemption model object for handling and an ``OK`` response is returned. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO(dumps({u"voucher": voucher})), cooperator=uncooperator(), ) requesting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(ok_response(), ), )
def test_post(self, get_config, voucher, unblinded_tokens): """ When the unblinded token collection receives a **POST**, the unblinded tokens in the request body are inserted into the system and an OK response is generated. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO( dumps({ u"unblinded-tokens": list(token.unblinded_token for token in unblinded_tokens) })), cooperator=uncooperator(), ) requesting = agent.request( b"POST", b"http://127.0.0.1/unblinded-token", bodyProducer=producer, ) self.assertThat( requesting, succeeded(ok_response(headers=application_json()), ), ) stored_tokens = root.controller.store.backup()[u"unblinded-tokens"] self.assertThat( stored_tokens, Equals(list(token.unblinded_token for token in unblinded_tokens)), )
def test_get(self, get_config, voucher, extra_tokens): """ When the unblinded token collection receives a **GET**, the response is the total number of unblinded tokens in the system, the unblinded tokens themselves, and information about tokens spent on recent lease maintenance activity. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) if extra_tokens is None: num_tokens = 0 else: num_tokens = root.controller.num_redemption_groups + extra_tokens # Put in a number of tokens with which to test. redeeming = root.controller.redeem(voucher, num_tokens) # Make sure the operation completed before proceeding. self.assertThat( redeeming, succeeded(Always()), ) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/unblinded-token", ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded_with_unblinded_tokens(num_tokens, num_tokens), )
def test_render_signup_success(self): """ """ self.signup = TrivialSignup() self.mailer = MemoryMailer() self.stripe = PositiveStripe() self.cross_domain = "http://*****:*****@example.invalid") response = self.successResultOf(d) body = self.successResultOf(readBody(response)) self.expectThat(response.code, Equals(OK)) self.expectThat(body, Contains("You subscribed.")) self.expectThat(self.mailer.emails, Equals([])) self.expectThat(self.signup.signups, Equals(1))
def test_unauthorized(self, get_config, path): """ A request for any resource without the required authorization token receives a 401 response. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/" + b"/".join(path), ) responses = [] requesting.addCallback(responses.append) self.assertThat( requesting, succeeded(Always()), ) [response] = responses self.assertThat( response.code, Equals(UNAUTHORIZED), )
def test_render_signup_failure(self): """ No subscription resources are provisioned if the Stripe interaction fails. """ self.signup = TrivialSignup() self.mailer = MemoryMailer() self.stripe = NegativeStripe() self.cross_domain = "http://*****:*****@example.invalid") response = self.successResultOf(d) body = self.successResultOf(readBody(response)) self.expectThat(response.code, Equals(PAYMENT_REQUIRED)) self.expectThat(body, Contains("Stripe error")) self.expectThat(self.mailer.emails, HasLength(1)) self.expectThat(self.signup.signups, Equals(0))
def test_latest_lease_maintenance_spending(self, get_config, size_observations, now): """ The most recently completed record of lease maintenance spending activity is reported in the response to a **GET** request. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, lambda: now) # Put some activity into it. total = 0 activity = root.store.start_lease_maintenance() for sizes in size_observations: total += required_passes(root.store.pass_value, sizes) activity.observe(sizes) activity.finish() agent = RequestTraversalAgent(root) d = agent.request( b"GET", b"http://127.0.0.1/unblinded-token", ) d.addCallback(readBody) d.addCallback( lambda body: loads(body)[u"lease-maintenance-spending"], ) self.assertThat( d, succeeded(Equals({ "when": now.isoformat(), "count": total, })), )
def _cors_test(self, method, uri): site = self.make_site() agent = RequestTraversalAgent(site.resource) d = agent.request(method, uri) response = self.successResultOf(d) self.expectThat( response.headers.getRawHeaders("Access-Control-Allow-Origin"), Equals([self.origin]), )
def test_no_body(self): """ `ForeverBodyResource` returns response headers, but no body. """ agent = RequestTraversalAgent(ForeverBodyResource()) response = self.successResultOf(agent.request(b'GET', b'https://an.example/')) d = readBody(response) self.assertNoResult(d)
def test_no_body(self): """ `ForeverBodyResource` returns response headers, but no body. """ agent = RequestTraversalAgent(ForeverBodyResource()) response = self.successResultOf( agent.request(b"GET", b"https://an.example/")) d = readBody(response) self.assertNoResult(d)
def test_spec_compliance(self): """ Does our output adhere to the `OpenMetrics <https://openmetrics.io/>` spec? https://github.com/OpenObservability/OpenMetrics/ https://prometheus.io/docs/instrumenting/exposition_formats/ """ root = HackItResource() root.putChild(b"", Statistics(FakeStatsProvider())) rta = RequestTraversalAgent(root) d = rta.request(b"GET", b"http://localhost/?t=openmetrics") self.assertThat(d, succeeded(matches_stats(self)))
def _test_get_known_voucher(self, get_config, now, voucher, voucher_matcher): """ Assert that a voucher that is ``PUT`` and then ``GET`` is represented in the JSON response. :param voucher_matcher: A matcher which matches the voucher expected to be returned by the ``GET``. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, lambda: now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO(dumps({u"voucher": voucher})), cooperator=uncooperator(), ) putting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.assertThat( putting, succeeded(ok_response(), ), ) getting = agent.request( b"GET", u"http://127.0.0.1/voucher/{}".format( quote( voucher.encode("utf-8"), safe=b"", ).decode("utf-8"), ).encode("ascii"), ) self.assertThat( getting, succeeded( MatchesAll( ok_response(headers=application_json()), AfterPreprocessing( readBody, succeeded( AfterPreprocessing( Voucher.from_json, voucher_matcher, ), ), ), ), ), )
def test_put_voucher(self, get_config, api_auth_token, voucher): """ When a voucher is ``PUT`` to ``VoucherCollection`` it is passed in to the redemption model object for handling and an ``OK`` response is returned. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) data = BytesIO(dumps({u"voucher": voucher})) requesting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=data, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(ok_response(), ), )
def test_put_invalid_body(self, get_config, api_auth_token, body): """ If the body of a ``PUT`` to ``VoucherCollection`` does not consist of an object with a single *voucher* property then the response is *BAD REQUEST*. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=BytesIO(body), ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
def test_get_invalid_voucher(self, get_config, api_auth_token, not_voucher): """ When a syntactically invalid voucher is requested with a ``GET`` to a child of ``VoucherCollection`` the response is **BAD REQUEST**. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) url = u"http://127.0.0.1/voucher/{}".format( quote( not_voucher.encode("utf-8"), safe=b"", ).decode("utf-8"), ).encode("ascii") requesting = authorized_request( api_auth_token, agent, b"GET", url, ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
def test_error_changes(self): duplicate_resource = POSTableData( sample_create_resource_record_sets_error_result.xml, b"text/xml", BAD_REQUEST, ) zone_id = "1234ABCDEF" agent = RequestTraversalAgent( static_resource({ b"2013-04-01": { b"hostedzone": { zone_id.encode("ascii"): { b"rrset": duplicate_resource, }, }, }, })) aws = AWSServiceRegion(access_key="abc", secret_key="def") client = get_route53_client(agent, aws, uncooperator()) err = self.failureResultOf( client.change_resource_record_sets( zone_id=zone_id, changes=[ create_rrset( sample_create_resource_record_sets_error_result.rrset) ], ), Route53Error) expected = { 'Code': 'InvalidChangeBatch', 'Message': "[Tried to create resource record set [name='duplicate.example.invalid.', type='CNAME'] but it already exists]", 'Type': 'Sender', } self.assertEqual(err.value.errors, [expected])
def test_version(self, get_config, api_auth_token): """ The ZKAPAuthorizer package version is available in a JSON response to a **GET** to ``/version``. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = authorized_request( api_auth_token, agent, b"GET", b"http://127.0.0.1/version", ) self.assertThat( requesting, succeeded( matches_response( code_matcher=Equals(OK), body_matcher=AfterPreprocessing( loads, Equals({"version": zkapauthorizer_version}), ), ), ), )
def __init__(self): base_url = URL.fromText(u"https://kubernetes.example.invalid./") self._state = _KubernetesState() self._resource = _kubernetes_resource(self) self._kubernetes = network_kubernetes( base_url=base_url, agent=RequestTraversalAgent(self._resource), )
def test_get_unknown_voucher(self, get_config, voucher): """ When a voucher is requested with a ``GET`` to a child of ``VoucherCollection`` the response is **NOT FOUND** if the voucher hasn't previously been submitted with a ``PUT``. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", u"http://127.0.0.1/voucher/{}".format(voucher).encode("ascii"), ) self.assertThat( requesting, succeeded(not_found_response(), ), )
def _test_list_vouchers(self, get_config, now, vouchers, match_response_object): # Hypothesis causes our test case instances to be re-used many times # between setUp and tearDown. Avoid re-using the same temporary # directory for every Hypothesis iteration because this test leaves # state behind that invalidates future iterations. tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, lambda: now) agent = RequestTraversalAgent(root) note("{} vouchers".format(len(vouchers))) for voucher in vouchers: producer = FileBodyProducer( BytesIO(dumps({u"voucher": voucher})), cooperator=uncooperator(), ) putting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.assertThat( putting, succeeded(ok_response(), ), ) getting = agent.request( b"GET", b"http://127.0.0.1/voucher", ) self.assertThat( getting, succeeded( MatchesAll( ok_response(headers=application_json()), AfterPreprocessing( json_content, succeeded(match_response_object, ), ), ), ), )
def test_cors_chargebee(self): chargebee_create_subscription = Resource() chargebee_estimates = Resource() chargebee_estimates.putChild( "create_subscription", chargebee_create_subscription, ) chargebee_v2 = Resource() chargebee_v2.putChild( "estimates", chargebee_estimates, ) chargebee_api = Resource() chargebee_api.putChild( "v2", chargebee_v2, ) chargebee_root = Resource() chargebee_root.putChild( "api", chargebee_v2, ) chargebee = ChargeBeeCreateSubscription( RequestTraversalAgent(chargebee_root), "example-test", "foo", "chargebee.com", ) root = Resource() root.putChild("create_subscription", chargebee) agent = RequestTraversalAgent( access_control_allow_origins([self.origin], root), ) d = agent.request( b"POST", b"http://127.0.0.0.1/create_subscription") response = self.successResultOf(d) self.expectThat( response.headers.getRawHeaders("Access-Control-Allow-Origin"), Equals([self.origin]), )
def test_get_position(self, get_config, voucher, extra_tokens, position): """ When the unblinded token collection receives a **GET** with a **position** query argument, it returns all unblinded tokens which sort greater than the position and no others. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) if extra_tokens is None: num_tokens = 0 else: num_tokens = root.controller.num_redemption_groups + extra_tokens # Put in a number of tokens with which to test. redeeming = root.controller.redeem(voucher, num_tokens) # Make sure the operation completed before proceeding. self.assertThat( redeeming, succeeded(Always()), ) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/unblinded-token?position={}".format( quote(position.encode("utf-8"), safe=b""), ), ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded_with_unblinded_tokens_with_matcher( num_tokens, AllMatch( MatchesAll( GreaterThan(position), IsInstance(unicode), ), ), matches_lease_maintenance_spending(), ), )
def test_get_order_matches_use_order(self, get_config, voucher, extra_tokens): """ The first unblinded token returned in a response to a **GET** request is the first token to be used to authorize a storage request. """ def after(d, f): new_d = Deferred() def f_and_continue(result): maybeDeferred(f).chainDeferred(new_d) return result d.addCallback(f_and_continue) return new_d def get_tokens(): d = agent.request( b"GET", b"http://127.0.0.1/unblinded-token", ) d.addCallback(readBody) d.addCallback(lambda body: loads(body)[u"unblinded-tokens"], ) return d def use_a_token(): root.store.extract_unblinded_tokens(1) tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) num_tokens = root.controller.num_redemption_groups + extra_tokens # Put in a number of tokens with which to test. redeeming = root.controller.redeem(voucher, num_tokens) # Make sure the operation completed before proceeding. self.assertThat( redeeming, succeeded(Always()), ) agent = RequestTraversalAgent(root) getting_initial_tokens = get_tokens() using_a_token = after(getting_initial_tokens, use_a_token) getting_tokens_after = after(using_a_token, get_tokens) self.assertThat( gatherResults([getting_initial_tokens, getting_tokens_after]), succeeded( MatchesPredicate( lambda (initial_tokens, tokens_after): initial_tokens[1:] == tokens_after, u"initial, after (%s): initial[1:] != after", ), ), )
def test_version(self, get_config): """ The ZKAPAuthorizer package version is available in a JSON response to a **GET** to ``/version``. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/version", ) requesting.addCallback(readBody) requesting.addCallback(loads) self.assertThat( requesting, succeeded(Equals({"version": zkapauthorizer_version})), )
def _test_get_known_voucher(self, get_config, api_auth_token, now, voucher, voucher_matcher): """ Assert that a voucher that is ``PUT`` and then ``GET`` is represented in the JSON response. :param voucher_matcher: A matcher which matches the voucher expected to be returned by the ``GET``. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, lambda: now) agent = RequestTraversalAgent(root) putting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=BytesIO(dumps({u"voucher": voucher})), ) self.assertThat( putting, succeeded(ok_response(), ), ) getting = authorized_request( api_auth_token, agent, b"GET", u"http://127.0.0.1/voucher/{}".format( quote( voucher.encode("utf-8"), safe=b"", ).decode("utf-8"), ).encode("ascii"), ) self.assertThat( getting, succeeded( MatchesAll( ok_response(headers=application_json()), AfterPreprocessing( readBody, succeeded( AfterPreprocessing( Voucher.from_json, voucher_matcher, ), ), ), ), ), )
def test_get_limit(self, get_config, voucher, extra_tokens, limit): """ When the unblinded token collection receives a **GET** with a **limit** query argument, it returns no more unblinded tokens than indicated by the limit. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) if extra_tokens is None: num_tokens = 0 else: num_tokens = root.controller.num_redemption_groups + extra_tokens # Put in a number of tokens with which to test. redeeming = root.controller.redeem(voucher, num_tokens) # Make sure the operation completed before proceeding. self.assertThat( redeeming, succeeded(Always()), ) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/unblinded-token?limit={}".format(limit), ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded_with_unblinded_tokens( num_tokens, min(num_tokens, limit), ), )
def test_calculated_price(self, encoding_params_and_get_config, api_auth_token, sizes): """ A well-formed request returns the price in ZKAPs as an integer and the storage period (the minimum allowed) that they pay for. """ encoding_params, get_config = encoding_params_and_get_config shares_needed, shares_happy, shares_total = encoding_params config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) expected_price = PriceCalculator( shares_needed=shares_needed, shares_total=shares_total, pass_value=get_configured_pass_value(config), ).calculate(sizes) self.assertThat( authorized_request( api_auth_token, agent, b"POST", self.url, headers={b"content-type": [b"application/json"]}, data=BytesIO(dumps({ u"version": 1, u"sizes": sizes })), ), succeeded( matches_response( code_matcher=Equals(OK), headers_matcher=application_json(), body_matcher=AfterPreprocessing( loads, Equals({ u"price": expected_price, u"period": get_configured_lease_duration(config), }), ), ), ), )
def _test_list_vouchers(self, get_config, api_auth_token, now, vouchers, match_response_object): config = get_config_with_api_token( # Hypothesis causes our test case instances to be re-used many # times between setUp and tearDown. Avoid re-using the same # temporary directory for every Hypothesis iteration because this # test leaves state behind that invalidates future iterations. self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, lambda: now) agent = RequestTraversalAgent(root) note("{} vouchers".format(len(vouchers))) for voucher in vouchers: data = BytesIO(dumps({u"voucher": voucher})) putting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=data, ) self.assertThat( putting, succeeded(ok_response(), ), ) getting = authorized_request( api_auth_token, agent, b"GET", b"http://127.0.0.1/voucher", ) self.assertThat( getting, succeeded( MatchesAll( ok_response(headers=application_json()), AfterPreprocessing( json_content, succeeded(match_response_object, ), ), ), ), )
def _client_for_rrsets(self, zone_id, rrsets_xml): agent = RequestTraversalAgent( static_resource({ b"2013-04-01": { b"hostedzone": { zone_id: { b"rrset": Data( rrsets_xml, b"text/xml", ) } } } })) aws = AWSServiceRegion(access_key="abc", secret_key="def") return get_route53_client(agent, aws, uncooperator())
def test_some_zones(self): agent = RequestTraversalAgent( static_resource({ b"2013-04-01": { b"hostedzone": Data( sample_list_hosted_zones_result.xml, b"text/xml", ), }, })) aws = AWSServiceRegion(access_key="abc", secret_key="def") client = get_route53_client(agent, aws, uncooperator()) zones = self.successResultOf(client.list_hosted_zones()) expected = [HostedZone(**sample_list_hosted_zones_result.details)] self.assertEquals(expected, zones)
def create_tahoe_treq_client(root=None): """ :param root: an instance created via `create_fake_tahoe_root`. The caller might want a copy of this to call `.add_data` for example. :returns: an instance of treq.client.HTTPClient wired up to in-memory fakes of the Tahoe WebUI. Only a subset of the real WebUI is available. """ if root is None: root = create_fake_tahoe_root() client = HTTPClient( agent=RequestTraversalAgent(root), data_to_body_producer=_SynchronousProducer, ) return client
def create_testing_http_client(reactor, config, global_service, get_api_token): """ :param global_service: an object providing the API of the global magic-folder service :param callable get_api_token: a no-argument callable that returns the current API token. :returns: a Treq HTTPClient which will do all requests to in-memory objects. These objects obtain their data from the service provided """ v1_resource = APIv1(config, global_service) root = magic_folder_resource(get_api_token, v1_resource) client = HTTPClient( agent=RequestTraversalAgent(root), data_to_body_producer=_SynchronousProducer, ) return client
def setUp(self): self.dir = FilePath(self.mktemp()) self.dir.makedirs() self.static = Static() self.static._dir = self.dir self.agent = RequestTraversalAgent(self.static)
class StaticTests(SynchronousTestCase): """ Test `yarrharr.application.Static`. These tests all do HEAD requests because: 1. ``twisted.web.static.File`` uses an ``IPullProducer`` internally. 2. ``HTTPChannel`` (used internally by server.Site, used internally by ``treq.testing.RequestTraversalAgent``, used internally by StubTreq) tries to adapt to a push producer using ``_PullToPush``. 3. ``twisted.internet._producer_helpers._PullToPush`` uses the global cooperator. 4. The global cooperator users the global reactor to schedule work, which is never started under the Django test runner. At least, that's what I *think* is going on. There is other stuff touching the global reactor too. See treq #225 and #226. It's an ugly hack, but we rely on the Content-Length header to tell if the right file is being served. """ def setUp(self): self.dir = FilePath(self.mktemp()) self.dir.makedirs() self.static = Static() self.static._dir = self.dir self.agent = RequestTraversalAgent(self.static) def assertResponse(self, d, *, code=200, content_type='', content_encoding='', content_length='0'): response = self.successResultOf(d) self.assertEqual(200, response.code) self.assertEqual([content_length], response.headers.getRawHeaders('content-length')) self.assertEqual(['public, max-age=31536000, immutable'], response.headers.getRawHeaders('cache-control')) self.assertEqual([content_type], response.headers.getRawHeaders('content-type', [''])) self.assertEqual([content_encoding], response.headers.getRawHeaders('content-encoding', [''])) self.assertEqual(['accept-encoding'], response.headers.getRawHeaders('vary')) def test_serve_js(self): """ JS is served as application/javascript, immutable. """ self.dir.child('foo-xxyy.js').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/foo-xxyy.js'), content_type='application/javascript', ) def test_serve_css(self): """ CSS is served as text/css, immutable. """ self.dir.child('bar-zz99.css').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/bar-zz99.css'), content_type='text/css', ) def test_serve_map(self): """ Source map files are served as application/octet-stream, immutable. """ self.dir.child('bar-zz99.css.map').touch() self.dir.child('foo-xxyy.js.map').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/foo-xxyy.js.map'), content_type='application/octet-stream', ) self.assertResponse( self.agent.request(b'HEAD', b'http://x/bar-zz99.css.map'), content_type='application/octet-stream', ) def test_serve_png(self): """ PNG images are served as image/png, immutable. """ self.dir.child('img-barq.png').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/img-barq.png'), content_type='image/png', ) def test_serve_svg(self): """ PNG images are served as image/svg+xml, immutable. """ self.dir.child('img-blif.svg').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/img-blif.svg'), content_type='image/svg+xml', ) def test_serve_ico(self): """ ICO images are served as image/x-icon, immutable. """ self.dir.child('img-bizf.ico').touch() self.assertResponse( self.agent.request(b'HEAD', b'http://x/img-bizf.ico'), content_type='image/x-icon', ) def test_accept_gzip(self): """ A client which only accepts gzip gets gzip. """ self.dir.child('a-bcd.js').setContent(b'1') self.dir.child('a-bcd.js.br').setContent(b'12') self.dir.child('a-bcd.js.gz').setContent(b'123') self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['gzip'], })), content_length='3', content_type='application/javascript', content_encoding='gzip', ) self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['x-gzip, deflate'], })), content_length='3', content_type='application/javascript', content_encoding='gzip', ) self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['deflate,gzip'], })), content_length='3', content_type='application/javascript', content_encoding='gzip', ) def test_accept_brotli(self): """ A client which accepts Brotli (br) gets it in preference to gzip. """ self.dir.child('a-bcd.js').setContent(b'1') self.dir.child('a-bcd.js.br').setContent(b'12') self.dir.child('a-bcd.js.gz').setContent(b'123') self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['br'], })), content_length='2', content_type='application/javascript', content_encoding='br', ) self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['gzip,br'], })), content_length='2', content_type='application/javascript', content_encoding='br', ) self.assertResponse( self.agent.request(b'HEAD', b'http://x/a-bcd.js', headers=Headers({ 'accept-encoding': ['br, deflate'], })), content_length='2', content_type='application/javascript', content_encoding='br', )
def test_no_response(self): agent = RequestTraversalAgent(BlackHoleResource()) d = agent.request(b'GET', b'http://an.example/') self.assertNoResult(d)