2022-03-14 19:02:01 +00:00
|
|
|
import { createConnection, Repository, In, Connection } from 'typeorm'
|
2021-11-16 17:49:13 +00:00
|
|
|
import {
|
|
|
|
Paginated,
|
|
|
|
paginate,
|
|
|
|
PaginateConfig,
|
|
|
|
FilterOperator,
|
|
|
|
isOperator,
|
|
|
|
getFilterTokens,
|
2022-01-27 21:12:52 +00:00
|
|
|
OperatorSymbolToFunction,
|
2022-03-14 17:48:56 +00:00
|
|
|
} from './paginate'
|
|
|
|
import { PaginateQuery } from './decorator'
|
2020-06-26 21:25:03 +00:00
|
|
|
import { HttpException } from '@nestjs/common'
|
2022-03-14 17:48:56 +00:00
|
|
|
import { CatEntity } from './__tests__/cat.entity'
|
|
|
|
import { CatToyEntity } from './__tests__/cat-toy.entity'
|
|
|
|
import { CatHomeEntity } from './__tests__/cat-home.entity'
|
2022-03-14 19:02:01 +00:00
|
|
|
import { clone } from 'lodash'
|
2020-06-26 21:25:03 +00:00
|
|
|
|
|
|
|
describe('paginate', () => {
|
2022-02-06 18:52:38 +00:00
|
|
|
let connection: Connection
|
2022-03-14 19:02:01 +00:00
|
|
|
let catRepo: Repository<CatEntity>
|
|
|
|
let catToyRepo: Repository<CatToyEntity>
|
|
|
|
let catHomeRepo: Repository<CatHomeEntity>
|
2020-06-28 17:34:00 +00:00
|
|
|
let cats: CatEntity[]
|
2022-03-14 19:02:01 +00:00
|
|
|
let catToys: CatToyEntity[]
|
|
|
|
let catHomes: CatHomeEntity[]
|
2020-06-26 21:25:03 +00:00
|
|
|
|
|
|
|
beforeAll(async () => {
|
2022-02-06 18:52:38 +00:00
|
|
|
connection = await createConnection({
|
2020-06-26 21:25:03 +00:00
|
|
|
type: 'sqlite',
|
|
|
|
database: ':memory:',
|
|
|
|
synchronize: true,
|
|
|
|
logging: false,
|
2022-03-14 19:02:01 +00:00
|
|
|
entities: [CatEntity, CatToyEntity, CatHomeEntity],
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|
2022-03-14 19:02:01 +00:00
|
|
|
catRepo = connection.getRepository(CatEntity)
|
|
|
|
catToyRepo = connection.getRepository(CatToyEntity)
|
|
|
|
catHomeRepo = connection.getRepository(CatHomeEntity)
|
|
|
|
cats = await catRepo.save([
|
2022-05-14 18:18:00 +00:00
|
|
|
catRepo.create({ name: 'Milo', color: 'brown', age: 6 }),
|
|
|
|
catRepo.create({ name: 'Garfield', color: 'ginger', age: 5 }),
|
2022-03-14 19:02:01 +00:00
|
|
|
catRepo.create({ name: 'Shadow', color: 'black', age: 4 }),
|
|
|
|
catRepo.create({ name: 'George', color: 'white', age: 3 }),
|
|
|
|
catRepo.create({ name: 'Leche', color: 'white', age: null }),
|
|
|
|
])
|
|
|
|
catToys = await catToyRepo.save([
|
|
|
|
catToyRepo.create({ name: 'Fuzzy Thing', cat: cats[0] }),
|
|
|
|
catToyRepo.create({ name: 'Stuffed Mouse', cat: cats[0] }),
|
|
|
|
catToyRepo.create({ name: 'Mouse', cat: cats[0] }),
|
|
|
|
catToyRepo.create({ name: 'String', cat: cats[1] }),
|
|
|
|
])
|
|
|
|
catHomes = await catHomeRepo.save([
|
|
|
|
catHomeRepo.create({ name: 'Box', cat: cats[0] }),
|
|
|
|
catHomeRepo.create({ name: 'House', cat: cats[1] }),
|
2020-06-28 17:34:00 +00:00
|
|
|
])
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should return an instance of Paginated', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
2021-08-19 14:42:18 +00:00
|
|
|
defaultSortBy: [['id', 'ASC']],
|
2020-06-26 21:25:03 +00:00
|
|
|
defaultLimit: 1,
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-26 21:25:03 +00:00
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
expect(result).toBeInstanceOf(Paginated)
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(0, 1))
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|
|
|
|
|
2022-02-06 18:52:38 +00:00
|
|
|
it('should accept a query builder', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
defaultSortBy: [['id', 'ASC']],
|
|
|
|
defaultLimit: 1,
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const queryBuilder = await catRepo.createQueryBuilder('cats')
|
2022-02-06 18:52:38 +00:00
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, queryBuilder, config)
|
|
|
|
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(0, 1))
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should accept a query builder with custom condition', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
defaultSortBy: [['id', 'ASC']],
|
|
|
|
defaultLimit: 1,
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const queryBuilder = await connection
|
|
|
|
.createQueryBuilder()
|
|
|
|
.select('cats')
|
|
|
|
.from(CatEntity, 'cats')
|
|
|
|
.where('cats.color = :color', { color: 'white' })
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, queryBuilder, config)
|
|
|
|
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(3, 4))
|
|
|
|
})
|
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
it('should default to page 1, if negative page is given', async () => {
|
2020-06-26 21:25:03 +00:00
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
2020-06-28 17:34:00 +00:00
|
|
|
defaultLimit: 1,
|
2020-06-26 21:25:03 +00:00
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
2020-06-28 17:34:00 +00:00
|
|
|
page: -1,
|
2020-06-26 21:25:03 +00:00
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-26 21:25:03 +00:00
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
expect(result.meta.currentPage).toBe(1)
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(0, 1))
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|
|
|
|
|
2021-03-04 12:29:53 +00:00
|
|
|
it('should default to limit maxLimit, if more than maxLimit is given', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
defaultLimit: 5,
|
2021-08-19 11:30:06 +00:00
|
|
|
maxLimit: 2,
|
2021-03-04 12:29:53 +00:00
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
page: 1,
|
|
|
|
limit: 20,
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-03-04 12:29:53 +00:00
|
|
|
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(0, 2))
|
|
|
|
})
|
|
|
|
|
2022-02-10 18:21:59 +00:00
|
|
|
it('should return correct links for some results', async () => {
|
2020-06-26 21:25:03 +00:00
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
page: 2,
|
|
|
|
limit: 2,
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const { links } = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-26 21:25:03 +00:00
|
|
|
|
|
|
|
expect(links.first).toBe('?page=1&limit=2&sortBy=id:ASC')
|
|
|
|
expect(links.previous).toBe('?page=1&limit=2&sortBy=id:ASC')
|
|
|
|
expect(links.current).toBe('?page=2&limit=2&sortBy=id:ASC')
|
|
|
|
expect(links.next).toBe('?page=3&limit=2&sortBy=id:ASC')
|
|
|
|
expect(links.last).toBe('?page=3&limit=2&sortBy=id:ASC')
|
|
|
|
})
|
|
|
|
|
2022-02-10 18:21:59 +00:00
|
|
|
it('should return only current link if zero results', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
searchableColumns: ['name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
page: 1,
|
|
|
|
limit: 2,
|
|
|
|
search: 'Pluto',
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const { links } = await paginate<CatEntity>(query, catRepo, config)
|
2022-02-10 18:21:59 +00:00
|
|
|
|
|
|
|
expect(links.first).toBe(undefined)
|
|
|
|
expect(links.previous).toBe(undefined)
|
|
|
|
expect(links.current).toBe('?page=1&limit=2&sortBy=id:ASC&search=Pluto')
|
|
|
|
expect(links.next).toBe(undefined)
|
|
|
|
expect(links.last).toBe(undefined)
|
|
|
|
})
|
|
|
|
|
2020-06-27 18:54:14 +00:00
|
|
|
it('should default to defaultSortBy if query sortBy does not exist', async () => {
|
2020-06-26 21:25:03 +00:00
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id', 'createdAt'],
|
2020-06-28 17:34:00 +00:00
|
|
|
defaultSortBy: [['id', 'DESC']],
|
2020-06-26 21:25:03 +00:00
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-26 21:25:03 +00:00
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
expect(result.meta.sortBy).toStrictEqual([['id', 'DESC']])
|
|
|
|
expect(result.data).toStrictEqual(cats.slice(0).reverse())
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|
|
|
|
|
2022-08-20 22:25:48 +00:00
|
|
|
it('should put null values last when sorting', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['age', 'createdAt'],
|
|
|
|
nullSort: 'last',
|
2022-08-22 13:46:23 +00:00
|
|
|
defaultSortBy: [['age', 'ASC']],
|
2022-08-20 22:25:48 +00:00
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2022-08-22 13:46:23 +00:00
|
|
|
const expectedResult = [...cats.slice(0, -1).reverse(), cats.slice(-1)[0]]
|
2022-08-20 22:25:48 +00:00
|
|
|
|
2022-08-22 13:46:23 +00:00
|
|
|
expect(result.meta.sortBy).toStrictEqual([['age', 'ASC']])
|
|
|
|
expect(result.data).toStrictEqual(expectedResult)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should put null values first when sorting', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['age', 'createdAt'],
|
|
|
|
nullSort: 'first',
|
|
|
|
defaultSortBy: [['age', 'ASC']],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
const expectedResult = [cats[cats.length - 1], ...cats.slice(0, cats.length - 1).reverse()]
|
|
|
|
|
|
|
|
expect(result.meta.sortBy).toStrictEqual([['age', 'ASC']])
|
|
|
|
expect(result.data).toStrictEqual(expectedResult)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should put null values first when nullSort is not specified', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['age', 'createdAt'],
|
|
|
|
defaultSortBy: [['age', 'ASC']],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
const expectedCats = cats.slice()
|
|
|
|
|
|
|
|
expect(result.meta.sortBy).toStrictEqual([['age', 'ASC']])
|
|
|
|
expect(result.data).toStrictEqual(expectedCats.reverse())
|
2022-08-20 22:25:48 +00:00
|
|
|
})
|
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
it('should sort result by multiple columns', async () => {
|
2020-06-27 18:54:14 +00:00
|
|
|
const config: PaginateConfig<CatEntity> = {
|
2020-06-28 17:34:00 +00:00
|
|
|
sortableColumns: ['name', 'color'],
|
2020-06-27 18:54:14 +00:00
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
sortBy: [
|
2020-06-28 17:34:00 +00:00
|
|
|
['color', 'DESC'],
|
|
|
|
['name', 'ASC'],
|
2020-06-27 18:54:14 +00:00
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-27 18:54:14 +00:00
|
|
|
|
2020-06-28 17:34:00 +00:00
|
|
|
expect(result.meta.sortBy).toStrictEqual([
|
|
|
|
['color', 'DESC'],
|
|
|
|
['name', 'ASC'],
|
2020-06-27 18:54:14 +00:00
|
|
|
])
|
2020-06-28 17:34:00 +00:00
|
|
|
expect(result.data).toStrictEqual([cats[3], cats[4], cats[1], cats[0], cats[2]])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on search term', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id', 'name', 'color'],
|
|
|
|
searchableColumns: ['name', 'color'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: 'i',
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2020-06-28 17:34:00 +00:00
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('i')
|
|
|
|
expect(result.data).toStrictEqual([cats[0], cats[1], cats[3], cats[4]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=i')
|
2020-06-27 18:54:14 +00:00
|
|
|
})
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
it('should return result based on search term on many-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatToyEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
searchableColumns: ['name', 'cat.name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: 'Milo',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatToyEntity>(query, catToyRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('Milo')
|
|
|
|
expect(result.data).toStrictEqual([catToys[0], catToys[1], catToys[2]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=Milo')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on search term on one-to-many relation', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
relations: ['toys'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
searchableColumns: ['name', 'toys.name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: 'Mouse',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('Mouse')
|
|
|
|
const toy = clone(catToys[1])
|
|
|
|
delete toy.cat
|
|
|
|
const toy2 = clone(catToys[2])
|
|
|
|
delete toy2.cat
|
|
|
|
expect(result.data).toStrictEqual([Object.assign(clone(cats[0]), { toys: [toy, toy2] })])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=Mouse')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on search term on one-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatHomeEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name', 'cat.id'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
sortBy: [['cat.id', 'DESC']],
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatHomeEntity>(query, catHomeRepo, config)
|
|
|
|
expect(result.meta.sortBy).toStrictEqual([['cat.id', 'DESC']])
|
|
|
|
expect(result.data).toStrictEqual([catHomes[0], catHomes[1]].sort((a, b) => b.cat.id - a.cat.id))
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=cat.id:DESC')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on sort and search on many-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatToyEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name', 'cat.id'],
|
|
|
|
searchableColumns: ['name', 'cat.name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
sortBy: [['cat.id', 'DESC']],
|
|
|
|
search: 'Milo',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatToyEntity>(query, catToyRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('Milo')
|
|
|
|
expect(result.data).toStrictEqual([catToys[0], catToys[1], catToys[2]].sort((a, b) => b.cat.id - a.cat.id))
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=cat.id:DESC&search=Milo')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on sort on one-to-many relation', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
relations: ['toys'],
|
|
|
|
sortableColumns: ['id', 'name', 'toys.id'],
|
|
|
|
searchableColumns: ['name', 'toys.name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
sortBy: [['toys.id', 'DESC']],
|
|
|
|
search: 'Mouse',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('Mouse')
|
|
|
|
const toy1 = clone(catToys[1])
|
|
|
|
delete toy1.cat
|
|
|
|
const toy2 = clone(catToys[2])
|
|
|
|
delete toy2.cat
|
|
|
|
expect(result.data).toStrictEqual([Object.assign(clone(cats[0]), { toys: [toy2, toy1] })])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=toys.id:DESC&search=Mouse')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on sort on one-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatHomeEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
searchableColumns: ['name', 'cat.name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: 'Garfield',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatHomeEntity>(query, catHomeRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('Garfield')
|
|
|
|
expect(result.data).toStrictEqual([catHomes[1]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=Garfield')
|
|
|
|
})
|
|
|
|
|
2021-10-12 11:01:53 +00:00
|
|
|
it('should return result based on search term and searchBy columns', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id', 'name', 'color'],
|
|
|
|
searchableColumns: ['name', 'color'],
|
|
|
|
}
|
|
|
|
|
|
|
|
const searchTerm = 'white'
|
|
|
|
const expectedResultData = cats.filter((cat: CatEntity) => cat.color === searchTerm)
|
|
|
|
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: searchTerm,
|
|
|
|
searchBy: ['color'],
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-10-12 11:01:53 +00:00
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual(searchTerm)
|
|
|
|
expect(result.meta.searchBy).toStrictEqual(['color'])
|
|
|
|
expect(result.data).toStrictEqual(expectedResultData)
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=white&searchBy=color')
|
|
|
|
})
|
|
|
|
|
2021-08-19 14:42:18 +00:00
|
|
|
it('should return result based on where config and filter', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
where: {
|
|
|
|
color: 'white',
|
|
|
|
},
|
|
|
|
filterableColumns: {
|
|
|
|
name: [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
name: '$not:Leche',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
name: '$not:Leche',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([cats[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$not:Leche')
|
|
|
|
})
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
it('should return result based on filter on many-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatToyEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
filterableColumns: {
|
|
|
|
'cat.name': [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
'cat.name': '$not:Milo',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatToyEntity>(query, catToyRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
'cat.name': '$not:Milo',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([catToys[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.name=$not:Milo')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on filter on one-to-many relation', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
relations: ['toys'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
filterableColumns: {
|
|
|
|
'toys.name': [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
'toys.name': '$not:Stuffed Mouse',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
const cat1 = clone(cats[0])
|
|
|
|
const cat2 = clone(cats[1])
|
|
|
|
const catToys1 = clone(catToys[0])
|
|
|
|
const catToys2 = clone(catToys[2])
|
|
|
|
const catToys3 = clone(catToys[3])
|
|
|
|
delete catToys1.cat
|
|
|
|
delete catToys2.cat
|
|
|
|
delete catToys3.cat
|
|
|
|
cat1.toys = [catToys1, catToys2]
|
|
|
|
cat2.toys = [catToys3]
|
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
'toys.name': '$not:Stuffed Mouse',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([cat1, cat2])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.toys.name=$not:Stuffed Mouse')
|
|
|
|
})
|
|
|
|
|
2022-03-14 19:02:55 +00:00
|
|
|
it('should return result based on filter on one-to-one relation', async () => {
|
2022-03-14 19:02:01 +00:00
|
|
|
const config: PaginateConfig<CatHomeEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
filterableColumns: {
|
|
|
|
'cat.name': [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
'cat.name': '$not:Garfield',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatHomeEntity>(query, catHomeRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
'cat.name': '$not:Garfield',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([catHomes[0]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.name=$not:Garfield')
|
|
|
|
})
|
|
|
|
|
2022-03-14 19:02:55 +00:00
|
|
|
it('should return result based on $in filter on one-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatHomeEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
filterableColumns: {
|
|
|
|
'cat.age': [FilterOperator.IN],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
'cat.age': '$in:4,6',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatHomeEntity>(query, catHomeRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
'cat.age': '$in:4,6',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([catHomes[0]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.age=$in:4,6')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on $btw filter on one-to-one relation', async () => {
|
|
|
|
const config: PaginateConfig<CatHomeEntity> = {
|
|
|
|
relations: ['cat'],
|
|
|
|
sortableColumns: ['id', 'name'],
|
|
|
|
filterableColumns: {
|
2022-05-14 17:52:16 +00:00
|
|
|
createdAt: [FilterOperator.BTW],
|
2022-03-14 19:02:55 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
'cat.age': '$btw:6,10',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatHomeEntity>(query, catHomeRepo, config)
|
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
'cat.age': '$btw:6,10',
|
|
|
|
})
|
2022-05-14 17:52:16 +00:00
|
|
|
expect(result.data).toStrictEqual([catHomes[0], catHomes[1]])
|
2022-03-14 19:02:55 +00:00
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.cat.age=$btw:6,10')
|
|
|
|
})
|
|
|
|
|
2021-09-28 11:15:24 +00:00
|
|
|
it('should return result based on where array and filter', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
where: [
|
|
|
|
{
|
|
|
|
color: 'white',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
age: 4,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
filterableColumns: {
|
|
|
|
name: [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
name: '$not:Leche',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-09-28 11:15:24 +00:00
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
name: '$not:Leche',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([cats[2], cats[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$not:Leche')
|
|
|
|
})
|
|
|
|
|
2021-08-19 14:42:18 +00:00
|
|
|
it('should return result based on multiple filter', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
name: [FilterOperator.NOT],
|
|
|
|
color: [FilterOperator.EQ],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
name: '$not:Leche',
|
|
|
|
color: 'white',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.meta.filter).toStrictEqual({
|
|
|
|
name: '$not:Leche',
|
|
|
|
color: 'white',
|
|
|
|
})
|
|
|
|
expect(result.data).toStrictEqual([cats[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.name=$not:Leche&filter.color=white')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on filter and search term', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
searchableColumns: ['name', 'color'],
|
|
|
|
filterableColumns: {
|
|
|
|
id: [FilterOperator.NOT, FilterOperator.IN],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
search: 'white',
|
|
|
|
filter: {
|
|
|
|
id: '$not:$in:1,2,5',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.meta.search).toStrictEqual('white')
|
|
|
|
expect(result.meta.filter).toStrictEqual({ id: '$not:$in:1,2,5' })
|
|
|
|
expect(result.data).toStrictEqual([cats[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=white&filter.id=$not:$in:1,2,5')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on filter and where config', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
where: {
|
|
|
|
color: In(['black', 'white']),
|
|
|
|
},
|
|
|
|
filterableColumns: {
|
|
|
|
id: [FilterOperator.NOT, FilterOperator.IN],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
id: '$not:$in:1,2,5',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.data).toStrictEqual([cats[2], cats[3]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.id=$not:$in:1,2,5')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on range filter', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
age: [FilterOperator.GTE],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
age: '$gte:4',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
2022-01-27 21:12:52 +00:00
|
|
|
expect(result.data).toStrictEqual([cats[0], cats[1], cats[2]])
|
2021-08-19 14:42:18 +00:00
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$gte:4')
|
|
|
|
})
|
|
|
|
|
2022-01-27 12:32:51 +00:00
|
|
|
it('should return result based on between range filter', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
age: [FilterOperator.BTW],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
2022-01-27 21:12:52 +00:00
|
|
|
age: '$btw:4,5',
|
2022-01-27 12:32:51 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2022-01-27 12:32:51 +00:00
|
|
|
|
2022-01-27 21:12:52 +00:00
|
|
|
expect(result.data).toStrictEqual([cats[1], cats[2]])
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$btw:4,5')
|
2022-01-27 12:32:51 +00:00
|
|
|
})
|
|
|
|
|
2021-08-19 14:42:18 +00:00
|
|
|
it('should return result based on is null query', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
age: [FilterOperator.NULL],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
age: '$null',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
2022-01-27 21:12:52 +00:00
|
|
|
expect(result.data).toStrictEqual([cats[4]])
|
2021-08-19 14:42:18 +00:00
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$null')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return result based on not null query', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
age: [FilterOperator.NOT, FilterOperator.NULL],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
age: '$not:$null',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
2022-01-27 21:12:52 +00:00
|
|
|
expect(result.data).toStrictEqual([cats[0], cats[1], cats[2], cats[3]])
|
2021-08-19 14:42:18 +00:00
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$not:$null')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should ignore filterable column which is not configured', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
name: [FilterOperator.NOT, FilterOperator.NULL],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
age: '$not:$null',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.data).toStrictEqual(cats)
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$not:$null')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should ignore filter operator which is not configured', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
filterableColumns: {
|
|
|
|
age: [FilterOperator.NOT],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
filter: {
|
|
|
|
age: '$not:$null',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-03-14 19:02:01 +00:00
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
2021-08-19 14:42:18 +00:00
|
|
|
|
|
|
|
expect(result.data).toStrictEqual(cats)
|
|
|
|
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$not:$null')
|
|
|
|
})
|
|
|
|
|
2020-06-26 21:25:03 +00:00
|
|
|
it('should throw an error when no sortableColumns', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: [],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2022-03-14 19:02:01 +00:00
|
|
|
await paginate<CatEntity>(query, catRepo, config)
|
2020-06-26 21:25:03 +00:00
|
|
|
} catch (err) {
|
|
|
|
expect(err).toBeInstanceOf(HttpException)
|
|
|
|
}
|
|
|
|
})
|
2021-11-16 17:49:13 +00:00
|
|
|
|
|
|
|
it.each([
|
|
|
|
{ operator: '$eq', result: true },
|
|
|
|
{ operator: '$gte', result: true },
|
|
|
|
{ operator: '$gt', result: true },
|
|
|
|
{ operator: '$in', result: true },
|
|
|
|
{ operator: '$null', result: true },
|
|
|
|
{ operator: '$lt', result: true },
|
|
|
|
{ operator: '$lte', result: true },
|
2022-01-27 12:32:51 +00:00
|
|
|
{ operator: '$btw', result: true },
|
2021-11-16 17:49:13 +00:00
|
|
|
{ operator: '$not', result: true },
|
|
|
|
{ operator: '$fake', result: false },
|
|
|
|
])('should check operator "$operator" valid is $result', ({ operator, result }) => {
|
|
|
|
expect(isOperator(operator)).toStrictEqual(result)
|
|
|
|
})
|
|
|
|
|
|
|
|
it.each([
|
|
|
|
{ operator: '$eq', name: 'Equal' },
|
|
|
|
{ operator: '$gt', name: 'MoreThan' },
|
|
|
|
{ operator: '$gte', name: 'MoreThanOrEqual' },
|
|
|
|
{ operator: '$in', name: 'In' },
|
|
|
|
{ operator: '$null', name: 'IsNull' },
|
|
|
|
{ operator: '$lt', name: 'LessThan' },
|
|
|
|
{ operator: '$lte', name: 'LessThanOrEqual' },
|
2022-01-27 12:32:51 +00:00
|
|
|
{ operator: '$btw', name: 'Between' },
|
2021-11-16 17:49:13 +00:00
|
|
|
{ operator: '$not', name: 'Not' },
|
|
|
|
])('should get operator function $name for "$operator"', ({ operator, name }) => {
|
2022-01-27 21:12:52 +00:00
|
|
|
const func = OperatorSymbolToFunction.get(operator as FilterOperator)
|
2021-11-16 17:49:13 +00:00
|
|
|
expect(func.name).toStrictEqual(name)
|
|
|
|
})
|
|
|
|
|
|
|
|
it.each([
|
|
|
|
{ string: '$eq:value', tokens: [null, '$eq', 'value'] },
|
|
|
|
{ string: '$eq:val:ue', tokens: [null, '$eq', 'val:ue'] },
|
|
|
|
{ string: '$in:value1,value2,value3', tokens: [null, '$in', 'value1,value2,value3'] },
|
2021-11-16 18:06:26 +00:00
|
|
|
{ string: '$not:$in:value1:a,value2:b,value3:c', tokens: ['$not', '$in', 'value1:a,value2:b,value3:c'] },
|
2021-11-16 17:49:13 +00:00
|
|
|
{ string: 'value', tokens: [null, '$eq', 'value'] },
|
|
|
|
{ string: 'val:ue', tokens: [null, '$eq', 'val:ue'] },
|
|
|
|
{ string: '$not:value', tokens: [null, '$not', 'value'] },
|
|
|
|
{ string: '$eq:$not:value', tokens: ['$eq', '$not', 'value'] },
|
|
|
|
{ string: '$eq:$null', tokens: ['$eq', '$null'] },
|
|
|
|
{ string: '$null', tokens: [null, '$null'] },
|
|
|
|
{ string: '', tokens: [null, '$eq', ''] },
|
|
|
|
{ string: '$eq:$not:$in:value', tokens: [] },
|
|
|
|
])('should get filter tokens for "$string"', ({ string, tokens }) => {
|
|
|
|
expect(getFilterTokens(string)).toStrictEqual(tokens)
|
|
|
|
})
|
2022-05-15 19:01:53 +00:00
|
|
|
|
|
|
|
it('should return all items even if deleted', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
withDeleted: true,
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
await catRepo.softDelete({ id: cats[0].id })
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
expect(result.meta.totalItems).toBe(cats.length)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return only undeleted items', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
withDeleted: false,
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
await catRepo.softDelete({ id: cats[0].id })
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
expect(result.meta.totalItems).toBe(cats.length - 1)
|
|
|
|
})
|
2022-07-27 17:58:00 +00:00
|
|
|
|
|
|
|
it('should return the specified columns only', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['id'],
|
|
|
|
select: ['id', 'name'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
result.data.forEach((cat) => {
|
|
|
|
expect(cat.color).not.toBeDefined()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return the specified relationship columns only', async () => {
|
|
|
|
const config: PaginateConfig<CatEntity> = {
|
|
|
|
sortableColumns: ['name'],
|
|
|
|
select: ['id', 'name', 'toys.name'],
|
|
|
|
relations: ['toys'],
|
|
|
|
}
|
|
|
|
const query: PaginateQuery = {
|
|
|
|
path: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await paginate<CatEntity>(query, catRepo, config)
|
|
|
|
|
|
|
|
result.data.forEach((cat) => {
|
|
|
|
expect(cat.id).toBeDefined()
|
|
|
|
expect(cat.name).toBeDefined()
|
|
|
|
expect(cat.color).not.toBeDefined()
|
|
|
|
|
|
|
|
cat.toys.map((toy) => {
|
|
|
|
expect(toy.name).toBeDefined()
|
|
|
|
expect(toy.id).not.toBeDefined()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2020-06-26 21:25:03 +00:00
|
|
|
})
|