test_ListsFeed.js (5317B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 ChromeUtils.defineESModuleGetters(this, { 7 actionTypes: "resource://newtab/common/Actions.mjs", 8 ListsFeed: "resource://newtab/lib/Widgets/ListsFeed.sys.mjs", 9 sinon: "resource://testing-common/Sinon.sys.mjs", 10 }); 11 12 const PREF_LISTS_ENABLED = "widgets.lists.enabled"; 13 const PREF_SYSTEM_LISTS_ENABLED = "widgets.system.lists.enabled"; 14 15 add_task(async function test_construction() { 16 let feed = new ListsFeed(); 17 18 feed.store = { 19 getState() { 20 return this.state; 21 }, 22 dispatch: sinon.spy(), 23 state: { 24 Prefs: { 25 values: { 26 [PREF_SYSTEM_LISTS_ENABLED]: false, 27 }, 28 }, 29 }, 30 }; 31 32 info("ListsFeed constructor should create initial values"); 33 34 Assert.ok(feed, "Could construct a ListsFeed"); 35 Assert.ok(!feed.loaded, "ListsFeed is not loaded"); 36 Assert.ok(!feed.enabled); 37 }); 38 39 add_task(async function test_onAction_INIT() { 40 let feed = new ListsFeed(); 41 42 feed.store = { 43 getState() { 44 return this.state; 45 }, 46 dispatch: sinon.spy(), 47 state: { 48 Prefs: { 49 values: { 50 [PREF_LISTS_ENABLED]: true, 51 [PREF_SYSTEM_LISTS_ENABLED]: true, 52 }, 53 }, 54 }, 55 }; 56 57 info("ListsFeed.onAction INIT should set initialized"); 58 59 await feed.onAction({ 60 type: actionTypes.INIT, 61 }); 62 63 Assert.ok(feed.initialized); 64 }); 65 66 add_task(async function test_isEnabled() { 67 let feed = new ListsFeed(); 68 69 feed.store = { 70 getState() { 71 return this.state; 72 }, 73 dispatch: sinon.spy(), 74 state: { 75 Prefs: { 76 values: { 77 [PREF_LISTS_ENABLED]: true, 78 [PREF_SYSTEM_LISTS_ENABLED]: true, 79 }, 80 }, 81 }, 82 }; 83 84 info("ListsFeed should be enabled via system pref"); 85 Assert.ok(feed.enabled); 86 }); 87 88 add_task(async function test_isEnabled() { 89 let feed = new ListsFeed(); 90 91 feed.store = { 92 getState() { 93 return this.state; 94 }, 95 dispatch: sinon.spy(), 96 state: { 97 Prefs: { 98 values: { 99 [PREF_LISTS_ENABLED]: true, 100 trainhopConfig: { 101 widgets: { 102 enabled: true, 103 listsEnabled: true, 104 timerEnabled: true, 105 }, 106 }, 107 }, 108 }, 109 }, 110 }; 111 112 info("ListsFeed should be enabled via trainhopConfig"); 113 Assert.ok(feed.enabled); 114 }); 115 116 add_task(async function test_isEnabled() { 117 let feed = new ListsFeed(); 118 119 feed.store = { 120 getState() { 121 return this.state; 122 }, 123 dispatch: sinon.spy(), 124 state: { 125 Prefs: { 126 values: { 127 [PREF_LISTS_ENABLED]: true, 128 widgetsConfig: { 129 enabled: true, 130 listsEnabled: true, 131 timerEnabled: true, 132 }, 133 }, 134 }, 135 }, 136 }; 137 138 info("ListsFeed should be enabled via widgetsConfig"); 139 Assert.ok(feed.enabled); 140 }); 141 142 add_task(async function test_syncLists_moves_completed_tasks_and_dispatches() { 143 const feed = new ListsFeed(); 144 145 // create mock data for Persistent Cache 146 const cachedListData = { 147 lists: { 148 myList: { 149 label: "My List", 150 tasks: [ 151 { id: 1, title: "Active task", completed: false }, 152 { id: 2, title: "Completed task", completed: true }, 153 ], 154 }, 155 }, 156 }; 157 158 const dispatchSpy = sinon.spy(); 159 160 feed.store = { 161 getState() { 162 return { 163 Prefs: { 164 values: { 165 [PREF_LISTS_ENABLED]: true, 166 [PREF_SYSTEM_LISTS_ENABLED]: true, 167 }, 168 }, 169 }; 170 }, 171 dispatch: dispatchSpy, 172 }; 173 174 const getStub = sinon.stub(feed.cache, "get").resolves(cachedListData); 175 176 await feed.syncLists(); 177 178 // Check that the tasks have been properly split 179 const [firstCall] = dispatchSpy.getCalls(); 180 const listsData = firstCall.args[0].data; 181 182 Assert.equal(listsData.myList.tasks.length, 1, "1 active task"); 183 Assert.equal(listsData.myList.completed.length, 1, "1 completed task"); 184 185 Assert.equal( 186 firstCall.args[0].type, 187 actionTypes.WIDGETS_LISTS_SET, 188 "dispatches lists" 189 ); 190 191 getStub.restore(); 192 }); 193 194 add_task(async function test_syncLists_errors_when_over_max() { 195 const PREF_WIDGETS_LISTS_MAX_LISTS = "widgets.lists.maxLists"; 196 197 const feed = new ListsFeed(); 198 const dispatchSpy = sinon.spy(); 199 200 // Store state: lists enabled, system lists enabled, max count = 1 201 feed.store = { 202 getState() { 203 return { 204 Prefs: { 205 values: { 206 [PREF_LISTS_ENABLED]: true, 207 [PREF_SYSTEM_LISTS_ENABLED]: true, 208 [PREF_WIDGETS_LISTS_MAX_LISTS]: 1, 209 }, 210 }, 211 }; 212 }, 213 dispatch: dispatchSpy, 214 }; 215 216 // Cached data with 2 lists -> exceeds max (1) 217 const cachedListData = { 218 lists: { 219 listA: { label: "List A", tasks: [], completed: [] }, 220 listB: { label: "List B", tasks: [], completed: [] }, 221 }, 222 }; 223 224 const getStub = sinon.stub(feed.cache, "get").resolves(cachedListData); 225 226 // Expect an error and NO dispatches 227 await Assert.rejects( 228 feed.syncLists(), 229 /Over the maximum list count/, 230 "syncLists should throw when over the maximum list count" 231 ); 232 233 Assert.equal( 234 dispatchSpy.callCount, 235 0, 236 "No dispatch should occur when over the maximum list count" 237 ); 238 239 getStub.restore(); 240 });