/**
 * Copyright 2021 Gravitational, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ import React from 'react' ; import { Router } from 'react-router' ; import { createMemoryHistory } from 'history' ; import renderHook , { act } from 'design/utils/renderHook' ; import { Label , Filter } from 'teleport/types' ; import useUrlFiltering , { Filterable , State } from './useUrlFiltering' ; test ( 'empty data list' , ( ) => { const history = createMemoryHistory ( { initialEntries : [ '/test' ] } ) ; jest . spyOn ( history , 'replace' ) ; let result ; act ( ( ) => { result = renderHook ( ( ) => useUrlFiltering ( [ ] ) , { wrapper : Wrapper , wrapperProps : { history } , } ) ; } ) ; let hook = result . current ; expect ( hook . filters ) . toHaveLength ( 0 ) ; expect ( hook . result ) . toHaveLength ( 0 ) ; } ) ; test ( 'extracting unique labels and making sorted filters from data list' , ( ) => { const label1 = { name : 'name100' , value : 'value100' } ; const label2 = { name : 'name9' , value : 'value9' } ; const label3 = { name : 'name80' , value : 'value90' } ; const label4 = { name : 'name1' , value : 'value1' } ; const label5 = { name : 'name10' , value : 'value10' } ; const data = [ { labels : [ label1 ] } , { labels : [ label1 , label2 ] } , { labels : [ label3 , label4 ] } , { labels : [ label1 , label2 , label3 , label4 ] } , { labels : [ label5 ] } , ] ; const history = createMemoryHistory ( { initialEntries : [ '/test' ] } ) ; let result ; act ( ( ) => { result = renderHook ( ( ) => useUrlFiltering ( data ) , { wrapper : Wrapper , wrapperProps : { history } , } ) ; } ) ; let hook = result . current ; expect ( hook . appliedFilters ) . toHaveLength ( 0 ) ; expect ( hook . result ) . toEqual ( data ) ; expect ( hook . filters ) . toHaveLength ( 5 ) ; expect ( hook . filters . map ( f => f . name ) ) . toEqual ( [ 'name1' , 'name9' , 'name10' , 'name80' , 'name100' , ] ) ; expect ( hook . filters [ 0 ] ) . toMatchObject ( { name : 'name1' , value : 'value1' , kind : 'label' , } ) ; } ) ; test ( 'filtering data' , ( ) => { const filter1 = { name : 'name100' , value : 'value100' , kind : 'label' , } ; const filter2 = { name : 'name9' , value : 'value9' , kind : 'label' , } ; const label1 = { name : 'name100' , value : 'value100' } ; const label2 = { name : 'name9' , value : 'value9' } ; const label3 = { name : 'name80' , value : 'value90' } ; const data = [ { labels : [ label1 ] } , { labels : [ label1 , label2 ] } , { labels : [ label3 ] } , ] ; const history = createMemoryHistory ( { initialEntries : [ '/test' ] } ) ; let result ; act ( ( ) => { result = renderHook ( ( ) => useUrlFiltering ( data ) , { wrapper : Wrapper , wrapperProps : { history } , } ) ; } ) ; let hook = result . current ; expect ( hook . appliedFilters ) . toHaveLength ( 0 ) ; expect ( hook . filters ) . toHaveLength ( 3 ) ; expect ( hook . result ) . toEqual ( data ) ; act ( ( ) => hook . applyFilters ( [ filter1 ] ) ) ; hook = result . current ; expect ( hook . result ) . toHaveLength ( 2 ) ; expect ( hook . result [ 0 ] . labels ) . toContainEqual ( label1 ) ; expect ( hook . result [ 1 ] . labels ) . toContainEqual ( label1 ) ; act ( ( ) => hook . toggleFilter ( filter2 ) ) ; hook = result . current ; expect ( hook . result ) . toHaveLength ( 1 ) ; expect ( hook . result [ 0 ] . labels ) . toEqual ( expect . arrayContaining ( [ label1 , label2 ] ) ) ; act ( ( ) => hook . applyFilters ( [ ] ) ) ; hook = result . current ; expect ( hook . result ) . toEqual ( data ) ; } ) ; function Wrapper ( props ) { return < Router history = { props . history } > { props . children } < /Router>; }