1 // Copyright 2019 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.
4
5 #include <memory>
6 #include <utility>
7
8 #include "base/strings/stringprintf.h"
9 #include "base/test/values_test_util.h"
10 #include "components/version_info/version_info.h"
11 #include "extensions/common/features/feature_channel.h"
12 #include "extensions/common/manifest_constants.h"
13 #include "extensions/common/manifest_handlers/replacement_apps.h"
14 #include "extensions/common/manifest_test.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace extensions {
18
19 namespace {
20
21 class ReplacementAppsManifestTest : public ManifestTest {
22 public:
ReplacementAppsManifestTest()23 ReplacementAppsManifestTest() : channel_(version_info::Channel::UNKNOWN) {}
24
25 protected:
CreateManifest(const char * replacement_web_app,const char * replacement_android_app)26 ManifestData CreateManifest(const char* replacement_web_app,
27 const char* replacement_android_app) {
28 if (replacement_web_app != nullptr && replacement_android_app != nullptr) {
29 // both replacement apps are specified
30 constexpr char kManifest[] =
31 R"({
32 "name": "test",
33 "version": "1",
34 "manifest_version": 2,
35 "app": {
36 "background": {
37 "scripts": ["background.js"]
38 }
39 },
40 "replacement_web_app": %s,
41 "replacement_android_app": %s
42 })";
43 base::Value manifest = base::test::ParseJson(base::StringPrintf(
44 kManifest, replacement_web_app, replacement_android_app));
45 return ManifestData(std::move(manifest), "test");
46 } else if (replacement_web_app != nullptr) {
47 // only web replacement app specified
48 constexpr char kManifest[] =
49 R"({
50 "name": "test",
51 "version": "1",
52 "manifest_version": 2,
53 "replacement_web_app": %s
54 })";
55 base::Value manifest = base::test::ParseJson(
56 base::StringPrintf(kManifest, replacement_web_app));
57 return ManifestData(std::move(manifest), "test");
58 } else if (replacement_android_app != nullptr) {
59 // only Android replacement app specified
60 constexpr char kManifest[] =
61 R"({
62 "name": "test",
63 "version": "1",
64 "manifest_version": 2,
65 "app": {
66 "background": {
67 "scripts": ["background.js"]
68 }
69 },
70 "replacement_android_app": %s
71 })";
72 base::Value manifest = base::test::ParseJson(
73 base::StringPrintf(kManifest, replacement_android_app));
74 return ManifestData(std::move(manifest), "test");
75 }
76
77 base::Value manifest = base::test::ParseJson(
78 R"({
79 "name": "test",
80 "version": "1",
81 "manifest_version": 2
82 })");
83 return ManifestData(std::move(manifest), "test");
84 }
85
86 private:
87 ScopedCurrentChannel channel_;
88 };
89
90 } // namespace
91
TEST_F(ReplacementAppsManifestTest,InvalidAndroidAppType)92 TEST_F(ReplacementAppsManifestTest, InvalidAndroidAppType) {
93 LoadAndExpectError(CreateManifest(nullptr, "123"),
94 manifest_errors::kInvalidReplacementAndroidApp);
95 LoadAndExpectError(CreateManifest(nullptr, "true"),
96 manifest_errors::kInvalidReplacementAndroidApp);
97 LoadAndExpectError(CreateManifest(nullptr, "{}"),
98 manifest_errors::kInvalidReplacementAndroidApp);
99 LoadAndExpectError(CreateManifest(nullptr, R"({"foo": false})"),
100 manifest_errors::kInvalidReplacementAndroidApp);
101 LoadAndExpectError(CreateManifest(nullptr, R"(["com.company.app"])"),
102 manifest_errors::kInvalidReplacementAndroidApp);
103 }
104
TEST_F(ReplacementAppsManifestTest,InvalidWebAppType)105 TEST_F(ReplacementAppsManifestTest, InvalidWebAppType) {
106 LoadAndExpectError(CreateManifest("32", nullptr),
107 manifest_errors::kInvalidReplacementWebApp);
108 LoadAndExpectError(CreateManifest("true", nullptr),
109 manifest_errors::kInvalidReplacementWebApp);
110 LoadAndExpectError(CreateManifest(R"("not_a_valid_url")", nullptr),
111 manifest_errors::kInvalidReplacementWebApp);
112 LoadAndExpectError(CreateManifest("{}", nullptr),
113 manifest_errors::kInvalidReplacementWebApp);
114 LoadAndExpectError(CreateManifest(R"({"foo": false})", nullptr),
115 manifest_errors::kInvalidReplacementWebApp);
116 LoadAndExpectError(CreateManifest(R"("http://not_secure.com")", nullptr),
117 manifest_errors::kInvalidReplacementWebApp);
118 LoadAndExpectError(CreateManifest(R"(["https://secure.com"])", nullptr),
119 manifest_errors::kInvalidReplacementWebApp);
120 LoadAndExpectError(
121 CreateManifest(R"(["https://www.google.com", "not_a_valid_url"])",
122 nullptr),
123 manifest_errors::kInvalidReplacementWebApp);
124 }
125
TEST_F(ReplacementAppsManifestTest,VerifyParse)126 TEST_F(ReplacementAppsManifestTest, VerifyParse) {
127 scoped_refptr<Extension> good = LoadAndExpectSuccess(
128 CreateManifest(R"("https://www.google.com")", R"("com.company.app")"));
129 EXPECT_TRUE(ReplacementAppsInfo::HasReplacementWebApp(good.get()));
130 EXPECT_EQ(ReplacementAppsInfo::GetReplacementWebApp(good.get()),
131 GURL("https://www.google.com"));
132 EXPECT_TRUE(ReplacementAppsInfo::HasReplacementAndroidApp(good.get()));
133 EXPECT_EQ(ReplacementAppsInfo::GetReplacementAndroidApp(good.get()),
134 "com.company.app");
135 }
136
137 } // namespace extensions
138