Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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 "components/doodle/doodle_types.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 #include <string> | |
| 9 | |
| 10 #include "base/json/json_reader.h" | |
| 11 #include "base/optional.h" | |
| 12 #include "base/values.h" | |
| 13 #include "testing/gmock/include/gmock/gmock.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 #include "url/gurl.h" | |
| 16 | |
| 17 using testing::Eq; | |
| 18 | |
| 19 namespace doodle { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 // Parses the given |json| string into a base::DictionaryValue and creates a | |
| 24 // DoodleImage out of that. |json| must be a valid json string. | |
| 25 base::Optional<DoodleImage> DoodleImageFromJson( | |
| 26 const std::string& json, | |
| 27 const base::Optional<GURL>& base_url) { | |
| 28 std::unique_ptr<base::DictionaryValue> value = | |
| 29 base::DictionaryValue::From(base::JSONReader::Read(json)); | |
| 30 DCHECK(value); | |
| 31 return DoodleImage::FromDictionary(*value, base_url); | |
| 32 } | |
| 33 | |
| 34 // Parses the given |json| string into a base::DictionaryValue and creates a | |
| 35 // DoodleConfig out of that. |json| must be a valid json string. | |
| 36 base::Optional<DoodleConfig> DoodleConfigFromJson( | |
| 37 const std::string& json, | |
| 38 const base::Optional<GURL>& base_url) { | |
| 39 std::unique_ptr<base::DictionaryValue> value = | |
| 40 base::DictionaryValue::From(base::JSONReader::Read(json)); | |
| 41 DCHECK(value); | |
| 42 return DoodleConfig::FromDictionary(*value, base_url); | |
| 43 } | |
| 44 | |
| 45 } // namespace | |
| 46 | |
| 47 TEST(DoodleImageTest, ParsesMinimalImage) { | |
| 48 std::string json = R"json({ | |
| 49 "url":"https://www.doodle.com/doodle" | |
| 50 })json"; | |
| 51 base::Optional<DoodleImage> image = DoodleImageFromJson(json, base::nullopt); | |
| 52 ASSERT_TRUE(image.has_value()); | |
| 53 EXPECT_THAT(image->url, Eq(GURL("https://www.doodle.com/doodle"))); | |
| 54 EXPECT_THAT(image->height, Eq(0)); | |
| 55 EXPECT_THAT(image->width, Eq(0)); | |
| 56 EXPECT_THAT(image->is_animated_gif, Eq(false)); | |
| 57 EXPECT_THAT(image->is_cta, Eq(false)); | |
| 58 } | |
| 59 | |
| 60 TEST(DoodleImageTest, ParsesFullImage) { | |
| 61 std::string json = R"json({ | |
| 62 "url":"https://www.doodle.com/doodle", | |
| 63 "height":100, | |
| 64 "width":50, | |
| 65 "is_animated_gif":true, | |
| 66 "is_cta":true | |
| 67 })json"; | |
| 68 base::Optional<DoodleImage> image = DoodleImageFromJson(json, base::nullopt); | |
| 69 ASSERT_TRUE(image.has_value()); | |
| 70 EXPECT_THAT(image->url, Eq(GURL("https://www.doodle.com/doodle"))); | |
| 71 EXPECT_THAT(image->height, Eq(100)); | |
| 72 EXPECT_THAT(image->width, Eq(50)); | |
| 73 EXPECT_THAT(image->is_animated_gif, Eq(true)); | |
| 74 EXPECT_THAT(image->is_cta, Eq(true)); | |
| 75 } | |
| 76 | |
| 77 TEST(DoodleImageTest, ResolvesRelativeUrl) { | |
| 78 std::string json = R"json({ | |
| 79 "url":"/the_doodle_path" | |
| 80 })json"; | |
| 81 base::Optional<DoodleImage> image = | |
| 82 DoodleImageFromJson(json, GURL("https://doodle.dood/")); | |
| 83 ASSERT_TRUE(image.has_value()); | |
| 84 EXPECT_THAT(image->url, Eq(GURL("https://doodle.dood/the_doodle_path"))); | |
| 85 } | |
| 86 | |
| 87 TEST(DoodleImageTest, DoesNotResolveAbsoluteUrl) { | |
| 88 std::string json = R"json({ | |
| 89 "url":"https://www.doodle.com/the_doodle_path" | |
| 90 })json"; | |
| 91 base::Optional<DoodleImage> image = | |
| 92 DoodleImageFromJson(json, GURL("https://other.com/")); | |
| 93 ASSERT_TRUE(image.has_value()); | |
| 94 EXPECT_THAT(image->url, Eq(GURL("https://www.doodle.com/the_doodle_path"))); | |
| 95 } | |
| 96 | |
| 97 TEST(DoodleImageTest, RequiresUrl) { | |
| 98 std::string json = R"json({ | |
| 99 "height":100, | |
| 100 "width":50, | |
| 101 "is_animated_gif":true, | |
| 102 "is_cta":true | |
| 103 })json"; | |
| 104 base::Optional<DoodleImage> image = DoodleImageFromJson(json, base::nullopt); | |
| 105 EXPECT_FALSE(image.has_value()); | |
| 106 } | |
| 107 | |
| 108 TEST(DoodleImageTest, PreservesFieldsOverRoundtrip) { | |
| 109 // Set all fields to non-default values. | |
| 110 DoodleImage image(GURL("https://www.doodle.com/doodle")); | |
| 111 image.height = 100; | |
| 112 image.width = 50; | |
| 113 image.is_animated_gif = true; | |
| 114 image.is_cta = true; | |
| 115 | |
| 116 // Convert to a dictionary and back. | |
| 117 base::Optional<DoodleImage> after_roundtrip = | |
| 118 DoodleImage::FromDictionary(*image.ToDictionary(), base::nullopt); | |
| 119 | |
| 120 // Make sure everything survived. | |
| 121 ASSERT_TRUE(after_roundtrip.has_value()); | |
| 122 EXPECT_THAT(*after_roundtrip, Eq(image)); | |
| 123 } | |
| 124 | |
| 125 TEST(DoodleConfigTest, ParsesMinimalConfig) { | |
| 126 std::string json = R"json({ | |
| 127 "large_image":{"url":"https://doodle.com/img.jpg"} | |
| 128 })json"; | |
| 129 base::Optional<DoodleConfig> config = | |
| 130 DoodleConfigFromJson(json, base::nullopt); | |
| 131 ASSERT_TRUE(config.has_value()); | |
| 132 EXPECT_THAT(config->doodle_type, Eq(DoodleType::UNKNOWN)); | |
| 133 EXPECT_THAT(config->alt_text, Eq(std::string())); | |
| 134 EXPECT_THAT(config->interactive_html, Eq(std::string())); | |
| 135 EXPECT_THAT(config->search_url, Eq(GURL())); | |
| 136 EXPECT_THAT(config->target_url, Eq(GURL())); | |
| 137 EXPECT_THAT(config->fullpage_interactive_url, Eq(GURL())); | |
| 138 EXPECT_FALSE(config->large_cta_image.has_value()); | |
| 139 EXPECT_FALSE(config->transparent_large_image.has_value()); | |
| 140 } | |
| 141 | |
| 142 TEST(DoodleConfigTest, ParsesFullConfig) { | |
| 143 std::string json = R"json({ | |
| 144 "doodle_type":"SLIDESHOW", | |
| 145 "alt_text":"some text", | |
| 146 "interactive_html":"<div id='dood'></div>", | |
| 147 "search_url":"https://doodle.com/search", | |
| 148 "target_url":"https://doodle.com/target", | |
| 149 "fullpage_interactive_url":"https://doodle.com/interactive", | |
| 150 "large_image":{"url":"https://doodle.com/img.jpg"}, | |
| 151 "large_cta_image":{"url":"https://doodle.com/cta.jpg"}, | |
| 152 "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"} | |
| 153 })json"; | |
| 154 base::Optional<DoodleConfig> config = | |
| 155 DoodleConfigFromJson(json, base::nullopt); | |
| 156 ASSERT_TRUE(config.has_value()); | |
| 157 EXPECT_THAT(config->doodle_type, Eq(DoodleType::SLIDESHOW)); | |
| 158 EXPECT_THAT(config->alt_text, Eq("some text")); | |
| 159 EXPECT_THAT(config->interactive_html, Eq("<div id='dood'></div>")); | |
| 160 EXPECT_THAT(config->search_url, Eq(GURL("https://doodle.com/search"))); | |
| 161 EXPECT_THAT(config->target_url, Eq(GURL("https://doodle.com/target"))); | |
| 162 EXPECT_THAT(config->fullpage_interactive_url, | |
| 163 Eq(GURL("https://doodle.com/interactive"))); | |
| 164 EXPECT_THAT(config->large_image.url, Eq(GURL("https://doodle.com/img.jpg"))); | |
| 165 ASSERT_TRUE(config->large_cta_image.has_value()); | |
| 166 EXPECT_THAT(config->large_cta_image->url, | |
| 167 Eq(GURL("https://doodle.com/cta.jpg"))); | |
| 168 ASSERT_TRUE(config->transparent_large_image.has_value()); | |
| 169 EXPECT_THAT(config->transparent_large_image->url, | |
| 170 Eq(GURL("https://doodle.com/transparent.jpg"))); | |
| 171 } | |
| 172 | |
| 173 TEST(DoodleConfigTest, RequiresLargeImage) { | |
| 174 std::string json = R"json({ | |
| 175 "doodle_type":"SLIDESHOW", | |
| 176 "alt_text":"some text", | |
| 177 "interactive_html":"<div id='dood'></div>", | |
| 178 "search_url":"https://doodle.com/search", | |
| 179 "target_url":"https://doodle.com/target", | |
| 180 "fullpage_interactive_url":"https://doodle.com/interactive", | |
| 181 "large_cta_image":{"url":"https://doodle.com/cta.jpg"}, | |
| 182 "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"} | |
| 183 })json"; | |
| 184 base::Optional<DoodleConfig> config = | |
| 185 DoodleConfigFromJson(json, base::nullopt); | |
| 186 EXPECT_FALSE(config.has_value()); | |
| 187 } | |
| 188 | |
| 189 TEST(DoodleConfigTest, RequiresValidLargeImage) { | |
| 190 std::string json = R"json({ | |
| 191 "doodle_type":"SLIDESHOW", | |
| 192 "alt_text":"some text", | |
| 193 "interactive_html":"<div id='dood'></div>", | |
| 194 "search_url":"https://doodle.com/search", | |
| 195 "target_url":"https://doodle.com/target", | |
| 196 "fullpage_interactive_url":"https://doodle.com/interactive", | |
| 197 "large_image":{"no_url":"asdf"}, | |
| 198 "large_cta_image":{"url":"https://doodle.com/cta.jpg"}, | |
| 199 "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"} | |
| 200 })json"; | |
| 201 base::Optional<DoodleConfig> config = | |
| 202 DoodleConfigFromJson(json, base::nullopt); | |
| 203 EXPECT_FALSE(config.has_value()); | |
| 204 } | |
| 205 | |
| 206 TEST(DoodleConfigTest, ResolvesRelativeUrls) { | |
| 207 std::string json = R"json({ | |
| 208 "search_url":"/search", | |
| 209 "target_url":"/target", | |
| 210 "fullpage_interactive_url":"/interactive", | |
| 211 "large_image":{"url":"/large.jpg"}, | |
| 212 "large_cta_image":{"url":"/cta.jpg"}, | |
| 213 "transparent_large_image":{"url":"/transparent.jpg"} | |
| 214 })json"; | |
| 215 base::Optional<DoodleConfig> config = | |
| 216 DoodleConfigFromJson(json, GURL("https://doodle.com/")); | |
| 217 ASSERT_TRUE(config.has_value()); | |
| 218 EXPECT_THAT(config->search_url, Eq(GURL("https://doodle.com/search"))); | |
| 219 EXPECT_THAT(config->target_url, Eq(GURL("https://doodle.com/target"))); | |
| 220 EXPECT_THAT(config->fullpage_interactive_url, | |
| 221 Eq(GURL("https://doodle.com/interactive"))); | |
| 222 EXPECT_THAT(config->large_image.url, | |
| 223 Eq(GURL("https://doodle.com/large.jpg"))); | |
| 224 ASSERT_TRUE(config->large_cta_image.has_value()); | |
| 225 EXPECT_THAT(config->large_cta_image->url, | |
| 226 Eq(GURL("https://doodle.com/cta.jpg"))); | |
| 227 ASSERT_TRUE(config->transparent_large_image.has_value()); | |
| 228 EXPECT_THAT(config->transparent_large_image->url, | |
| 229 Eq(GURL("https://doodle.com/transparent.jpg"))); | |
| 230 } | |
| 231 | |
| 232 TEST(DoodleConfigTest, PreservesFieldsOverRoundtrip) { | |
| 233 // Set all fields to non-default values. | |
| 234 DoodleConfig config(DoodleType::SLIDESHOW, | |
| 235 DoodleImage(GURL("https://www.doodle.com/img.jpg"))); | |
| 236 config.alt_text = "some text"; | |
| 237 config.interactive_html = "<div id='dood'></div>"; | |
| 238 config.search_url = GURL("https://doodle.com/search"); | |
| 239 config.target_url = GURL("https://doodle.com/target"); | |
| 240 config.fullpage_interactive_url = GURL("https://doodle.com/interactive"); | |
| 241 config.large_cta_image = DoodleImage(GURL("https://www.doodle.com/cta.jpg")); | |
| 242 config.transparent_large_image = | |
| 243 DoodleImage(GURL("https://www.doodle.com/transparent.jpg")); | |
| 244 | |
| 245 // Convert to a dictionary and back. | |
| 246 base::Optional<DoodleConfig> after_roundtrip = | |
| 247 DoodleConfig::FromDictionary(*config.ToDictionary(), base::nullopt); | |
|
sfiera
2017/03/13 13:07:53
Should fields be preserved when round-tripping wit
Marc Treib
2017/03/13 13:29:12
They should be preserved - the resolving only appl
| |
| 248 | |
| 249 // Make sure everything survived. | |
| 250 ASSERT_TRUE(after_roundtrip.has_value()); | |
| 251 EXPECT_THAT(*after_roundtrip, Eq(config)); | |
| 252 } | |
| 253 | |
|
sfiera
2017/03/13 13:07:53
Invalid URLs? I think you have a DCHECK when makin
Marc Treib
2017/03/13 13:29:12
Which DCHECK do you mean?
I've added tests with in
sfiera
2017/03/13 13:46:15
GURL::spec() DCHECKs on non-empty, invalid URLs. Y
Marc Treib
2017/03/13 14:04:32
Ah - the GURL construction handles that, it return
sfiera
2017/03/13 14:10:23
Hmm. I wonder how I knew about this, then—I could
| |
| 254 } // namespace doodle | |
| OLD | NEW |