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 package org.chromium.chrome.browser.search_engines.settings;
6 
7 import static org.hamcrest.MatcherAssert.assertThat;
8 import static org.hamcrest.Matchers.contains;
9 
10 import android.text.format.DateUtils;
11 
12 import org.junit.Test;
13 import org.junit.runner.RunWith;
14 import org.robolectric.annotation.Config;
15 
16 import org.chromium.base.test.BaseRobolectricTestRunner;
17 import org.chromium.components.search_engines.TemplateUrl;
18 
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22 
23 /** Unit tests for {@link SearchEngineAdapter}. */
24 @RunWith(BaseRobolectricTestRunner.class)
25 @Config(manifest = Config.NONE)
26 public class SearchEngineAdapterTest {
27     @Test
testSortandGetCustomSearchEngine()28     public void testSortandGetCustomSearchEngine() {
29         long currentTime = System.currentTimeMillis();
30         TemplateUrl dse = new MockTemplateUrl(0, "default", currentTime);
31 
32         MockTemplateUrl prepopulated1 = new MockTemplateUrl(11, "prepopulated1", currentTime);
33         prepopulated1.isPrepopulated = true;
34         prepopulated1.prepopulatedId = 0;
35 
36         MockTemplateUrl prepopulated2 = new MockTemplateUrl(12, "prepopulated2", currentTime - 1);
37         prepopulated2.isPrepopulated = true;
38         prepopulated2.prepopulatedId = 1;
39 
40         MockTemplateUrl prepopulated3 = new MockTemplateUrl(13, "prepopulated3", currentTime - 2);
41         prepopulated3.isPrepopulated = true;
42         prepopulated3.prepopulatedId = 2;
43 
44         MockTemplateUrl custom1 = new MockTemplateUrl(101, "custom_keyword1", currentTime);
45         MockTemplateUrl custom2 = new MockTemplateUrl(102, "custom_keyword2", currentTime - 1);
46         MockTemplateUrl custom3 = new MockTemplateUrl(103, "custom_keyword3", currentTime - 2);
47         MockTemplateUrl custom4 = new MockTemplateUrl(104, "custom_keyword4", currentTime - 3);
48         MockTemplateUrl custom5 = new MockTemplateUrl(105, "custom_keyword5", currentTime - 4);
49 
50         ArrayList<TemplateUrl> templateUrls = new ArrayList<>(Arrays.asList(
51                 dse, prepopulated1, prepopulated2, prepopulated3, custom1, custom2, custom3));
52 
53         List<TemplateUrl> output = new ArrayList<>(templateUrls);
54         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, dse);
55         assertThat(output,
56                 contains(prepopulated1, prepopulated2, prepopulated3, dse, custom1, custom2,
57                         custom3));
58 
59         // Mark one of the custom engines as older than the visible threshold.
60         custom2.updateAgeInDays(3);
61         output = new ArrayList<>(templateUrls);
62         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, dse);
63         assertThat(output,
64                 contains(prepopulated1, prepopulated2, prepopulated3, dse, custom1, custom3));
65 
66         // Mark one of the custom engines as older than the other.
67         custom1.updateAgeInDays(1);
68         output = new ArrayList<>(templateUrls);
69         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, dse);
70         assertThat(output,
71                 contains(prepopulated1, prepopulated2, prepopulated3, dse, custom3, custom1));
72 
73         // Include more than 3 custom serach engines and ensure they're filtered accordingly.
74         templateUrls.add(custom4);
75         templateUrls.add(custom5);
76         output = new ArrayList<>(templateUrls);
77         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, dse);
78         assertThat(output,
79                 contains(prepopulated1, prepopulated2, prepopulated3, dse, custom3, custom4,
80                         custom5));
81 
82         // Specify an older custom search engine as default, and ensure it is included as well as
83         // the 3 most recent custom search engines.
84         output = new ArrayList<>(Arrays.asList(
85                 prepopulated1, prepopulated2, custom1, custom2, custom3, custom4, custom5));
86         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, custom2);
87         assertThat(
88                 output, contains(prepopulated1, prepopulated2, custom2, custom3, custom4, custom5));
89     }
90 
91     @Test
testSortandGetCustomSearchEngine_PrepopulateIdOrdering()92     public void testSortandGetCustomSearchEngine_PrepopulateIdOrdering() {
93         long currentTime = System.currentTimeMillis();
94         MockTemplateUrl prepopulated1 = new MockTemplateUrl(11, "prepopulated1", currentTime);
95         prepopulated1.isPrepopulated = true;
96         prepopulated1.prepopulatedId = 3;
97 
98         MockTemplateUrl prepopulated2 = new MockTemplateUrl(12, "prepopulated2", currentTime - 1);
99         prepopulated2.isPrepopulated = true;
100         prepopulated2.prepopulatedId = 1;
101 
102         MockTemplateUrl prepopulated3 = new MockTemplateUrl(13, "prepopulated3", currentTime - 2);
103         prepopulated3.isPrepopulated = true;
104         prepopulated3.prepopulatedId = 4;
105 
106         List<TemplateUrl> templateUrls = Arrays.asList(prepopulated1, prepopulated2, prepopulated3);
107 
108         List<TemplateUrl> output = new ArrayList<>(templateUrls);
109         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, prepopulated1);
110         assertThat(output, contains(prepopulated2, prepopulated1, prepopulated3));
111 
112         prepopulated1.prepopulatedId = 0;
113         output = new ArrayList<>(templateUrls);
114         SearchEngineAdapter.sortAndFilterUnnecessaryTemplateUrl(output, prepopulated1);
115         assertThat(output, contains(prepopulated1, prepopulated2, prepopulated3));
116     }
117 
118     private static class MockTemplateUrl extends TemplateUrl {
119         public String shortName = "";
120         public int prepopulatedId;
121         public boolean isPrepopulated;
122         public String keyword = "";
123         public long lastVisitedTime;
124         public String url = "https://testurl.com/?searchstuff={searchTerms}";
125 
MockTemplateUrl(long fakeNativePtr, String keyword, long lastVisitedTime)126         public MockTemplateUrl(long fakeNativePtr, String keyword, long lastVisitedTime) {
127             super(fakeNativePtr);
128             this.keyword = keyword;
129             this.shortName = keyword;
130             this.lastVisitedTime = lastVisitedTime;
131         }
132 
133         @Override
getShortName()134         public String getShortName() {
135             return shortName;
136         }
137 
138         @Override
getPrepopulatedId()139         public int getPrepopulatedId() {
140             return prepopulatedId;
141         }
142 
143         @Override
getIsPrepopulated()144         public boolean getIsPrepopulated() {
145             return isPrepopulated;
146         }
147 
148         @Override
getKeyword()149         public String getKeyword() {
150             return keyword;
151         }
152 
153         @Override
getLastVisitedTime()154         public long getLastVisitedTime() {
155             return lastVisitedTime;
156         }
157 
158         @Override
getURL()159         public String getURL() {
160             return url;
161         }
162 
updateAgeInDays(int days)163         void updateAgeInDays(int days) {
164             lastVisitedTime = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS * days;
165         }
166     }
167 }
168