| Index: content/common/content_security_policy/csp_policy_unittest.cc | 
| diff --git a/content/common/content_security_policy/csp_policy_unittest.cc b/content/common/content_security_policy/csp_policy_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..aadf6df2935031479d59f4369b9b60c00c60e11a | 
| --- /dev/null | 
| +++ b/content/common/content_security_policy/csp_policy_unittest.cc | 
| @@ -0,0 +1,126 @@ | 
| +// Copyright 2017 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "content/common/content_security_policy/csp_context.h" | 
| +#include "content/common/content_security_policy_header.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace content { | 
| + | 
| +namespace { | 
| +class CSPContextTest : public CSPContext { | 
| + public: | 
| +  const std::string& LastConsoleMessage() { return console_message_; } | 
| + | 
| + private: | 
| +  void LogToConsole(const std::string& message) override { | 
| +    console_message_ = message; | 
| +  } | 
| +  std::string console_message_; | 
| +}; | 
| + | 
| +CSPPolicy ParsePolicy(CSPContext* context, const std::string& value) { | 
| +  return CSPPolicy::Parse(context, | 
| +                          ContentSecurityPolicyHeader{ | 
| +                              value, blink::WebContentSecurityPolicyTypeEnforce, | 
| +                              blink::WebContentSecurityPolicySourceHTTP}); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +TEST(CSPPolicy, ReportDuplicateDirective) { | 
| +  { | 
| +    CSPContextTest context; | 
| +    CSPPolicy policy = ParsePolicy(&context, | 
| +                                   "default-src 'self';" | 
| +                                   "default-src 'self'"); | 
| +    const char console_message[] = | 
| +        "Ignoring duplicate Content-Security-Policy directive 'default-src'.\n"; | 
| +    EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +  } | 
| +  { | 
| +    CSPContextTest context; | 
| +    CSPPolicy policy = ParsePolicy(&context, | 
| +                                   "report-uri 'self';" | 
| +                                   "report-uri 'self'"); | 
| +    const char console_message[] = | 
| +        "Ignoring duplicate Content-Security-Policy directive 'report-uri'.\n"; | 
| +    EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +  } | 
| +} | 
| + | 
| +TEST(CSPPolicy, ReportInvalidDirectiveInMeta) { | 
| +  CSPContextTest context; | 
| +  CSPPolicy policy = CSPPolicy::Parse( | 
| +      &context, | 
| +      ContentSecurityPolicyHeader{"frame-ancestors 'self'", | 
| +                                  blink::WebContentSecurityPolicyTypeEnforce, | 
| +                                  blink::WebContentSecurityPolicySourceMeta}); | 
| +  const char console_message[] = | 
| +      "Content Security Policies delivered via a <meta> element may not " | 
| +      "contain the frame-ancestors directive."; | 
| +  EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +} | 
| + | 
| +TEST(CSPPolicy, ReportViolation) { | 
| +  CSPContextTest context; | 
| + | 
| +  CSPPolicy policy = ParsePolicy(&context, "form-action www.example.com"); | 
| +  EXPECT_FALSE(policy.Allow(&context, CSPDirective::FormAction, | 
| +                            GURL("http://www.not-example.com"))); | 
| + | 
| +  const char console_message[] = | 
| +      "Refused to send form data to 'http://www.not-example.com/' because it " | 
| +      "violates the following Content Security Policy directive: \"form-action " | 
| +      "www.example.com\"\n"; | 
| +  EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +} | 
| + | 
| +TEST(CSPPolicy, DirectiveFallback) { | 
| +  { | 
| +    CSPContextTest context; | 
| +    CSPPolicy policy = ParsePolicy(&context, "default-src http://a.com"); | 
| +    EXPECT_FALSE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://b.com"))); | 
| +    const char console_message[] = | 
| +        "Refused to frame 'http://b.com/' because it violates " | 
| +        "the following Content Security Policy directive: \"default-src " | 
| +        "http://a.com\" Note that 'frame-src' was not explicitly " | 
| +        "set, so 'default-src' is used as a fallback.\n"; | 
| +    EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +    EXPECT_TRUE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://a.com"))); | 
| +  } | 
| +  { | 
| +    CSPContextTest context; | 
| +    CSPPolicy policy = ParsePolicy(&context, "child-src http://a.com"); | 
| +    EXPECT_FALSE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://b.com"))); | 
| +    const char console_message[] = | 
| +        "Refused to frame 'http://b.com/' because it violates " | 
| +        "the following Content Security Policy directive: \"child-src " | 
| +        "http://a.com\" Note that 'frame-src' was not explicitly " | 
| +        "set, so 'child-src' is used as a fallback.\n"; | 
| +    EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +    EXPECT_TRUE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://a.com"))); | 
| +  } | 
| +  { | 
| +    CSPContextTest context; | 
| +    CSPPolicy policy = ParsePolicy(&context, | 
| +                                   "frame-src http://a.com;" | 
| +                                   "child-src http://b.com;"); | 
| +    EXPECT_TRUE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://a.com"))); | 
| +    EXPECT_FALSE( | 
| +        policy.Allow(&context, CSPDirective::FrameSrc, GURL("http://b.com"))); | 
| +    const char console_message[] = | 
| +        "Refused to frame 'http://b.com/' because it violates " | 
| +        "the following Content Security Policy directive: \"frame-src " | 
| +        "http://a.com\"\n"; | 
| +    EXPECT_EQ(console_message, context.LastConsoleMessage()); | 
| +  } | 
| +} | 
| + | 
| +}  // namespace content | 
|  |