test_ExternalComponentsFeed.js (4210B)
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 ExternalComponentsFeed: 8 "resource://newtab/lib/ExternalComponentsFeed.sys.mjs", 9 actionTypes: "resource://newtab/common/Actions.mjs", 10 actionCreators: "resource://newtab/common/Actions.mjs", 11 sinon: "resource://testing-common/Sinon.sys.mjs", 12 }); 13 14 /** 15 * Tests that ExternalComponentsFeed can be constructed successfully. 16 */ 17 add_task(async function test_construction() { 18 info("ExternalComponentsFeed should construct with registry"); 19 20 const feed = new ExternalComponentsFeed(); 21 22 Assert.ok(feed, "Could construct an ExternalComponentsFeed"); 23 }); 24 25 /** 26 * Tests that the INIT action triggers refreshComponents to be called with isStartup flag. 27 */ 28 add_task(async function test_onAction_INIT_dispatches_refresh() { 29 info( 30 "ExternalComponentsFeed.onAction INIT should refresh components with isStartup" 31 ); 32 33 const feed = new ExternalComponentsFeed(); 34 const dispatchSpy = sinon.spy(); 35 36 feed.store = { 37 dispatch: dispatchSpy, 38 }; 39 40 sinon.stub(feed, "refreshComponents"); 41 42 await feed.onAction({ 43 type: actionTypes.INIT, 44 }); 45 46 Assert.ok( 47 feed.refreshComponents.calledOnce, 48 "refreshComponents should be called on INIT" 49 ); 50 51 Assert.ok( 52 feed.refreshComponents.calledWith({ isStartup: true }), 53 "refreshComponents should be called with isStartup: true" 54 ); 55 56 feed.refreshComponents.restore(); 57 }); 58 59 /** 60 * Tests that refreshComponents dispatches a REFRESH_EXTERNAL_COMPONENTS action 61 * with the correct structure and routing metadata. 62 */ 63 add_task(async function test_refreshComponents_dispatches_action() { 64 info("ExternalComponentsFeed.refreshComponents should dispatch broadcast"); 65 66 const feed = new ExternalComponentsFeed(); 67 const dispatchSpy = sinon.spy(); 68 69 feed.store = { 70 dispatch: dispatchSpy, 71 }; 72 73 feed.refreshComponents(); 74 75 Assert.ok(dispatchSpy.calledOnce, "dispatch should be called"); 76 77 const [action] = dispatchSpy.firstCall.args; 78 Assert.equal(action.type, actionTypes.REFRESH_EXTERNAL_COMPONENTS); 79 Assert.ok(Array.isArray(action.data), "data should be an array"); 80 }); 81 82 /** 83 * Tests that the dispatched action includes component data as an array. 84 */ 85 add_task(async function test_refreshComponents_includes_registry_values() { 86 info( 87 "ExternalComponentsFeed.refreshComponents should include all components" 88 ); 89 90 const feed = new ExternalComponentsFeed(); 91 const dispatchSpy = sinon.spy(); 92 93 feed.store = { 94 dispatch: dispatchSpy, 95 }; 96 97 feed.refreshComponents(); 98 99 Assert.ok(dispatchSpy.calledOnce, "dispatch should be called"); 100 101 const [action] = dispatchSpy.firstCall.args; 102 Assert.ok( 103 Array.isArray(action.data), 104 "Dispatched data should be an array of components" 105 ); 106 }); 107 108 /** 109 * Tests that refreshComponents marks the action as a startup action when isStartup is true. 110 */ 111 add_task(async function test_refreshComponents_marks_startup_action() { 112 info( 113 "ExternalComponentsFeed.refreshComponents should mark action as startup when isStartup is true" 114 ); 115 116 const feed = new ExternalComponentsFeed(); 117 const dispatchSpy = sinon.spy(); 118 119 feed.store = { 120 dispatch: dispatchSpy, 121 }; 122 123 feed.refreshComponents({ isStartup: true }); 124 125 Assert.ok(dispatchSpy.calledOnce, "dispatch should be called"); 126 127 const [action] = dispatchSpy.firstCall.args; 128 Assert.equal( 129 action.meta?.isStartup, 130 true, 131 "Action should have meta.isStartup set to true" 132 ); 133 }); 134 135 /** 136 * Tests that refreshComponents does not mark the action as startup when isStartup is false or not provided. 137 */ 138 add_task(async function test_refreshComponents_non_startup_action() { 139 info( 140 "ExternalComponentsFeed.refreshComponents should not mark action as startup by default" 141 ); 142 143 const feed = new ExternalComponentsFeed(); 144 const dispatchSpy = sinon.spy(); 145 146 feed.store = { 147 dispatch: dispatchSpy, 148 }; 149 150 feed.refreshComponents(); 151 152 Assert.ok(dispatchSpy.calledOnce, "dispatch should be called"); 153 154 const [action] = dispatchSpy.firstCall.args; 155 Assert.ok( 156 !action.meta?.isStartup, 157 "Action should not have meta.isStartup set" 158 ); 159 });