OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 package org.chromium.chrome.browser.webapps; | 5 package org.chromium.chrome.browser.webapps; |
6 | 6 |
7 import static org.junit.Assert.assertEquals; | 7 import static org.junit.Assert.assertEquals; |
8 import static org.junit.Assert.assertFalse; | 8 import static org.junit.Assert.assertFalse; |
9 import static org.junit.Assert.assertTrue; | 9 import static org.junit.Assert.assertTrue; |
10 | 10 |
| 11 import android.content.Intent; |
| 12 import android.graphics.Bitmap; |
| 13 import android.graphics.Color; |
| 14 import android.os.Bundle; |
11 import android.provider.Settings; | 15 import android.provider.Settings; |
| 16 import android.text.TextUtils; |
12 | 17 |
13 import org.junit.Before; | 18 import org.junit.Before; |
14 import org.junit.Test; | 19 import org.junit.Test; |
15 import org.junit.runner.RunWith; | 20 import org.junit.runner.RunWith; |
16 import org.robolectric.RuntimeEnvironment; | 21 import org.robolectric.RuntimeEnvironment; |
17 import org.robolectric.annotation.Config; | 22 import org.robolectric.annotation.Config; |
18 import org.robolectric.shadows.ShadowApplication; | 23 import org.robolectric.shadows.ShadowApplication; |
| 24 import org.robolectric.shadows.ShadowBitmap; |
19 | 25 |
20 import org.chromium.base.CommandLine; | 26 import org.chromium.base.CommandLine; |
21 import org.chromium.base.ContextUtils; | 27 import org.chromium.base.ContextUtils; |
22 import org.chromium.blink_public.platform.WebDisplayMode; | 28 import org.chromium.blink_public.platform.WebDisplayMode; |
23 import org.chromium.chrome.browser.ShortcutHelper; | 29 import org.chromium.chrome.browser.ShortcutHelper; |
24 import org.chromium.chrome.browser.ShortcutSource; | |
25 import org.chromium.chrome.browser.tab.Tab; | 30 import org.chromium.chrome.browser.tab.Tab; |
26 import org.chromium.content_public.common.ScreenOrientationValues; | 31 import org.chromium.content_public.common.ScreenOrientationValues; |
27 import org.chromium.testing.local.LocalRobolectricTestRunner; | 32 import org.chromium.testing.local.LocalRobolectricTestRunner; |
28 import org.chromium.webapk.lib.client.WebApkVersion; | 33 import org.chromium.webapk.lib.client.WebApkVersion; |
| 34 import org.chromium.webapk.lib.common.WebApkConstants; |
| 35 import org.chromium.webapk.lib.common.WebApkMetaDataKeys; |
29 import org.chromium.webapk.test.WebApkTestHelper; | 36 import org.chromium.webapk.test.WebApkTestHelper; |
30 | 37 |
31 import java.util.HashMap; | 38 import java.util.HashMap; |
| 39 import java.util.Map; |
32 | 40 |
33 /** | 41 /** |
34 * Unit tests for WebApkUpdateManager. | 42 * Unit tests for WebApkUpdateManager. |
35 */ | 43 */ |
36 @RunWith(LocalRobolectricTestRunner.class) | 44 @RunWith(LocalRobolectricTestRunner.class) |
37 @Config(manifest = Config.NONE) | 45 @Config(manifest = Config.NONE) |
38 public class WebApkUpdateManagerTest { | 46 public class WebApkUpdateManagerTest { |
39 /** WebAPK's id in {@link WebAppDataStorage}. */ | 47 /** WebAPK's id in {@link WebAppDataStorage}. */ |
40 private static final String WEBAPK_ID = "id"; | 48 private static final String WEBAPK_ID = |
| 49 WebApkConstants.WEBAPK_ID_PREFIX + WebApkTestHelper.WEBAPK_PACKAGE_N
AME; |
41 | 50 |
42 /** Value of the "name" <meta-data> tag in the Android Manifest. */ | 51 /** Web Manifest URL */ |
43 private static final String ANDROID_MANIFEST_NAME = "Android Manifest name"; | 52 private static final String WEB_MANIFEST_URL = "manifest.json"; |
44 | 53 |
45 /** Value of the "name" property in the Web Manifest. */ | 54 private static final String START_URL = "/start_url.html"; |
46 private static final String WEB_MANIFEST_NAME = "Web Manifest name"; | 55 private static final String SCOPE_URL = "/"; |
| 56 private static final String NAME = "Long Name"; |
| 57 private static final String SHORT_NAME = "Short Name"; |
| 58 private static final String ICON_URL = "/icon.png"; |
| 59 private static final String ICON_MURMUR2_HASH = "3"; |
| 60 private static final int DISPLAY_MODE = WebDisplayMode.Undefined; |
| 61 private static final int ORIENTATION = ScreenOrientationValues.DEFAULT; |
| 62 private static final long THEME_COLOR = 1L; |
| 63 private static final long BACKGROUND_COLOR = 2L; |
| 64 |
| 65 /** Different name than the one used in {@link defaultManifestData()}. */ |
| 66 private static final String DIFFERENT_NAME = "Different Name"; |
47 | 67 |
48 /** {@link WebappDataStorage#Clock} subclass which enables time to be manual
ly advanced. */ | 68 /** {@link WebappDataStorage#Clock} subclass which enables time to be manual
ly advanced. */ |
49 private static class MockClock extends WebappDataStorage.Clock { | 69 private static class MockClock extends WebappDataStorage.Clock { |
50 // 0 has a special meaning: {@link WebappDataStorage#LAST_USED_UNSET}. | 70 // 0 has a special meaning: {@link WebappDataStorage#LAST_USED_UNSET}. |
51 private long mTimeMillis = 1; | 71 private long mTimeMillis = 1; |
52 | 72 |
53 public void advance(long millis) { | 73 public void advance(long millis) { |
54 mTimeMillis += millis; | 74 mTimeMillis += millis; |
55 } | 75 } |
56 | 76 |
57 @Override | 77 @Override |
58 public long currentTimeMillis() { | 78 public long currentTimeMillis() { |
59 return mTimeMillis; | 79 return mTimeMillis; |
60 } | 80 } |
61 } | 81 } |
62 | 82 |
63 /** Mock {@link ManifestUpgradeDetector}. */ | 83 /** Mock {@link WebApkUpdateDataFetcher}. */ |
64 private static class TestManifestUpgradeDetector extends ManifestUpgradeDete
ctor { | 84 private static class TestWebApkUpdateDataFetcher extends WebApkUpdateDataFet
cher { |
65 private boolean mStarted; | 85 private boolean mStarted; |
66 | 86 |
67 public TestManifestUpgradeDetector( | |
68 Tab tab, WebApkInfo info, ManifestUpgradeDetector.Callback callb
ack) { | |
69 super(tab, info, callback); | |
70 } | |
71 | |
72 public boolean wasStarted() { | 87 public boolean wasStarted() { |
73 return mStarted; | 88 return mStarted; |
74 } | 89 } |
75 | 90 |
76 @Override | 91 @Override |
77 public boolean start() { | 92 public boolean start(Tab tab, WebApkInfo oldInfo, Observer observer) { |
78 mStarted = true; | 93 mStarted = true; |
79 return true; | 94 return true; |
80 } | 95 } |
81 } | 96 } |
82 | 97 |
83 private static class TestWebApkUpdateManager extends WebApkUpdateManager { | 98 private static class TestWebApkUpdateManager extends WebApkUpdateManager { |
84 private WebappDataStorage.Clock mClock; | 99 private WebappDataStorage.Clock mClock; |
85 private TestManifestUpgradeDetector mUpgradeDetector; | 100 private TestWebApkUpdateDataFetcher mFetcher; |
86 private int mNumUpdatesRequested; | 101 private boolean mUpdateRequested; |
87 private String mUpdateName; | 102 private String mUpdateName; |
88 private boolean mDestroyedManifestUpgradeDetector; | 103 private boolean mDestroyedFetcher; |
89 | 104 |
90 public TestWebApkUpdateManager(WebappDataStorage.Clock clock) { | 105 public TestWebApkUpdateManager(WebappDataStorage.Clock clock) { |
91 mClock = clock; | 106 mClock = clock; |
92 } | 107 } |
93 | 108 |
94 /** | 109 /** |
95 * Returns whether the is-update-needed check has been triggered. | 110 * Returns whether the is-update-needed check has been triggered. |
96 */ | 111 */ |
97 public boolean updateCheckStarted() { | 112 public boolean updateCheckStarted() { |
98 return mUpgradeDetector != null && mUpgradeDetector.wasStarted(); | 113 return mFetcher != null && mFetcher.wasStarted(); |
99 } | 114 } |
100 | 115 |
101 /** | 116 /** |
102 * Returns whether an update has been requested. | 117 * Returns whether an update has been requested. |
103 */ | 118 */ |
104 public boolean updateRequested() { | 119 public boolean updateRequested() { |
105 return mNumUpdatesRequested > 0; | 120 return mUpdateRequested; |
106 } | 121 } |
107 | 122 |
108 /** | 123 /** |
109 * Returns the number of updates which have been requested. | |
110 */ | |
111 public int numUpdatesRequested() { | |
112 return mNumUpdatesRequested; | |
113 } | |
114 | |
115 /** | |
116 * Returns the "name" from the requested update. Null if an update has n
ot been requested. | 124 * Returns the "name" from the requested update. Null if an update has n
ot been requested. |
117 */ | 125 */ |
118 public String requestedUpdateName() { | 126 public String requestedUpdateName() { |
119 return mUpdateName; | 127 return mUpdateName; |
120 } | 128 } |
121 | 129 |
122 public boolean destroyedManifestUpgradeDetector() { | 130 public boolean destroyedFetcher() { |
123 return mDestroyedManifestUpgradeDetector; | 131 return mDestroyedFetcher; |
124 } | 132 } |
125 | 133 |
126 @Override | 134 @Override |
127 protected ManifestUpgradeDetector buildManifestUpgradeDetector(Tab tab,
WebApkInfo info) { | 135 protected WebApkUpdateDataFetcher buildFetcher() { |
128 mUpgradeDetector = new TestManifestUpgradeDetector(tab, info, this); | 136 mFetcher = new TestWebApkUpdateDataFetcher(); |
129 return mUpgradeDetector; | 137 return mFetcher; |
130 } | 138 } |
131 | 139 |
132 @Override | 140 @Override |
133 protected void updateAsync(WebApkInfo info, String bestIconUrl) { | 141 protected void updateAsync(WebApkInfo info, String bestIconUrl) { |
134 ++mNumUpdatesRequested; | 142 mUpdateRequested = true; |
135 mUpdateName = info.name(); | 143 mUpdateName = info.name(); |
136 } | 144 } |
137 | 145 |
138 @Override | 146 @Override |
139 protected void destroyUpgradeDetector() { | 147 protected void destroyFetcher() { |
140 mUpgradeDetector = null; | 148 mFetcher = null; |
141 mDestroyedManifestUpgradeDetector = true; | 149 mDestroyedFetcher = true; |
142 } | 150 } |
143 | 151 |
144 @Override | 152 @Override |
145 protected long currentTimeMillis() { | 153 protected long currentTimeMillis() { |
146 return mClock.currentTimeMillis(); | 154 return mClock.currentTimeMillis(); |
147 } | 155 } |
| 156 |
| 157 // Stubbed out because real implementation uses native. |
| 158 @Override |
| 159 protected boolean urlsMatchIgnoringFragments(String url1, String url2) { |
| 160 return TextUtils.equals(url1, url2); |
| 161 } |
| 162 } |
| 163 |
| 164 private static class ManifestData { |
| 165 public String startUrl; |
| 166 public String scopeUrl; |
| 167 public String name; |
| 168 public String shortName; |
| 169 public Map<String, String> iconUrlToMurmur2HashMap; |
| 170 public String bestIconUrl; |
| 171 public Bitmap bestIcon; |
| 172 public int displayMode; |
| 173 public int orientation; |
| 174 public long themeColor; |
| 175 public long backgroundColor; |
148 } | 176 } |
149 | 177 |
150 private MockClock mClock; | 178 private MockClock mClock; |
151 private int mShellApkVersion; | |
152 | |
153 /** Sets the version of the code in //chrome/android/webapk/shell_apk. */ | |
154 public void setShellApkVersion(int shellApkVersion) { | |
155 mShellApkVersion = shellApkVersion; | |
156 } | |
157 | 179 |
158 private WebappDataStorage getStorage() { | 180 private WebappDataStorage getStorage() { |
159 return WebappRegistry.getInstance().getWebappDataStorage(WEBAPK_ID); | 181 return WebappRegistry.getInstance().getWebappDataStorage(WEBAPK_ID); |
160 } | 182 } |
161 | 183 |
162 private WebApkInfo infoWithName(String name) { | 184 /** |
163 return WebApkInfo.create(WEBAPK_ID, "", "", null, name, "", WebDisplayMo
de.Standalone, | 185 * Registers WebAPK with default package name. Overwrites previous registrat
ions. |
164 ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, | 186 * @param manifestData <meta-data> values for WebAPK's Android Manife
st. |
165 ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, | 187 * @param shellApkVersionCode WebAPK's version of the //chrome/android/webap
k/shell_apk code. |
166 ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, | 188 */ |
167 WebApkTestHelper.WEBAPK_PACKAGE_NAME, mShellApkVersion, "", "", | 189 private void registerWebApk(ManifestData manifestData, int shellApkVersionCo
de) { |
168 new HashMap<String, String>()); | 190 Bundle metaData = new Bundle(); |
| 191 metaData.putInt( |
| 192 WebApkMetaDataKeys.SHELL_APK_VERSION, shellApkVersionCode); |
| 193 metaData.putString(WebApkMetaDataKeys.START_URL, manifestData.startUrl); |
| 194 metaData.putString(WebApkMetaDataKeys.SCOPE, manifestData.scopeUrl); |
| 195 metaData.putString(WebApkMetaDataKeys.NAME, manifestData.name); |
| 196 metaData.putString(WebApkMetaDataKeys.SHORT_NAME, manifestData.shortName
); |
| 197 metaData.putString(WebApkMetaDataKeys.THEME_COLOR, manifestData.themeCol
or + "L"); |
| 198 metaData.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, manifestData.bac
kgroundColor + "L"); |
| 199 metaData.putString(WebApkMetaDataKeys.WEB_MANIFEST_URL, WEB_MANIFEST_URL
); |
| 200 |
| 201 String iconUrlsAndIconMurmur2Hashes = ""; |
| 202 for (Map.Entry<String, String> mapEntry : manifestData.iconUrlToMurmur2H
ashMap.entrySet()) { |
| 203 String murmur2Hash = mapEntry.getValue(); |
| 204 if (murmur2Hash == null) { |
| 205 murmur2Hash = "0"; |
| 206 } |
| 207 iconUrlsAndIconMurmur2Hashes += " " + mapEntry.getKey() + " " + murm
ur2Hash; |
| 208 } |
| 209 iconUrlsAndIconMurmur2Hashes = iconUrlsAndIconMurmur2Hashes.trim(); |
| 210 metaData.putString(WebApkMetaDataKeys.ICON_URLS_AND_ICON_MURMUR2_HASHES, |
| 211 iconUrlsAndIconMurmur2Hashes); |
| 212 |
| 213 WebApkTestHelper.registerWebApkWithMetaData(metaData); |
169 } | 214 } |
170 | 215 |
171 private WebApkInfo fetchedWebApkInfo() { | 216 private static ManifestData defaultManifestData() { |
172 return infoWithName(WEB_MANIFEST_NAME); | 217 ManifestData manifestData = new ManifestData(); |
| 218 manifestData.startUrl = START_URL; |
| 219 manifestData.scopeUrl = SCOPE_URL; |
| 220 manifestData.name = NAME; |
| 221 manifestData.shortName = SHORT_NAME; |
| 222 |
| 223 manifestData.iconUrlToMurmur2HashMap = new HashMap<String, String>(); |
| 224 manifestData.iconUrlToMurmur2HashMap.put(ICON_URL, ICON_MURMUR2_HASH); |
| 225 |
| 226 manifestData.bestIconUrl = ICON_URL; |
| 227 manifestData.bestIcon = createBitmap(Color.GREEN); |
| 228 manifestData.displayMode = DISPLAY_MODE; |
| 229 manifestData.orientation = ORIENTATION; |
| 230 manifestData.themeColor = THEME_COLOR; |
| 231 manifestData.backgroundColor = BACKGROUND_COLOR; |
| 232 return manifestData; |
173 } | 233 } |
174 | 234 |
175 private void updateIfNeeded(WebApkUpdateManager updateManager) { | 235 private static WebApkInfo infoFromManifestData(ManifestData manifestData) { |
176 WebApkInfo info = infoWithName(ANDROID_MANIFEST_NAME); | 236 if (manifestData == null) return null; |
| 237 |
| 238 return WebApkInfo.create("", "", manifestData.scopeUrl, |
| 239 new WebApkInfo.Icon(manifestData.bestIcon), manifestData.name, |
| 240 manifestData.shortName, manifestData.displayMode, manifestData.o
rientation, -1, |
| 241 manifestData.themeColor, manifestData.backgroundColor, |
| 242 WebApkTestHelper.WEBAPK_PACKAGE_NAME, -1, WEB_MANIFEST_URL, |
| 243 manifestData.startUrl, manifestData.iconUrlToMurmur2HashMap); |
| 244 } |
| 245 |
| 246 /** |
| 247 * Creates 1x1 bitmap. |
| 248 * @param color The bitmap color. |
| 249 */ |
| 250 private static Bitmap createBitmap(int color) { |
| 251 int colors[] = { color }; |
| 252 return ShadowBitmap.createBitmap(colors, 1, 1, Bitmap.Config.ALPHA_8); |
| 253 } |
| 254 |
| 255 private static void updateIfNeeded(WebApkUpdateManager updateManager) { |
| 256 // Use the intent version of {@link WebApkInfo#create()} in order to tes
t default values |
| 257 // set by the intent version of {@link WebApkInfo#create()}. |
| 258 Intent intent = new Intent(); |
| 259 intent.putExtra(ShortcutHelper.EXTRA_URL, ""); |
| 260 intent.putExtra( |
| 261 ShortcutHelper.EXTRA_WEBAPK_PACKAGE_NAME, WebApkTestHelper.WEBAP
K_PACKAGE_NAME); |
| 262 WebApkInfo info = WebApkInfo.create(intent); |
| 263 |
177 updateManager.updateIfNeeded(null, info); | 264 updateManager.updateIfNeeded(null, info); |
178 } | 265 } |
179 | 266 |
180 private void onGotWebApkCompatibleWebManifestForInitialUrl( | 267 private static void onGotUnchangedWebManifestForInitialUrl(WebApkUpdateManag
er updateManager) { |
181 WebApkUpdateManager updateManager, boolean needsUpdate) { | 268 onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifes
tData()); |
| 269 } |
| 270 |
| 271 private static void onFinishedFetchingWebManifestForInitialUrl( |
| 272 WebApkUpdateManager updateManager, ManifestData fetchedManifestData)
{ |
| 273 String bestIconUrl = randomIconUrl(fetchedManifestData); |
182 updateManager.onFinishedFetchingWebManifestForInitialUrl( | 274 updateManager.onFinishedFetchingWebManifestForInitialUrl( |
183 needsUpdate, fetchedWebApkInfo(), null); | 275 infoFromManifestData(fetchedManifestData), bestIconUrl); |
| 276 } |
| 277 |
| 278 private static void onGotManifestData(WebApkUpdateManager updateManager, |
| 279 ManifestData fetchedManifestData) { |
| 280 String bestIconUrl = randomIconUrl(fetchedManifestData); |
| 281 updateManager.onGotManifestData(infoFromManifestData(fetchedManifestData
), bestIconUrl); |
| 282 } |
| 283 |
| 284 private static String randomIconUrl(ManifestData fetchedManifestData) { |
| 285 if (fetchedManifestData == null || fetchedManifestData.iconUrlToMurmur2H
ashMap.isEmpty()) { |
| 286 return null; |
| 287 } |
| 288 return fetchedManifestData.iconUrlToMurmur2HashMap.keySet().iterator().n
ext(); |
184 } | 289 } |
185 | 290 |
186 /** | 291 /** |
187 * Runs {@link WebApkUpdateManager#updateIfNeeded()} and returns whether an | 292 * Runs {@link WebApkUpdateManager#updateIfNeeded()} and returns whether an |
188 * is-update-needed check has been triggered. | 293 * is-update-needed check has been triggered. |
189 */ | 294 */ |
190 private boolean updateIfNeededChecksForUpdatedWebManifest() { | 295 private boolean updateIfNeededChecksForUpdatedWebManifest() { |
191 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 296 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
192 updateIfNeeded(updateManager); | 297 updateIfNeeded(updateManager); |
193 return updateManager.updateCheckStarted(); | 298 return updateManager.updateCheckStarted(); |
194 } | 299 } |
195 | 300 |
| 301 /** |
| 302 * Checks whether the WebAPK is updated given data from the WebAPK's Android
Manifest and data |
| 303 * from the fetched Web Manifest. |
| 304 */ |
| 305 private boolean checkUpdateNeededForFetchedManifest( |
| 306 ManifestData androidManifestData, ManifestData fetchedManifestData)
{ |
| 307 registerWebApk(androidManifestData, WebApkVersion.CURRENT_SHELL_APK_VERS
ION); |
| 308 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
| 309 |
| 310 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
| 311 updateIfNeeded(updateManager); |
| 312 assertTrue(updateManager.updateCheckStarted()); |
| 313 updateManager.onFinishedFetchingWebManifestForInitialUrl( |
| 314 infoFromManifestData(fetchedManifestData), fetchedManifestData.b
estIconUrl); |
| 315 return updateManager.updateRequested(); |
| 316 } |
| 317 |
196 @Before | 318 @Before |
197 public void setUp() { | 319 public void setUp() { |
198 ContextUtils.initApplicationContextForTests(RuntimeEnvironment.applicati
on); | 320 ContextUtils.initApplicationContextForTests(RuntimeEnvironment.applicati
on); |
199 CommandLine.init(null); | 321 CommandLine.init(null); |
200 | 322 |
| 323 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE
RSION); |
201 Settings.Secure.putInt(RuntimeEnvironment.application.getContentResolver
(), | 324 Settings.Secure.putInt(RuntimeEnvironment.application.getContentResolver
(), |
202 Settings.Secure.INSTALL_NON_MARKET_APPS, 1); | 325 Settings.Secure.INSTALL_NON_MARKET_APPS, 1); |
203 | 326 |
204 mClock = new MockClock(); | 327 mClock = new MockClock(); |
205 WebappDataStorage.setClockForTests(mClock); | 328 WebappDataStorage.setClockForTests(mClock); |
206 | 329 |
207 mShellApkVersion = WebApkVersion.CURRENT_SHELL_APK_VERSION; | |
208 | |
209 WebappRegistry.getInstance().register( | 330 WebappRegistry.getInstance().register( |
210 WEBAPK_ID, new WebappRegistry.FetchWebappDataStorageCallback() { | 331 WEBAPK_ID, new WebappRegistry.FetchWebappDataStorageCallback() { |
211 @Override | 332 @Override |
212 public void onWebappDataStorageRetrieved(WebappDataStorage s
torage) {} | 333 public void onWebappDataStorageRetrieved(WebappDataStorage s
torage) {} |
213 }); | 334 }); |
214 ShadowApplication.getInstance().runBackgroundTasks(); | 335 ShadowApplication.getInstance().runBackgroundTasks(); |
215 | 336 |
216 WebappDataStorage storage = getStorage(); | 337 WebappDataStorage storage = getStorage(); |
217 storage.updateTimeOfLastCheckForUpdatedWebManifest(); | 338 storage.updateTimeOfLastCheckForUpdatedWebManifest(); |
218 storage.updateTimeOfLastWebApkUpdateRequestCompletion(); | 339 storage.updateTimeOfLastWebApkUpdateRequestCompletion(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 406 } |
286 | 407 |
287 // Chrome is killed. | 408 // Chrome is killed. |
288 // {@link WebApkUpdateManager#onFinishedFetchingWebManifestForInitialUrl
()} is never called. | 409 // {@link WebApkUpdateManager#onFinishedFetchingWebManifestForInitialUrl
()} is never called. |
289 | 410 |
290 { | 411 { |
291 // Relaunching the WebAPK should do an is-update-needed check. | 412 // Relaunching the WebAPK should do an is-update-needed check. |
292 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(
mClock); | 413 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(
mClock); |
293 updateIfNeeded(updateManager); | 414 updateIfNeeded(updateManager); |
294 assertTrue(updateManager.updateCheckStarted()); | 415 assertTrue(updateManager.updateCheckStarted()); |
295 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); | 416 onGotUnchangedWebManifestForInitialUrl(updateManager); |
296 } | 417 } |
297 | 418 |
298 { | 419 { |
299 // Relaunching the WebAPK should not do an is-update-needed-check. | 420 // Relaunching the WebAPK should not do an is-update-needed-check. |
300 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(
mClock); | 421 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(
mClock); |
301 updateIfNeeded(updateManager); | 422 updateIfNeeded(updateManager); |
302 assertFalse(updateManager.updateCheckStarted()); | 423 assertFalse(updateManager.updateCheckStarted()); |
303 } | 424 } |
304 } | 425 } |
305 | 426 |
306 /** | 427 /** |
307 * Test that the completion time of the previous WebAPK update is not modifi
ed if: | 428 * Test that the completion time of the previous WebAPK update is not modifi
ed if: |
308 * - The previous WebAPK update succeeded. | 429 * - The previous WebAPK update succeeded. |
309 * AND | 430 * AND |
310 * - A WebAPK update is not required. | 431 * - A WebAPK update is not required. |
311 */ | 432 */ |
312 @Test | 433 @Test |
313 public void testUpdateNotNeeded() { | 434 public void testUpdateNotNeeded() { |
314 long initialTime = mClock.currentTimeMillis(); | 435 long initialTime = mClock.currentTimeMillis(); |
315 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 436 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
316 | 437 |
317 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 438 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
318 updateIfNeeded(updateManager); | 439 updateIfNeeded(updateManager); |
319 assertTrue(updateManager.updateCheckStarted()); | 440 assertTrue(updateManager.updateCheckStarted()); |
320 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); | 441 onGotUnchangedWebManifestForInitialUrl(updateManager); |
321 assertFalse(updateManager.updateRequested()); | 442 assertFalse(updateManager.updateRequested()); |
322 | 443 |
323 WebappDataStorage storage = getStorage(); | 444 WebappDataStorage storage = getStorage(); |
324 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); | 445 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); |
325 assertEquals(initialTime, storage.getLastWebApkUpdateRequestCompletionTi
me()); | 446 assertEquals(initialTime, storage.getLastWebApkUpdateRequestCompletionTi
me()); |
326 } | 447 } |
327 | 448 |
328 /** | 449 /** |
329 * Test that the last WebAPK update is marked as having succeeded if: | 450 * Test that the last WebAPK update is marked as having succeeded if: |
330 * - The previous WebAPK update failed. | 451 * - The previous WebAPK update failed. |
331 * AND | 452 * AND |
332 * - A WebAPK update is no longer required. | 453 * - A WebAPK update is no longer required. |
333 */ | 454 */ |
334 @Test | 455 @Test |
335 public void testMarkUpdateAsSucceededIfUpdateNoLongerNeeded() { | 456 public void testMarkUpdateAsSucceededIfUpdateNoLongerNeeded() { |
336 WebappDataStorage storage = getStorage(); | 457 WebappDataStorage storage = getStorage(); |
337 storage.updateDidLastWebApkUpdateRequestSucceed(false); | 458 storage.updateDidLastWebApkUpdateRequestSucceed(false); |
338 mClock.advance(WebApkUpdateManager.RETRY_UPDATE_DURATION); | 459 mClock.advance(WebApkUpdateManager.RETRY_UPDATE_DURATION); |
339 | 460 |
340 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 461 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
341 updateIfNeeded(updateManager); | 462 updateIfNeeded(updateManager); |
342 assertTrue(updateManager.updateCheckStarted()); | 463 assertTrue(updateManager.updateCheckStarted()); |
343 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); | 464 onGotUnchangedWebManifestForInitialUrl(updateManager); |
344 assertFalse(updateManager.updateRequested()); | 465 assertFalse(updateManager.updateRequested()); |
345 | 466 |
346 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); | 467 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); |
347 assertEquals( | 468 assertEquals( |
348 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo
mpletionTime()); | 469 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo
mpletionTime()); |
349 } | 470 } |
350 | 471 |
351 /** | 472 /** |
352 * Test that the WebAPK update is marked as having failed if Chrome is kille
d prior to the | 473 * Test that the WebAPK update is marked as having failed if Chrome is kille
d prior to the |
353 * WebAPK update completing. | 474 * WebAPK update completing. |
354 */ | 475 */ |
355 @Test | 476 @Test |
356 public void testMarkUpdateAsFailedIfClosePriorToUpdateCompleting() { | 477 public void testMarkUpdateAsFailedIfClosePriorToUpdateCompleting() { |
357 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 478 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
358 | 479 |
359 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 480 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
360 updateIfNeeded(updateManager); | 481 updateIfNeeded(updateManager); |
361 assertTrue(updateManager.updateCheckStarted()); | 482 assertTrue(updateManager.updateCheckStarted()); |
362 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, true); | 483 ManifestData manifestData = defaultManifestData(); |
| 484 manifestData.name = DIFFERENT_NAME; |
| 485 onFinishedFetchingWebManifestForInitialUrl(updateManager, manifestData); |
363 assertTrue(updateManager.updateRequested()); | 486 assertTrue(updateManager.updateRequested()); |
364 | 487 |
365 // Chrome is killed. {@link WebApkUpdateManager#onBuiltWebApk} is never
called. | 488 // Chrome is killed. {@link WebApkUpdateManager#onBuiltWebApk} is never
called. |
366 | 489 |
367 // Check {@link WebappDataStorage} state. | 490 // Check {@link WebappDataStorage} state. |
368 WebappDataStorage storage = getStorage(); | 491 WebappDataStorage storage = getStorage(); |
369 assertFalse(storage.getDidLastWebApkUpdateRequestSucceed()); | 492 assertFalse(storage.getDidLastWebApkUpdateRequestSucceed()); |
370 assertEquals( | 493 assertEquals( |
371 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo
mpletionTime()); | 494 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo
mpletionTime()); |
372 } | 495 } |
373 | 496 |
374 /** | 497 /** |
375 * Test that an update with data from the WebAPK's Android manifest is done
if: | 498 * Test that an update with data from the WebAPK's Android manifest is done
if: |
376 * - WebAPK's code is out of date | 499 * - WebAPK's code is out of date |
377 * AND | 500 * AND |
378 * - WebAPK's start_url does not refer to a Web Manifest. | 501 * - WebAPK's start_url does not refer to a Web Manifest. |
379 * | 502 * |
380 * It is good to minimize the number of users with out of date WebAPKs. We t
ry to keep WebAPKs | 503 * It is good to minimize the number of users with out of date WebAPKs. We t
ry to keep WebAPKs |
381 * up to date even if the web developer has removed the Web Manifest from th
eir site. | 504 * up to date even if the web developer has removed the Web Manifest from th
eir site. |
382 */ | 505 */ |
383 @Test | 506 @Test |
384 public void testShellApkOutOfDateNoWebManifest() { | 507 public void testShellApkOutOfDateNoWebManifest() { |
385 setShellApkVersion(WebApkVersion.CURRENT_SHELL_APK_VERSION - 1); | 508 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE
RSION - 1); |
386 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 509 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
387 | 510 |
388 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 511 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
389 updateIfNeeded(updateManager); | 512 updateIfNeeded(updateManager); |
390 assertTrue(updateManager.updateCheckStarted()); | 513 assertTrue(updateManager.updateCheckStarted()); |
391 | 514 |
392 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu
ll); | 515 onFinishedFetchingWebManifestForInitialUrl(updateManager, null); |
393 assertTrue(updateManager.updateRequested()); | 516 assertTrue(updateManager.updateRequested()); |
394 assertEquals(ANDROID_MANIFEST_NAME, updateManager.requestedUpdateName())
; | 517 assertEquals(NAME, updateManager.requestedUpdateName()); |
395 | 518 |
396 // Check that the {@link ManifestUpgradeDetector} has been destroyed. Th
is prevents | 519 // Check that the {@link ManifestUpgradeDetector} has been destroyed. Th
is prevents |
397 // {@link #onFinishedFetchingWebManifestForInitialUrl()} and {@link #onG
otManifestData()} | 520 // {@link #onFinishedFetchingWebManifestForInitialUrl()} and {@link #onG
otManifestData()} |
398 // from getting called. | 521 // from getting called. |
399 assertTrue(updateManager.destroyedManifestUpgradeDetector()); | 522 assertTrue(updateManager.destroyedFetcher()); |
400 } | 523 } |
401 | 524 |
402 /** | 525 /** |
403 * Test that an update with data from the fetched Web Manifest is done if th
e WebAPK's code is | 526 * Test that an update with data from the fetched Web Manifest is done if th
e WebAPK's code is |
404 * out of date and the WebAPK's start_url refers to a Web Manifest. | 527 * out of date and the WebAPK's start_url refers to a Web Manifest. |
405 */ | 528 */ |
406 @Test | 529 @Test |
407 public void testShellApkOutOfDateStillHasWebManifest() { | 530 public void testShellApkOutOfDateStillHasWebManifest() { |
408 setShellApkVersion(WebApkVersion.CURRENT_SHELL_APK_VERSION - 1); | 531 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE
RSION - 1); |
409 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 532 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
410 | 533 |
411 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 534 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
412 updateIfNeeded(updateManager); | 535 updateIfNeeded(updateManager); |
413 assertTrue(updateManager.updateCheckStarted()); | 536 assertTrue(updateManager.updateCheckStarted()); |
414 | 537 |
415 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, fetchedW
ebApkInfo(), null); | 538 onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifes
tData()); |
416 assertTrue(updateManager.updateRequested()); | 539 assertTrue(updateManager.updateRequested()); |
417 assertEquals(WEB_MANIFEST_NAME, updateManager.requestedUpdateName()); | 540 assertEquals(NAME, updateManager.requestedUpdateName()); |
418 | 541 |
419 assertTrue(updateManager.destroyedManifestUpgradeDetector()); | 542 assertTrue(updateManager.destroyedFetcher()); |
420 } | 543 } |
421 | 544 |
422 /** | 545 /** |
423 * Test that an update is requested if: | 546 * Test that an update is requested if: |
424 * - start_url does not refer to a Web Manifest. | 547 * - start_url does not refer to a Web Manifest. |
425 * AND | 548 * AND |
426 * - The user eventually navigates to a page pointing to a Web Manifest with
the correct URL. | 549 * - The user eventually navigates to a page pointing to a Web Manifest with
the correct URL. |
427 * AND | 550 * AND |
428 * - The Web Manifest has changed. | 551 * - The Web Manifest has changed. |
429 * | 552 * |
430 * This scenario can occur if the WebAPK's start_url is a Javascript redirec
t. | 553 * This scenario can occur if the WebAPK's start_url is a Javascript redirec
t. |
431 */ | 554 */ |
432 @Test | 555 @Test |
433 public void testStartUrlRedirectsToPageWithUpdatedWebManifest() { | 556 public void testStartUrlRedirectsToPageWithUpdatedWebManifest() { |
434 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 557 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
435 | 558 |
436 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 559 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
437 updateIfNeeded(updateManager); | 560 updateIfNeeded(updateManager); |
438 assertTrue(updateManager.updateCheckStarted()); | 561 assertTrue(updateManager.updateCheckStarted()); |
439 | 562 |
440 // start_url does not have a Web Manifest. No update should be requested
. | 563 // start_url does not have a Web Manifest. No update should be requested
. |
441 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu
ll); | 564 onFinishedFetchingWebManifestForInitialUrl(updateManager, null); |
442 assertFalse(updateManager.updateRequested()); | 565 assertFalse(updateManager.updateRequested()); |
443 // {@link ManifestUpgradeDetector} should still be alive so that it can
get | 566 // {@link ManifestUpgradeDetector} should still be alive so that it can
get |
444 // {@link #onGotManifestData} when page with the Web Manifest finishes l
oading. | 567 // {@link #onGotManifestData} when page with the Web Manifest finishes l
oading. |
445 assertFalse(updateManager.destroyedManifestUpgradeDetector()); | 568 assertFalse(updateManager.destroyedFetcher()); |
446 | 569 |
447 // start_url redirects to page with Web Manifest. | 570 // start_url redirects to page with Web Manifest. |
448 | 571 |
449 updateManager.onGotManifestData(true, fetchedWebApkInfo(), null); | 572 ManifestData manifestData = defaultManifestData(); |
| 573 manifestData.name = DIFFERENT_NAME; |
| 574 onGotManifestData(updateManager, manifestData); |
450 assertTrue(updateManager.updateRequested()); | 575 assertTrue(updateManager.updateRequested()); |
451 assertEquals(WEB_MANIFEST_NAME, updateManager.requestedUpdateName()); | 576 assertEquals(DIFFERENT_NAME, updateManager.requestedUpdateName()); |
452 | 577 |
453 assertTrue(updateManager.destroyedManifestUpgradeDetector()); | 578 assertTrue(updateManager.destroyedFetcher()); |
454 } | 579 } |
455 | 580 |
456 /** | 581 /** |
457 * Test than an update is not requested if: | 582 * Test that an update is not requested if: |
458 * - start_url does not refer to a Web Manifest. | 583 * - start_url does not refer to a Web Manifest. |
459 * AND | 584 * AND |
460 * - The user eventually navigates to a page pointing to a Web Manifest with
the correct URL. | 585 * - The user eventually navigates to a page pointing to a Web Manifest with
the correct URL. |
461 * AND | 586 * AND |
462 * - The Web Manifest has not changed. | 587 * - The Web Manifest has not changed. |
463 */ | 588 */ |
464 @Test | 589 @Test |
465 public void testStartUrlRedirectsToPageWithUnchangedWebManifest() { | 590 public void testStartUrlRedirectsToPageWithUnchangedWebManifest() { |
466 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); | 591 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); |
467 | 592 |
468 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); | 593 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo
ck); |
469 updateIfNeeded(updateManager); | 594 updateIfNeeded(updateManager); |
470 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu
ll); | 595 onFinishedFetchingWebManifestForInitialUrl(updateManager, null); |
471 updateManager.onGotManifestData(false, fetchedWebApkInfo(), null); | 596 onGotManifestData(updateManager, defaultManifestData()); |
472 assertFalse(updateManager.updateRequested()); | 597 assertFalse(updateManager.updateRequested()); |
473 | 598 |
474 // We got the Web Manifest. The {@link ManifestUpgradeDetector} should b
e destroyed to stop | 599 // We got the Web Manifest. The {@link ManifestUpgradeDetector} should b
e destroyed to stop |
475 // it from fetching the Web Manifest for subsequent page loads. | 600 // it from fetching the Web Manifest for subsequent page loads. |
476 assertTrue(updateManager.destroyedManifestUpgradeDetector()); | 601 assertTrue(updateManager.destroyedFetcher()); |
| 602 } |
| 603 |
| 604 @Test |
| 605 public void testManifestDoesNotUpgrade() { |
| 606 assertFalse( |
| 607 checkUpdateNeededForFetchedManifest(defaultManifestData(), defau
ltManifestData())); |
| 608 } |
| 609 |
| 610 /** |
| 611 * Test that an upgrade is not requested when the Web Manifest did not chang
e and the Web |
| 612 * Manifest scope is empty. |
| 613 */ |
| 614 @Test |
| 615 public void testManifestEmptyScopeShouldNotUpgrade() { |
| 616 ManifestData oldData = defaultManifestData(); |
| 617 // webapk_installer.cc sets the scope to the default scope if the scope
is empty. |
| 618 oldData.scopeUrl = ShortcutHelper.getScopeFromUrl(oldData.startUrl); |
| 619 ManifestData fetchedData = defaultManifestData(); |
| 620 fetchedData.scopeUrl = ""; |
| 621 assertTrue(!oldData.scopeUrl.equals(fetchedData.scopeUrl)); |
| 622 assertFalse(checkUpdateNeededForFetchedManifest(oldData, fetchedData)); |
| 623 } |
| 624 |
| 625 /** |
| 626 * Test that an upgrade is requested when the Web Manifest is updated from u
sing a non-empty |
| 627 * scope to an empty scope. |
| 628 */ |
| 629 @Test |
| 630 public void testManifestNonEmptyScopeToEmptyScopeShouldUpgrade() { |
| 631 ManifestData oldData = defaultManifestData(); |
| 632 oldData.startUrl = "/fancy/scope/special/snowflake.html"; |
| 633 oldData.scopeUrl = "/fancy/scope/"; |
| 634 assertTrue( |
| 635 !oldData.scopeUrl.equals(ShortcutHelper.getScopeFromUrl(oldData.
startUrl))); |
| 636 ManifestData fetchedData = defaultManifestData(); |
| 637 fetchedData.startUrl = "/fancy/scope/special/snowflake.html"; |
| 638 fetchedData.scopeUrl = ""; |
| 639 |
| 640 assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData)); |
| 641 } |
| 642 |
| 643 /** |
| 644 * Test that an upgrade is requested when: |
| 645 * - WebAPK was generated using icon at {@link ICON_URL} from Web Manifest. |
| 646 * - Bitmap at {@link ICON_URL} has changed. |
| 647 */ |
| 648 @Test |
| 649 public void testHomescreenIconChangeShouldUpgrade() { |
| 650 ManifestData fetchedData = defaultManifestData(); |
| 651 fetchedData.iconUrlToMurmur2HashMap.put(fetchedData.bestIconUrl, ICON_MU
RMUR2_HASH + "1"); |
| 652 fetchedData.bestIcon = createBitmap(Color.BLUE); |
| 653 assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fe
tchedData)); |
| 654 } |
| 655 |
| 656 /** |
| 657 * Test that an upgrade is requested when: |
| 658 * - WebAPK is generated using icon at {@link ICON_URL} from Web Manifest. |
| 659 * - Web Manifest is updated to refer to different icon. |
| 660 */ |
| 661 @Test |
| 662 public void testHomescreenBestIconUrlChangeShouldUpgrade() { |
| 663 ManifestData fetchedData = defaultManifestData(); |
| 664 fetchedData.iconUrlToMurmur2HashMap.clear(); |
| 665 fetchedData.iconUrlToMurmur2HashMap.put("/icon2.png", "22"); |
| 666 fetchedData.bestIconUrl = "/icon2.png"; |
| 667 assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fe
tchedData)); |
| 668 } |
| 669 |
| 670 /** |
| 671 * Test that an upgrade is not requested if: |
| 672 * - icon URL is added to the Web Manifest |
| 673 * AND |
| 674 * - "best" icon URL for the launcher icon did not change. |
| 675 */ |
| 676 @Test |
| 677 public void testIconUrlsChangeShouldNotUpgradeIfTheBestIconUrlDoesNotChange(
) { |
| 678 ManifestData fetchedData = defaultManifestData(); |
| 679 fetchedData.iconUrlToMurmur2HashMap.clear(); |
| 680 fetchedData.iconUrlToMurmur2HashMap.put(ICON_URL, ICON_MURMUR2_HASH); |
| 681 fetchedData.iconUrlToMurmur2HashMap.put("/icon2.png", null); |
| 682 assertFalse(checkUpdateNeededForFetchedManifest(defaultManifestData(), f
etchedData)); |
| 683 } |
| 684 |
| 685 /** |
| 686 * Test than upgrade is requested if: |
| 687 * - the WebAPK's meta data has murmur2 hashes for all of the icons. |
| 688 * AND |
| 689 * - the Web Manifest has not changed |
| 690 * AND |
| 691 * - the computed best icon URL is different from the one stored in the WebA
PK's meta data. |
| 692 */ |
| 693 @Test |
| 694 public void testWebManifestSameButBestIconUrlChangedShouldNotUpgrade() { |
| 695 String iconUrl1 = "/icon1.png"; |
| 696 String iconUrl2 = "/icon2.png"; |
| 697 String hash1 = "11"; |
| 698 String hash2 = "22"; |
| 699 |
| 700 ManifestData oldData = defaultManifestData(); |
| 701 oldData.bestIconUrl = iconUrl1; |
| 702 oldData.iconUrlToMurmur2HashMap.clear(); |
| 703 oldData.iconUrlToMurmur2HashMap.put(iconUrl1, hash1); |
| 704 oldData.iconUrlToMurmur2HashMap.put(iconUrl2, hash2); |
| 705 |
| 706 ManifestData fetchedData = defaultManifestData(); |
| 707 fetchedData.bestIconUrl = iconUrl2; |
| 708 fetchedData.iconUrlToMurmur2HashMap.clear(); |
| 709 fetchedData.iconUrlToMurmur2HashMap.put(iconUrl1, null); |
| 710 fetchedData.iconUrlToMurmur2HashMap.put(iconUrl2, hash2); |
| 711 |
| 712 assertFalse(checkUpdateNeededForFetchedManifest(oldData, fetchedData)); |
477 } | 713 } |
478 } | 714 } |
OLD | NEW |