Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/ntp_snippets/ntp_snippets_service.h" | |
| 6 | |
| 5 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 6 #include "base/macros.h" | 8 #include "base/macros.h" |
| 7 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 8 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 10 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
| 11 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 12 #include "components/ntp_snippets/ntp_snippet.h" | 14 #include "components/ntp_snippets/ntp_snippet.h" |
| 13 #include "components/ntp_snippets/ntp_snippets_fetcher.h" | 15 #include "components/ntp_snippets/ntp_snippets_fetcher.h" |
| 14 #include "components/ntp_snippets/ntp_snippets_service.h" | |
| 15 #include "components/prefs/testing_pref_service.h" | 16 #include "components/prefs/testing_pref_service.h" |
| 16 #include "net/url_request/url_request_test_util.h" | 17 #include "net/url_request/url_request_test_util.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 namespace ntp_snippets { | 20 namespace ntp_snippets { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 24 const base::Time::Exploded kDefaultCreationTime = {2015, 11, 4, 25, 13, 46, 45}; | |
| 25 | |
| 26 base::Time GetDefaultCreationTime() { | |
| 27 return base::Time::FromUTCExploded(kDefaultCreationTime); | |
| 28 } | |
| 29 | |
| 23 std::string GetTestJson(const std::string& content_creation_time_str, | 30 std::string GetTestJson(const std::string& content_creation_time_str, |
| 24 const std::string& expiry_time_str) { | 31 const std::string& expiry_time_str) { |
| 25 char json_str_format[] = | 32 char json_str_format[] = |
| 26 "{ \"recos\": [ " | 33 "{ \"recos\": [ " |
| 27 "{ \"contentInfo\": {" | 34 "{ \"contentInfo\": {" |
| 28 "\"url\" : \"http://localhost/foobar\"," | 35 "\"url\" : \"http://localhost/foobar\"," |
| 29 "\"site_title\" : \"Site Title\"," | 36 "\"site_title\" : \"Site Title\"," |
| 30 "\"favicon_url\" : \"http://localhost/favicon\"," | 37 "\"favicon_url\" : \"http://localhost/favicon\"," |
| 31 "\"title\" : \"Title\"," | 38 "\"title\" : \"Title\"," |
| 32 "\"snippet\" : \"Snippet\"," | 39 "\"snippet\" : \"Snippet\"," |
| 33 "\"thumbnailUrl\" : \"http://localhost/salient_image\"," | 40 "\"thumbnailUrl\" : \"http://localhost/salient_image\"," |
| 34 "\"creationTimestampSec\" : \"%s\"," | 41 "\"creationTimestampSec\" : \"%s\"," |
| 35 "\"expiryTimestampSec\" : \"%s\"" | 42 "\"expiryTimestampSec\" : \"%s\"" |
| 36 "}}" | 43 "}}" |
| 37 "]}"; | 44 "]}"; |
| 38 | 45 |
| 39 return base::StringPrintf(json_str_format, content_creation_time_str.c_str(), | 46 return base::StringPrintf(json_str_format, content_creation_time_str.c_str(), |
| 40 expiry_time_str.c_str()); | 47 expiry_time_str.c_str()); |
| 41 } | 48 } |
| 42 | 49 |
| 43 std::string GetTestJson(const std::string& content_creation_time_str) { | 50 std::string GetTestJson(const std::string& content_creation_time_str) { |
| 44 int64_t expiry_time = | 51 base::Time expiry_time = base::Time::Now() + base::TimeDelta::FromHours(1); |
| 45 (base::Time::Now() + base::TimeDelta::FromHours(1)).ToJavaTime() / | |
| 46 base::Time::kMillisecondsPerSecond; | |
| 47 | |
| 48 return GetTestJson(content_creation_time_str, | 52 return GetTestJson(content_creation_time_str, |
| 49 base::Int64ToString(expiry_time)); | 53 NTPSnippet::TimeToJsonString(expiry_time)); |
| 50 } | 54 } |
| 51 | 55 |
| 52 std::string GetTestJson(int64_t content_creation_time_sec) { | 56 std::string GetTestJson() { |
| 53 int64_t expiry_time = | 57 return GetTestJson(NTPSnippet::TimeToJsonString(GetDefaultCreationTime())); |
| 54 (base::Time::Now() + base::TimeDelta::FromHours(1)).ToJavaTime() / | |
| 55 base::Time::kMillisecondsPerSecond; | |
| 56 | |
| 57 return GetTestJson(base::Int64ToString(content_creation_time_sec), | |
| 58 base::Int64ToString(expiry_time)); | |
| 59 } | 58 } |
| 60 | 59 |
| 61 std::string GetTestExpiredJson(int64_t content_creation_time_sec) { | 60 std::string GetTestExpiredJson() { |
| 62 int64_t expiry_time = | 61 return GetTestJson(NTPSnippet::TimeToJsonString(GetDefaultCreationTime()), |
| 63 (base::Time::Now()).ToJavaTime() / base::Time::kMillisecondsPerSecond; | 62 NTPSnippet::TimeToJsonString(base::Time::Now())); |
| 64 | |
| 65 return GetTestJson(base::Int64ToString(content_creation_time_sec), | |
| 66 base::Int64ToString(expiry_time)); | |
| 67 } | 63 } |
| 68 | 64 |
| 69 void ParseJson( | 65 void ParseJson( |
| 70 const std::string& json, | 66 const std::string& json, |
| 71 const ntp_snippets::NTPSnippetsService::SuccessCallback& success_callback, | 67 const ntp_snippets::NTPSnippetsService::SuccessCallback& success_callback, |
| 72 const ntp_snippets::NTPSnippetsService::ErrorCallback& error_callback) { | 68 const ntp_snippets::NTPSnippetsService::ErrorCallback& error_callback) { |
| 73 base::JSONReader json_reader; | 69 base::JSONReader json_reader; |
| 74 scoped_ptr<base::Value> value = json_reader.ReadToValue(json); | 70 scoped_ptr<base::Value> value = json_reader.ReadToValue(json); |
| 71 ASSERT_TRUE(value); | |
|
Marc Treib
2016/04/12 14:47:51
This is a bit pointless right now - I'll add tests
| |
| 75 if (value) { | 72 if (value) { |
| 76 success_callback.Run(std::move(value)); | 73 success_callback.Run(std::move(value)); |
| 77 } else { | 74 } else { |
| 78 error_callback.Run(json_reader.GetErrorMessage()); | 75 error_callback.Run(json_reader.GetErrorMessage()); |
| 79 } | 76 } |
| 80 } | 77 } |
| 81 | 78 |
| 82 } // namespace | 79 } // namespace |
| 83 | 80 |
| 84 class NTPSnippetsServiceTest : public testing::Test { | 81 class NTPSnippetsServiceTest : public testing::Test { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 97 scoped_refptr<base::SingleThreadTaskRunner> task_runner( | 94 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 98 base::ThreadTaskRunnerHandle::Get()); | 95 base::ThreadTaskRunnerHandle::Get()); |
| 99 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = | 96 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = |
| 100 new net::TestURLRequestContextGetter(task_runner.get()); | 97 new net::TestURLRequestContextGetter(task_runner.get()); |
| 101 | 98 |
| 102 service_.reset(new NTPSnippetsService( | 99 service_.reset(new NTPSnippetsService( |
| 103 pref_service_.get(), nullptr, task_runner, std::string("fr"), nullptr, | 100 pref_service_.get(), nullptr, task_runner, std::string("fr"), nullptr, |
| 104 make_scoped_ptr(new NTPSnippetsFetcher( | 101 make_scoped_ptr(new NTPSnippetsFetcher( |
| 105 task_runner, std::move(request_context_getter), true)), | 102 task_runner, std::move(request_context_getter), true)), |
| 106 base::Bind(&ParseJson))); | 103 base::Bind(&ParseJson))); |
| 104 service_->Init(true); | |
| 107 } | 105 } |
| 108 | 106 |
| 109 protected: | 107 protected: |
| 110 NTPSnippetsService* service() { | 108 NTPSnippetsService* service() { |
| 111 return service_.get(); | 109 return service_.get(); |
| 112 } | 110 } |
| 113 | 111 |
| 114 bool LoadFromJSONString(const std::string& json) { | 112 void LoadFromJSONString(const std::string& json) { |
| 115 scoped_ptr<base::Value> value = base::JSONReader::Read(json); | 113 service_->OnSnippetsDownloaded(json); |
| 116 if (!value) | |
| 117 return false; | |
| 118 | |
| 119 return service_->LoadFromValue(*value); | |
| 120 } | 114 } |
| 121 | 115 |
| 122 private: | 116 private: |
| 123 base::MessageLoop message_loop_; | 117 base::MessageLoop message_loop_; |
| 124 scoped_ptr<TestingPrefServiceSimple> pref_service_; | 118 scoped_ptr<TestingPrefServiceSimple> pref_service_; |
| 125 scoped_ptr<NTPSnippetsService> service_; | 119 scoped_ptr<NTPSnippetsService> service_; |
| 126 | 120 |
| 127 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); | 121 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); |
| 128 }; | 122 }; |
| 129 | 123 |
| 130 TEST_F(NTPSnippetsServiceTest, Loop) { | 124 TEST_F(NTPSnippetsServiceTest, Loop) { |
| 131 std::string json_str( | 125 std::string json_str( |
| 132 "{ \"recos\": [ " | 126 "{ \"recos\": [ " |
| 133 "{ \"contentInfo\": { \"url\" : \"http://localhost/foobar\" }}" | 127 "{ \"contentInfo\": { \"url\" : \"http://localhost/foobar\" }}" |
| 134 "]}"); | 128 "]}"); |
| 135 ASSERT_TRUE(LoadFromJSONString(json_str)); | 129 LoadFromJSONString(json_str); |
| 136 | 130 |
| 137 // The same for loop without the '&' should not compile. | 131 // The same for loop without the '&' should not compile. |
| 138 for (auto& snippet : *service()) { | 132 for (auto& snippet : *service()) { |
| 139 // Snippet here is a const. | 133 // Snippet here is a const. |
| 140 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); | 134 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); |
| 141 } | 135 } |
| 142 // Without the const, this should not compile. | 136 // Without the const, this should not compile. |
| 143 for (const NTPSnippet& snippet : *service()) { | 137 for (const NTPSnippet& snippet : *service()) { |
| 144 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); | 138 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); |
| 145 } | 139 } |
| 146 } | 140 } |
| 147 | 141 |
| 148 TEST_F(NTPSnippetsServiceTest, Full) { | 142 TEST_F(NTPSnippetsServiceTest, Full) { |
| 149 std::string json_str(GetTestJson(1448459205)); | 143 std::string json_str(GetTestJson()); |
| 150 | 144 |
| 151 ASSERT_TRUE(LoadFromJSONString(json_str)); | 145 LoadFromJSONString(json_str); |
| 152 EXPECT_EQ(service()->size(), 1u); | 146 EXPECT_EQ(service()->size(), 1u); |
| 153 | 147 |
| 154 // The same for loop without the '&' should not compile. | 148 // The same for loop without the '&' should not compile. |
| 155 for (auto& snippet : *service()) { | 149 for (auto& snippet : *service()) { |
| 156 // Snippet here is a const. | 150 // Snippet here is a const. |
| 157 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); | 151 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); |
| 158 EXPECT_EQ(snippet.site_title(), "Site Title"); | 152 EXPECT_EQ(snippet.site_title(), "Site Title"); |
| 159 EXPECT_EQ(snippet.favicon_url(), GURL("http://localhost/favicon")); | 153 EXPECT_EQ(snippet.favicon_url(), GURL("http://localhost/favicon")); |
| 160 EXPECT_EQ(snippet.title(), "Title"); | 154 EXPECT_EQ(snippet.title(), "Title"); |
| 161 EXPECT_EQ(snippet.snippet(), "Snippet"); | 155 EXPECT_EQ(snippet.snippet(), "Snippet"); |
| 162 EXPECT_EQ(snippet.salient_image_url(), | 156 EXPECT_EQ(snippet.salient_image_url(), |
| 163 GURL("http://localhost/salient_image")); | 157 GURL("http://localhost/salient_image")); |
| 164 base::Time then = | 158 EXPECT_EQ(GetDefaultCreationTime(), snippet.publish_date()); |
| 165 base::Time::FromUTCExploded({2015, 11, 4, 25, 13, 46, 45}); | |
| 166 EXPECT_EQ(then, snippet.publish_date()); | |
| 167 } | 159 } |
| 168 } | 160 } |
| 169 | 161 |
| 170 TEST_F(NTPSnippetsServiceTest, Discard) { | 162 TEST_F(NTPSnippetsServiceTest, Discard) { |
| 171 std::string json_str( | 163 std::string json_str( |
| 172 "{ \"recos\": [ { \"contentInfo\": { \"url\" : \"http://site.com\" }}]}"); | 164 "{ \"recos\": [ { \"contentInfo\": { \"url\" : \"http://site.com\" }}]}"); |
| 173 ASSERT_TRUE(LoadFromJSONString(json_str)); | 165 LoadFromJSONString(json_str); |
| 174 | 166 |
| 175 ASSERT_EQ(1u, service()->size()); | 167 ASSERT_EQ(1u, service()->size()); |
| 176 | 168 |
| 177 // Discarding a non-existent snippet shouldn't do anything. | 169 // Discarding a non-existent snippet shouldn't do anything. |
| 178 EXPECT_FALSE(service()->DiscardSnippet(GURL("http://othersite.com"))); | 170 EXPECT_FALSE(service()->DiscardSnippet(GURL("http://othersite.com"))); |
| 179 EXPECT_EQ(1u, service()->size()); | 171 EXPECT_EQ(1u, service()->size()); |
| 180 | 172 |
| 181 // Discard the snippet. | 173 // Discard the snippet. |
| 182 EXPECT_TRUE(service()->DiscardSnippet(GURL("http://site.com"))); | 174 EXPECT_TRUE(service()->DiscardSnippet(GURL("http://site.com"))); |
| 183 EXPECT_EQ(0u, service()->size()); | 175 EXPECT_EQ(0u, service()->size()); |
| 184 | 176 |
| 185 // Make sure that fetching the same snippet again does not re-add it. | 177 // Make sure that fetching the same snippet again does not re-add it. |
| 186 ASSERT_TRUE(LoadFromJSONString(json_str)); | 178 LoadFromJSONString(json_str); |
| 187 EXPECT_EQ(0u, service()->size()); | 179 EXPECT_EQ(0u, service()->size()); |
| 188 | 180 |
| 189 // The snippet should stay discarded even after re-creating the service. | 181 // The snippet should stay discarded even after re-creating the service. |
| 190 CreateSnippetsService(); | 182 CreateSnippetsService(); |
| 191 // Init the service, so the prefs get loaded. | 183 LoadFromJSONString(json_str); |
| 192 // TODO(treib): This should happen in CreateSnippetsService. | |
| 193 service()->Init(true); | |
| 194 ASSERT_TRUE(LoadFromJSONString(json_str)); | |
| 195 EXPECT_EQ(0u, service()->size()); | 184 EXPECT_EQ(0u, service()->size()); |
| 196 } | 185 } |
| 197 | 186 |
| 198 TEST_F(NTPSnippetsServiceTest, CreationTimestampParseFail) { | 187 TEST_F(NTPSnippetsServiceTest, CreationTimestampParseFail) { |
| 199 std::string json_str(GetTestJson("aaa1448459205")); | 188 std::string json_str(GetTestJson("aaa1448459205")); |
| 200 | 189 |
| 201 ASSERT_TRUE(LoadFromJSONString(json_str)); | 190 LoadFromJSONString(json_str); |
| 202 EXPECT_EQ(service()->size(), 1u); | 191 EXPECT_EQ(service()->size(), 1u); |
| 203 | 192 |
| 204 // The same for loop without the '&' should not compile. | 193 // The same for loop without the '&' should not compile. |
| 205 for (auto& snippet : *service()) { | 194 for (auto& snippet : *service()) { |
| 206 // Snippet here is a const. | 195 // Snippet here is a const. |
| 207 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); | 196 EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar")); |
| 208 EXPECT_EQ(snippet.title(), "Title"); | 197 EXPECT_EQ(snippet.title(), "Title"); |
| 209 EXPECT_EQ(snippet.snippet(), "Snippet"); | 198 EXPECT_EQ(snippet.snippet(), "Snippet"); |
| 210 EXPECT_EQ(base::Time::UnixEpoch(), snippet.publish_date()); | 199 EXPECT_EQ(base::Time::UnixEpoch(), snippet.publish_date()); |
| 211 } | 200 } |
| 212 } | 201 } |
| 213 | 202 |
| 214 TEST_F(NTPSnippetsServiceTest, RemoveExpiredContent) { | 203 TEST_F(NTPSnippetsServiceTest, RemoveExpiredContent) { |
| 215 std::string json_str(GetTestExpiredJson(1448459205)); | 204 std::string json_str(GetTestExpiredJson()); |
| 216 | 205 |
| 217 ASSERT_TRUE(LoadFromJSONString(json_str)); | 206 LoadFromJSONString(json_str); |
| 218 EXPECT_EQ(service()->size(), 0u); | 207 EXPECT_EQ(service()->size(), 0u); |
| 219 } | 208 } |
| 220 | 209 |
| 221 } // namespace ntp_snippets | 210 } // namespace ntp_snippets |
| OLD | NEW |