Fix breakages in https://codereview.chromium.org/1155713003/
[chromium-blink-merge.git] / ios / web / net / clients / crw_csp_network_client_unittest.mm
blob29c51238f393d5bd8492e253ea46ac3c85fc8b1b
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/net/clients/crw_csp_network_client.h"
7 #import <Foundation/Foundation.h>
9 #include "base/mac/scoped_nsobject.h"
10 #import "ios/net/clients/crn_forwarding_network_client.h"
11 #import "ios/web/net/crw_url_verifying_protocol_handler.h"
12 #include "ios/web/public/test/test_web_thread_bundle.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/gtest_mac.h"
16 @interface CRWCspMockClient : CRNForwardingNetworkClient
17 @end
19 @implementation CRWCspMockClient {
20   base::scoped_nsobject<NSURLResponse> _response;
23 - (void)didReceiveResponse:(NSURLResponse*)response {
24   _response.reset([response retain]);
27 - (NSURLResponse*)response {
28   return _response;
31 @end
33 class CRWCspNetworkClientTest : public testing::Test {
34  public:
35   CRWCspNetworkClientTest() {
36     mock_client_.reset([[CRWCspMockClient alloc] init]);
37     csp_client_.reset([[CRWCspNetworkClient alloc] init]);
38     [csp_client_ setUnderlyingClient:mock_client_];
39   }
41   web::TestWebThreadBundle thread_bundle_;
42   base::scoped_nsobject<CRWCspNetworkClient> csp_client_;
43   base::scoped_nsobject<CRWCspMockClient> mock_client_;
46 TEST_F(CRWCspNetworkClientTest, FixCspHeaders) {
47   base::scoped_nsobject<NSDictionary> input_headers([@{
48     @"Foo" : @"Bar",
49     @"coNteNt-seCuRity-POLicy" : @"coNNect-sRc foo.com; script-src 'self'",
50     @"X-WebKit-CSP" : @"frame-src 'self'"
51   } retain]);
53   base::scoped_nsobject<NSHTTPURLResponse> input_response(
54       [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://foo"]
55                                   statusCode:200
56                                  HTTPVersion:@"HTTP/1.1"
57                                 headerFields:input_headers]);
59   [csp_client_ didReceiveResponse:input_response];
60   ASSERT_TRUE(
61       [[mock_client_ response] isKindOfClass:[NSHTTPURLResponse class]]);
62   base::scoped_nsobject<NSDictionary> output_headers(
63       [[static_cast<NSHTTPURLResponse*>([mock_client_ response])
64           allHeaderFields] retain]);
66   // Check that unrelated headers are copied.
67   EXPECT_NSEQ(@"Bar", [output_headers objectForKey:@"Foo"]);
69   base::scoped_nsobject<NSString> csp_header(
70       [[output_headers objectForKey:@"coNteNt-seCuRity-POLicy"] retain]);
72   EXPECT_TRUE(csp_header.get());
74   // frame-src is not created because there were no frame-src and no
75   // default-src.
76   // 'self' and |kURLForVerification| are prepended to the connect-src value.
77   NSString* expected_csp_header = [NSString stringWithFormat:
78       @"coNNect-sRc 'self' %s foo.com; " @"script-src 'self'",
79       web::kURLForVerification];
80   EXPECT_NSEQ(expected_csp_header, csp_header);
82   // X-WebKit-CSP is handled as well.
83   // crwebinvoke: crwebinvokeimmediate: and crwebnull: are prepended to the
84   // existing frame-src value.
85   // connect-src is not created because there were no connect-src and no
86   // default-src.
87   csp_header.reset([[output_headers objectForKey:@"X-WebKit-CSP"] retain]);
88   EXPECT_NSEQ(@"frame-src crwebinvoke: crwebinvokeimmediate: crwebnull: 'self'",
89               csp_header);
92 TEST_F(CRWCspNetworkClientTest, FixCspHeadersWithDefault) {
93   base::scoped_nsobject<NSDictionary> input_headers([@{
94     @"Content-Security-Policy" : @"default-src foo.com; connect-src *"
95   } retain]);
97   base::scoped_nsobject<NSHTTPURLResponse> input_response(
98       [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://foo"]
99                                   statusCode:200
100                                  HTTPVersion:@"HTTP/1.1"
101                                 headerFields:input_headers]);
103   [csp_client_ didReceiveResponse:input_response];
104   ASSERT_TRUE(
105       [[mock_client_ response] isKindOfClass:[NSHTTPURLResponse class]]);
106   base::scoped_nsobject<NSDictionary> output_headers(
107       [[static_cast<NSHTTPURLResponse*>([mock_client_ response])
108           allHeaderFields] retain]);
110   base::scoped_nsobject<NSString> csp_header(
111       [[output_headers objectForKey:@"Content-Security-Policy"] retain]);
113   EXPECT_TRUE(csp_header.get());
115   // crwebinvoke: crwebinvokeimmediate: and crwebnull: are prepended to the
116   // existing default-src value because there was no frame-src.
117   // 'self' and |kURLForVerification| are prepended to the connect-src value.
118   NSString* expected_csp_header = [NSString stringWithFormat:
119       @"default-src crwebinvoke: crwebinvokeimmediate: crwebnull: foo.com; "
120       @"connect-src 'self' %s *", web::kURLForVerification];
121   EXPECT_NSEQ(expected_csp_header, csp_header);
124 TEST_F(CRWCspNetworkClientTest, NonHTTPResponse) {
125   base::scoped_nsobject<NSURLResponse> response([[NSURLResponse alloc] init]);
126   [csp_client_ didReceiveResponse:response];
127   // The client is a pass-through, compare the pointers.
128   EXPECT_EQ(response, [mock_client_ response]);