| Index: components/arc/intent_helper/intent_filter_unittest.cc
|
| diff --git a/components/arc/intent_helper/intent_filter_unittest.cc b/components/arc/intent_helper/intent_filter_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f3528cf5decc914987b0027cc0a8ecbabf5c27f8
|
| --- /dev/null
|
| +++ b/components/arc/intent_helper/intent_filter_unittest.cc
|
| @@ -0,0 +1,321 @@
|
| +// Copyright 2016 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 <memory>
|
| +#include <string>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "components/arc/common/intent_helper.mojom.h"
|
| +#include "components/arc/intent_helper/intent_filter.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace arc {
|
| +
|
| +namespace {
|
| +
|
| +class IntentFilterBuilder {
|
| + public:
|
| + IntentFilterBuilder():
|
| + filter_spec_(mojom::IntentFilter::New()) {
|
| + }
|
| +
|
| + IntentFilterBuilder& authority(const std::string& host) {
|
| + return authority(host, -1);
|
| + }
|
| +
|
| + IntentFilterBuilder& authority(const std::string& host, int port) {
|
| + mojom::AuthorityEntryPtr ae = mojom::AuthorityEntry::New();
|
| + ae->host = host;
|
| + ae->port = port;
|
| + filter_spec_->data_authorities.push_back(std::move(ae));
|
| + return *this;
|
| + }
|
| +
|
| + IntentFilterBuilder& path(const std::string& path,
|
| + const mojom::PatternType& type) {
|
| + mojom::PatternMatcherPtr p = mojom::PatternMatcher::New();
|
| + p->pattern = path;
|
| + p->type = type;
|
| + filter_spec_->data_paths.push_back(std::move(p));
|
| + return *this;
|
| + }
|
| +
|
| + operator IntentFilter() const {
|
| + return std::move(IntentFilter(filter_spec_));
|
| + }
|
| +
|
| + private:
|
| + mojom::IntentFilterPtr filter_spec_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_empty) {
|
| + // Empty URL shouldn't match a filter with an authority.
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("authority1");
|
| +
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| +
|
| + // Empty URL shouldn't match a filter with an authority and port.
|
| + IntentFilter filter_port_100 = IntentFilterBuilder()
|
| + .authority("authority1", 100);
|
| +
|
| + EXPECT_FALSE(filter_port_100.match(GURL()));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_simple) {
|
| + // URL authority should match the filter authority.
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("authority1");
|
| +
|
| + EXPECT_FALSE(filter.match(GURL("http://authority2")));
|
| + EXPECT_FALSE(filter.match(GURL("https://authority2")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://authority1")));
|
| + EXPECT_TRUE(filter.match(GURL("https://authority1")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_no_port) {
|
| + // A filter with no port should accept matching authority URLs with any port.
|
| + IntentFilter filter_no_port = IntentFilterBuilder()
|
| + .authority("authority1");
|
| +
|
| + EXPECT_TRUE(filter_no_port.match(GURL("http://authority1:0")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("https://authority1:0")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("http://authority1:22")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("https://authority1:22")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("http://authority1:1024")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("https://authority1:1024")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("http://authority1:65535")));
|
| + EXPECT_TRUE(filter_no_port.match(GURL("https://authority1:65535")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_with_port) {
|
| + // A filter with a specified port should only match URLs with that port.
|
| + IntentFilter filter_port_100 = IntentFilterBuilder()
|
| + .authority("authority1", 100);
|
| +
|
| + EXPECT_FALSE(filter_port_100.match(GURL("http://authority1")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("https://authority1")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("http://authority1:0")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("https://authority1:0")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("http://authority1:22")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("https://authority1:22")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("http://authority1:1024")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("https://authority1:1024")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("http://authority1:65535")));
|
| + EXPECT_FALSE(filter_port_100.match(GURL("https://authority1:65535")));
|
| +
|
| + EXPECT_TRUE(filter_port_100.match(GURL("http://authority1:100")));
|
| + EXPECT_TRUE(filter_port_100.match(GURL("https://authority1:100")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_multiple) {
|
| + // A filter with multiple authorities should match URLs that match any of
|
| + // those authorities.
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("authority1", 100)
|
| + .authority("authority2");
|
| +
|
| + EXPECT_FALSE(filter.match(GURL("http://authority1")));
|
| + EXPECT_FALSE(filter.match(GURL("http://authority3")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://authority1:100")));
|
| + EXPECT_TRUE(filter.match(GURL("http://authority2")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_substring) {
|
| + // Make sure substrings don't match in non-wildcard cases.
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("authority1");
|
| +
|
| + EXPECT_FALSE(filter.match(GURL("http://authority")));
|
| + EXPECT_FALSE(filter.match(GURL("http://authority12")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestAuthorityEntry_wild) {
|
| + // Make sure wildcards work
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("*.authority1");
|
| +
|
| + EXPECT_FALSE(filter.match(GURL("http://.authority")));
|
| + EXPECT_FALSE(filter.match(GURL("http://.authority12")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://.authority1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://foo.authority1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://bar.authority1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://foo.bar.authority1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://foo.authority1.authority1")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestDataPath_literal) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/path1", mojom::PatternType::PATTERN_LITERAL);
|
| +
|
| + // Empty paths, prefix-, and substring-matches should fail.
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/path")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/path12")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1")));
|
| +}
|
| +
|
| +TEST(IntentFilterTest, TestDataPath_prefix) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/path1", mojom::PatternType::PATTERN_PREFIX);
|
| +
|
| + // Empty paths and substring-matches should fail.
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/path")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path12")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globSuffix) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/path1.*", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + // Empty paths and substring-matches should fail.
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/path")));
|
| +
|
| + // Glob should match any substring including the empty susbstring.
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path11")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path112345")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1.")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1.....")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/path1path")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globInfix) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/a.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + // Empty paths and substring-matches should fail.
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a")));
|
| +
|
| + // Extra junk on the end should fail.
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/abc")));
|
| +
|
| + // Glob should match any substring including the empty susbstring.
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/ab")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a1b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a12345b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a.b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a.....b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/aab")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/aaaaab")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a/foo/b")));
|
| +
|
| + // TODO(kenobi): These cases don't work correctly. However, the chrome-side
|
| + // intent filter matching code needs to replicate the results of the
|
| + // android-side pattern matcher, otherwise chrome will attempt to send URLs to
|
| + // android that won't successfully match with any installed app. See
|
| + // b/30160040.
|
| + // EXPECT_TRUE(filter.match(GURL("http://host.com/abb")));
|
| + // EXPECT_TRUE(filter.match(GURL("http://host.com/abbbbb")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globOnly) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/.*", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + // Empty URLs should fail.
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| +
|
| + // Any path should match.
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/aaa")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/aaa/bbb")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/.")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globSingleChar) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/a1*b", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a12b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/ab12b")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/ab")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a1b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a111b")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globEscapedChar) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/a\\.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a1b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a111b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/abc")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a.bc")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a...bc")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/ab")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a.b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a...b")));
|
| +}
|
| +
|
| +// Glob tests based loosely on android's CTS IntentFilterTest#testPaths.
|
| +TEST(IntentFilterTest, TestDataPath_globEscapedStar) {
|
| + IntentFilter filter = IntentFilterBuilder()
|
| + .authority("host.com")
|
| + .path("/a.\\*b", mojom::PatternType::PATTERN_SIMPLE_GLOB);
|
| +
|
| + EXPECT_FALSE(filter.match(GURL()));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/ab")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a.b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a*b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a1b")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a.*bc")));
|
| + EXPECT_FALSE(filter.match(GURL("http://host.com/a1*bc")));
|
| +
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a.*b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a1*b")));
|
| + EXPECT_TRUE(filter.match(GURL("http://host.com/a2*b")));
|
| +}
|
| +
|
| +} // namespace arc
|
|
|