77 waitFor ,
88 userEvent ,
99} from '@mongodb-js/testing-library-compass' ;
10- import { OptionEditor } from './option-editor' ;
10+ import { OptionEditor , getOptionBasedQueries } from './option-editor' ;
1111import type { SinonSpy } from 'sinon' ;
1212import { applyFromHistory } from '../stores/query-bar-reducer' ;
1313import sinon from 'sinon' ;
@@ -47,7 +47,8 @@ describe('OptionEditor', function () {
4747 insertEmptyDocOnFocus
4848 onChange = { ( ) => { } }
4949 value = ""
50- savedQueries = { [ ] }
50+ recentQueries = { [ ] }
51+ favoriteQueries = { [ ] }
5152 onApplyQuery = { applyFromHistory }
5253 > </ OptionEditor >
5354 ) ;
@@ -69,7 +70,8 @@ describe('OptionEditor', function () {
6970 insertEmptyDocOnFocus
7071 onChange = { ( ) => { } }
7172 value = "{ foo: 1 }"
72- savedQueries = { [ ] }
73+ recentQueries = { [ ] }
74+ favoriteQueries = { [ ] }
7375 onApplyQuery = { applyFromHistory }
7476 > </ OptionEditor >
7577 ) ;
@@ -91,7 +93,8 @@ describe('OptionEditor', function () {
9193 insertEmptyDocOnFocus
9294 onChange = { ( ) => { } }
9395 value = ""
94- savedQueries = { [ ] }
96+ favoriteQueries = { [ ] }
97+ recentQueries = { [ ] }
9598 onApplyQuery = { applyFromHistory }
9699 > </ OptionEditor >
97100 ) ;
@@ -119,7 +122,8 @@ describe('OptionEditor', function () {
119122 insertEmptyDocOnFocus
120123 onChange = { ( ) => { } }
121124 value = ""
122- savedQueries = { [ ] }
125+ favoriteQueries = { [ ] }
126+ recentQueries = { [ ] }
123127 onApplyQuery = { applyFromHistory }
124128 > </ OptionEditor >
125129 ) ;
@@ -149,7 +153,8 @@ describe('OptionEditor', function () {
149153 insertEmptyDocOnFocus
150154 onChange = { ( ) => { } }
151155 value = ""
152- savedQueries = { [ ] }
156+ favoriteQueries = { [ ] }
157+ recentQueries = { [ ] }
153158 onApplyQuery = { applyFromHistory }
154159 > </ OptionEditor >
155160 ) ;
@@ -167,7 +172,7 @@ describe('OptionEditor', function () {
167172 } ) ;
168173 } ) ;
169174
170- describe ( 'when render filter bar with the query history autocompleter ' , function ( ) {
175+ describe ( 'when rendering filter option ' , function ( ) {
171176 let onApplySpy : SinonSpy ;
172177 let preferencesAccess : PreferencesAccess ;
173178
@@ -182,64 +187,54 @@ describe('OptionEditor', function () {
182187 insertEmptyDocOnFocus
183188 onChange = { ( ) => { } }
184189 value = ""
185- savedQueries = { [
190+ recentQueries = { [
186191 {
187- type : 'recent' ,
188- lastExecuted : new Date ( ) ,
189- queryProperties : {
190- filter : { a : 1 } ,
191- } ,
192- } ,
193- {
194- type : 'favorite' ,
195- lastExecuted : new Date ( ) ,
196- queryProperties : {
197- filter : { a : 2 } ,
198- sort : { a : - 1 } ,
199- } ,
192+ _lastExecuted : new Date ( ) ,
193+ filter : { a : 1 } ,
200194 } ,
195+ ] }
196+ favoriteQueries = { [
201197 {
202- type : 'recent' ,
203- lastExecuted : new Date ( ) ,
204- queryProperties : {
205- filter : { a : 2 } ,
206- sort : { a : - 1 } ,
207- update : { a : 10 } ,
208- } ,
198+ _lastExecuted : new Date ( ) ,
199+ filter : { a : 2 } ,
200+ sort : { a : - 1 } ,
209201 } ,
210202 ] }
211203 onApplyQuery = { onApplySpy }
212204 />
213205 </ PreferencesProvider >
214206 ) ;
207+ userEvent . click ( screen . getByRole ( 'textbox' ) ) ;
208+ await waitFor ( ( ) => {
209+ screen . getByLabelText ( 'Completions' ) ;
210+ } ) ;
215211 } ) ;
216212
217213 afterEach ( function ( ) {
218214 cleanup ( ) ;
219215 } ) ;
220216
221- it ( 'filter applied correctly when autocomplete option is clicked' , async function ( ) {
222- userEvent . click ( screen . getByRole ( 'textbox' ) ) ;
223- await waitFor ( ( ) => {
224- expect ( screen . getAllByText ( '{ a: 1 }' ) [ 0 ] ) . to . be . visible ;
225- expect ( screen . getByText ( '{ a: 2 }, sort: { a: -1 }' ) ) . to . be . visible ;
226- expect (
227- screen . queryByText ( '{ a: 2 }, sort: { a: -1 }, update: { a: 10 }' )
228- ) . to . be . null ;
229- } ) ;
217+ it ( 'renders autocomplete options' , function ( ) {
218+ expect ( screen . getAllByText ( '{ a: 1 }' ) [ 0 ] ) . to . be . visible ;
219+ expect ( screen . getByText ( '{ a: 2 }, sort: { a: -1 }' ) ) . to . be . visible ;
220+ } ) ;
230221
222+ it ( 'calls onApply with correct params' , async function ( ) {
231223 // Simulate selecting the autocomplete option
232224 userEvent . click ( screen . getByText ( '{ a: 2 }, sort: { a: -1 }' ) ) ;
233225 await waitFor ( ( ) => {
234- expect ( onApplySpy . lastCall ) . to . be . calledWithExactly ( {
235- filter : { a : 2 } ,
236- sort : { a : - 1 } ,
237- } ) ;
226+ expect ( onApplySpy . lastCall ) . to . be . calledWithExactly (
227+ {
228+ filter : { a : 2 } ,
229+ sort : { a : - 1 } ,
230+ } ,
231+ [ ]
232+ ) ;
238233 } ) ;
239234 } ) ;
240235 } ) ;
241236
242- describe ( 'when render project bar with the query history autocompleter ' , function ( ) {
237+ describe ( 'when rendering project option ' , function ( ) {
243238 let onApplySpy : SinonSpy ;
244239 let preferencesAccess : PreferencesAccess ;
245240
@@ -254,62 +249,124 @@ describe('OptionEditor', function () {
254249 insertEmptyDocOnFocus
255250 onChange = { ( ) => { } }
256251 value = ""
257- savedQueries = { [
258- {
259- type : 'favorite' ,
260- lastExecuted : new Date ( ) ,
261- queryProperties : {
262- project : { a : 1 } ,
263- } ,
264- } ,
252+ favoriteQueries = { [
265253 {
266- type : 'favorite' ,
267- lastExecuted : new Date ( ) ,
268- queryProperties : {
269- filter : { a : 2 } ,
270- sort : { a : - 1 } ,
271- } ,
254+ _lastExecuted : new Date ( ) ,
255+ project : { a : 1 } ,
272256 } ,
257+ ] }
258+ recentQueries = { [
273259 {
274- type : 'recent' ,
275- lastExecuted : new Date ( ) ,
276- queryProperties : {
277- filter : { a : 2 } ,
278- sort : { a : - 1 } ,
279- project : { a : 0 } ,
280- } ,
260+ _lastExecuted : new Date ( ) ,
261+ project : { a : 0 } ,
281262 } ,
282263 ] }
283264 onApplyQuery = { onApplySpy }
284265 />
285266 </ PreferencesProvider >
286267 ) ;
268+ userEvent . click ( screen . getByRole ( 'textbox' ) ) ;
269+ await waitFor ( ( ) => {
270+ screen . getByLabelText ( 'Completions' ) ;
271+ } ) ;
287272 } ) ;
288273
289274 afterEach ( function ( ) {
290275 cleanup ( ) ;
291276 } ) ;
292277
293- it ( 'only queries with project property are shown in project editor' , async function ( ) {
294- userEvent . click ( screen . getByRole ( 'textbox' ) ) ;
295- await waitFor ( ( ) => {
296- expect ( screen . getAllByText ( 'project: { a: 1 }' ) [ 0 ] ) . to . be . visible ;
297- expect ( screen . queryByText ( '{ a: 2 }, sort: { a: -1 }' ) ) . to . be . null ;
298- expect ( screen . getByText ( '{ a: 2 }, sort: { a: -1 }, project: { a: 0 }' ) )
299- . to . be . visible ;
300- } ) ;
278+ it ( 'renders autocomplete options' , function ( ) {
279+ expect ( screen . getAllByText ( 'project: { a: 1 }' ) [ 0 ] ) . to . be . visible ;
280+ expect ( screen . getAllByText ( 'project: { a: 0 }' ) [ 0 ] ) . to . be . visible ;
281+ } ) ;
301282
283+ it ( 'calls onApply with correct params' , async function ( ) {
302284 // Simulate selecting the autocomplete option
303- userEvent . click (
304- screen . getByText ( '{ a: 2 }, sort: { a: -1 }, project: { a: 0 }' )
305- ) ;
285+ userEvent . click ( screen . getByText ( 'project: { a: 0 }' ) ) ;
306286 await waitFor ( ( ) => {
307- expect ( onApplySpy . lastCall ) . to . be . calledWithExactly ( {
308- filter : { a : 2 } ,
309- sort : { a : - 1 } ,
310- project : { a : 0 } ,
311- } ) ;
287+ expect ( onApplySpy ) . to . have . been . calledOnceWithExactly (
288+ {
289+ project : { a : 0 } ,
290+ } ,
291+ [ 'filter' , 'collation' , 'sort' , 'hint' , 'skip' , 'limit' , 'maxTimeMS' ]
292+ ) ;
312293 } ) ;
313294 } ) ;
314295 } ) ;
296+
297+ describe ( 'getOptionBasedQueries' , function ( ) {
298+ const savedQueries = [
299+ {
300+ _lastExecuted : new Date ( ) ,
301+ filter : { a : 1 } ,
302+ project : { b : 1 } ,
303+ sort : { c : 1 } ,
304+ collation : { locale : 'en' } ,
305+ hint : { a : 1 } ,
306+ skip : 1 ,
307+ limit : 1 ,
308+ } ,
309+ ] ;
310+
311+ it ( 'filters out update queries' , function ( ) {
312+ const queries = getOptionBasedQueries ( 'filter' , 'recent' , [
313+ ...savedQueries ,
314+ { _lastExecuted : new Date ( ) , update : { a : 1 } , filter : { a : 2 } } ,
315+ ] ) ;
316+ expect ( queries . length ) . to . equal ( 1 ) ;
317+ } ) ;
318+
319+ it ( 'filters out empty queries' , function ( ) {
320+ const queries = getOptionBasedQueries ( 'filter' , 'recent' , [
321+ ...savedQueries ,
322+ { _lastExecuted : new Date ( ) } ,
323+ ] ) ;
324+ expect ( queries . length ) . to . equal ( 1 ) ;
325+ } ) ;
326+
327+ it ( 'filters out duplicate queries' , function ( ) {
328+ const queries = getOptionBasedQueries ( 'filter' , 'recent' , [
329+ ...savedQueries ,
330+ ...savedQueries ,
331+ ...savedQueries ,
332+ { _lastExecuted : new Date ( ) } ,
333+ { _lastExecuted : new Date ( ) } ,
334+ ] ) ;
335+ expect ( queries . length ) . to . equal ( 1 ) ;
336+ } ) ;
337+
338+ const optionNames = [
339+ 'filter' ,
340+ 'project' ,
341+ 'sort' ,
342+ 'collation' ,
343+ 'hint' ,
344+ ] as const ;
345+ for ( const name of optionNames ) {
346+ it ( `maps query for ${ name } ` , function ( ) {
347+ const queries = getOptionBasedQueries ( name , 'recent' , savedQueries ) ;
348+
349+ // For filter, we include all the query properties and for the rest
350+ // we only include that specific option.
351+ const queryProperties =
352+ name === 'filter'
353+ ? Object . fromEntries (
354+ Object . entries ( savedQueries [ 0 ] ) . filter (
355+ ( [ key ] ) => key !== '_lastExecuted'
356+ )
357+ )
358+ : {
359+ [ name ] : savedQueries [ 0 ] [ name ] ,
360+ } ;
361+
362+ expect ( queries ) . to . deep . equal ( [
363+ {
364+ lastExecuted : savedQueries [ 0 ] . _lastExecuted ,
365+ queryProperties,
366+ type : 'recent' ,
367+ } ,
368+ ] ) ;
369+ } ) ;
370+ }
371+ } ) ;
315372} ) ;
0 commit comments