build: Use eslint-config-wikimedia v0.9.0 and make pass
[lhc/web/wiklou.git] / tests / qunit / suites / resources / mediawiki.widgets / MediaSearch / mediawiki.widgets.APIResultsQueue.test.js
1 /*!
2 * VisualEditor DataModel ResourceQueue tests.
3 *
4 * @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org
5 */
6
7 QUnit.module( 'mediawiki.widgets.APIResultsQueue' );
8
9 ( function () {
10 var itemCounter, FullResourceProvider, EmptyResourceProvider, SingleResultResourceProvider;
11
12 itemCounter = 0;
13 FullResourceProvider = function ( config ) {
14 this.timer = null;
15 this.responseDelay = 1;
16 // Inheritance
17 FullResourceProvider.super.call( this, '', config );
18 };
19 EmptyResourceProvider = function ( config ) {
20 this.timer = null;
21 this.responseDelay = 1;
22 // Inheritance
23 EmptyResourceProvider.super.call( this, '', config );
24 };
25 SingleResultResourceProvider = function ( config ) {
26 this.timer = null;
27 this.responseDelay = 1;
28 // Inheritance
29 SingleResultResourceProvider.super.call( this, '', config );
30 };
31
32 OO.inheritClass( FullResourceProvider, mw.widgets.APIResultsProvider );
33 OO.inheritClass( EmptyResourceProvider, mw.widgets.APIResultsProvider );
34 OO.inheritClass( SingleResultResourceProvider, mw.widgets.APIResultsProvider );
35
36 FullResourceProvider.prototype.getResults = function ( howMany ) {
37 var i, timer,
38 result = [],
39 deferred = $.Deferred();
40
41 for ( i = itemCounter; i < itemCounter + howMany; i++ ) {
42 result.push( 'result ' + ( i + 1 ) );
43 }
44 itemCounter = i;
45
46 timer = setTimeout(
47 function () {
48 // Always resolve with some values
49 deferred.resolve( result );
50 },
51 this.responseDelay );
52
53 return deferred.promise( { abort: function () {
54 clearTimeout( timer );
55 } } );
56 };
57
58 EmptyResourceProvider.prototype.getResults = function () {
59 var provider = this,
60 deferred = $.Deferred(),
61 timer = setTimeout(
62 function () {
63 provider.toggleDepleted( true );
64 // Always resolve with empty value
65 deferred.resolve( [] );
66 },
67 this.responseDelay );
68
69 return deferred.promise( { abort: function () {
70 clearTimeout( timer );
71 } } );
72 };
73
74 SingleResultResourceProvider.prototype.getResults = function ( howMany ) {
75 var timer,
76 provider = this,
77 deferred = $.Deferred();
78
79 timer = setTimeout(
80 function () {
81 provider.toggleDepleted( howMany > 1 );
82 // Always resolve with one value
83 deferred.resolve( [ 'one result (' + ( itemCounter++ + 1 ) + ')' ] );
84 },
85 this.responseDelay );
86
87 return deferred.promise( { abort: function () {
88 clearTimeout( timer );
89 } } );
90 };
91
92 /* Tests */
93
94 QUnit.test( 'Query providers', function ( assert ) {
95 var done = assert.async(),
96 providers = [
97 new FullResourceProvider(),
98 new EmptyResourceProvider(),
99 new SingleResultResourceProvider()
100 ],
101 queue = new mw.widgets.APIResultsQueue( {
102 threshold: 2
103 } );
104
105 assert.expect( 15 );
106
107 // Add providers to queue
108 queue.setProviders( providers );
109
110 // Set parameters and fetch
111 queue.setParams( { foo: 'bar' } );
112
113 queue.get( 10 )
114 .then( function ( data ) {
115 // Check that we received all requested results
116 assert.strictEqual( data.length, 10, 'Query 1: Results received.' );
117 // We've asked for 10 items + 2 threshold from all providers.
118 // Provider 1 returned 12 results
119 // Provider 2 returned 0 results
120 // Provider 3 returned 1 results
121 // Overall 13 results. 10 were retrieved. 3 left in queue.
122 assert.strictEqual( queue.getQueueSize(), 3, 'Query 1: Remaining queue size.' );
123
124 // Check if sources are depleted
125 assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 1: Full provider not depleted.' );
126 assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 1: Empty provider is depleted.' );
127 assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 1: Single result provider is depleted.' );
128
129 // Ask for more results
130 return queue.get( 10 );
131 } )
132 .then( function ( data1 ) {
133 // This time, only provider 1 was queried, because the other
134 // two were marked as depleted.
135 // * We asked for 10 items
136 // * There are currently 3 items in the queue
137 // * The queue queried provider #1 for 12 items
138 // * The queue returned 10 results as requested
139 // * 5 results are now left in the queue.
140 assert.strictEqual( data1.length, 10, 'Query 1: Second set of results received.' );
141 assert.strictEqual( queue.getQueueSize(), 5, 'Query 1: Remaining queue size.' );
142
143 // Change the query
144 queue.setParams( { foo: 'baz' } );
145 // Check if sources are depleted
146 assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
147 assert.strictEqual( providers[ 1 ].isDepleted(), false, 'Query 2: Empty provider not depleted.' );
148 assert.strictEqual( providers[ 2 ].isDepleted(), false, 'Query 2: Single result provider not depleted.' );
149
150 return queue.get( 10 );
151 } )
152 .then( function ( data2 ) {
153 // This should be the same as the very first result
154 assert.strictEqual( data2.length, 10, 'Query 2: Results received.' );
155 assert.strictEqual( queue.getQueueSize(), 3, 'Query 2: Remaining queue size.' );
156 // Check if sources are depleted
157 assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
158 assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 2: Empty provider is not depleted.' );
159 assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 2: Single result provider is not depleted.' );
160 } )
161 // Finish the async test
162 .then( done );
163 } );
164
165 QUnit.test( 'Abort providers', function ( assert ) {
166 var done = assert.async(),
167 completed = false,
168 biggerQueue = new mw.widgets.APIResultsQueue( {
169 threshold: 5
170 } ),
171 providers = [
172 new FullResourceProvider(),
173 new EmptyResourceProvider(),
174 new SingleResultResourceProvider()
175 ];
176
177 assert.expect( 1 );
178
179 // Make the delay higher
180 providers.forEach( function ( provider ) {
181 provider.responseDelay = 3;
182 } );
183
184 // Add providers to queue
185 biggerQueue.setProviders( providers );
186
187 biggerQueue.setParams( { foo: 'bar' } );
188 biggerQueue.get( 100 )
189 .always( function () {
190 // This should only run if the promise wasn't aborted
191 completed = true;
192 } );
193
194 // Make the delay higher
195 providers.forEach( function ( provider ) {
196 provider.responseDelay = 5;
197 } );
198
199 biggerQueue.setParams( { foo: 'baz' } );
200 biggerQueue.get( 10 )
201 .then( function () {
202 assert.strictEqual( completed, false, 'Provider promises aborted.' );
203 } )
204 // Finish the async test
205 .then( done );
206 } );
207 }() );