@feathersjs/adapter-tests
Version:
Feathers shared database adapter test suite
777 lines (646 loc) • 23.6 kB
text/typescript
import assert from 'assert'
import { AdapterMethodsTest } from './declarations'
export default (test: AdapterMethodsTest, app: any, _errors: any, serviceName: string, idProp: string) => {
describe(' Methods', () => {
let doug: any
let service: any
beforeEach(async () => {
service = app.service(serviceName)
doug = await app.service(serviceName).create({
name: 'Doug',
age: 32
})
})
afterEach(async () => {
try {
await app.service(serviceName).remove(doug[idProp])
} catch (error: any) {}
})
describe('get', () => {
test('.get', async () => {
const data = await service.get(doug[idProp])
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id matches`)
assert.strictEqual(data.name, 'Doug', 'data.name matches')
assert.strictEqual(data.age, 32, 'data.age matches')
})
test('.get + $select', async () => {
const data = await service.get(doug[idProp], {
query: { $select: ['name'] }
})
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id property matches`)
assert.strictEqual(data.name, 'Doug', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
})
test('.get + id + query', async () => {
try {
await service.get(doug[idProp], {
query: { name: 'Tester' }
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
})
test('.get + NotFound', async () => {
try {
await service.get('568225fbfe21222432e836ff')
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.get + NotFound (integer)', async () => {
try {
await service.get(123456789)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.get + id + query id', async () => {
const alice = await service.create({
name: 'Alice',
age: 12
})
try {
await service.get(doug[idProp], {
query: { [idProp]: alice[idProp] }
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
await service.remove(alice[idProp])
})
})
describe('find', () => {
test('.find', async () => {
const data = await service.find()
assert.ok(Array.isArray(data), 'Data is an array')
assert.strictEqual(data.length, 1, 'Got one entry')
})
})
describe('remove', () => {
test('.remove', async () => {
const data = await service.remove(doug[idProp])
assert.strictEqual(data.name, 'Doug', 'data.name matches')
})
test('.remove + $select', async () => {
const data = await service.remove(doug[idProp], {
query: { $select: ['name'] }
})
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id property matches`)
assert.strictEqual(data.name, 'Doug', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
})
test('.remove + id + query', async () => {
try {
await service.remove(doug[idProp], {
query: { name: 'Tester' }
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
})
test('.remove + NotFound', async () => {
try {
await service.remove('568225fbfe21222432e836ff')
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.remove + NotFound (integer)', async () => {
try {
await service.remove(123456789)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.remove + multi', async () => {
try {
await service.remove(null)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(
error.name,
'MethodNotAllowed',
'Removing multiple without option set throws MethodNotAllowed'
)
}
service.options.multi = ['remove']
await service.create({ name: 'Dave', age: 29, created: true })
await service.create({
name: 'David',
age: 3,
created: true
})
const data = await service.remove(null, {
query: { created: true }
})
assert.strictEqual(data.length, 2)
const names = data.map((person: any) => person.name)
assert.ok(names.includes('Dave'), 'Dave removed')
assert.ok(names.includes('David'), 'David removed')
})
test('.remove + multi no pagination', async () => {
try {
await service.remove(doug[idProp])
} catch (error: any) {}
const count = 14
const defaultPaginate = 10
assert.ok(count > defaultPaginate, 'count is bigger than default pagination')
const multiBefore = service.options.multi
const paginateBefore = service.options.paginate
try {
service.options.multi = true
service.options.paginate = {
default: defaultPaginate,
max: 100
}
const emptyItems = await service.find({ paginate: false })
assert.strictEqual(emptyItems.length, 0, 'no items before')
const createdItems = await service.create(
Array.from(Array(count)).map((_, i) => ({
name: `name-${i}`,
age: 3,
created: true
}))
)
assert.strictEqual(createdItems.length, count, `created ${count} items`)
const foundItems = await service.find({ paginate: false })
assert.strictEqual(foundItems.length, count, `created ${count} items`)
const foundPaginatedItems = await service.find({})
assert.strictEqual(foundPaginatedItems.data.length, defaultPaginate, 'found paginated items')
const allItems = await service.remove(null, {
query: { created: true }
})
assert.strictEqual(allItems.length, count, `removed all ${count} items`)
} finally {
await service.remove(null, {
query: { created: true },
paginate: false
})
service.options.multi = multiBefore
service.options.paginate = paginateBefore
}
})
test('.remove + id + query id', async () => {
const alice = await service.create({
name: 'Alice',
age: 12
})
try {
await service.remove(doug[idProp], {
query: { [idProp]: alice[idProp] }
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
await service.remove(alice[idProp])
})
})
describe('update', () => {
test('.update', async () => {
const originalData = { [idProp]: doug[idProp], name: 'Dougler' }
const originalCopy = Object.assign({}, originalData)
const data = await service.update(doug[idProp], originalData)
assert.deepStrictEqual(originalData, originalCopy, 'data was not modified')
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id matches`)
assert.strictEqual(data.name, 'Dougler', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
})
test('.update + $select', async () => {
const originalData = {
[idProp]: doug[idProp],
name: 'Dougler',
age: 10
}
const data = await service.update(doug[idProp], originalData, {
query: { $select: ['name'] }
})
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id property matches`)
assert.strictEqual(data.name, 'Dougler', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
})
test('.update + id + query', async () => {
try {
await service.update(
doug[idProp],
{
name: 'Dougler'
},
{
query: { name: 'Tester' }
}
)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
const updatedDoug = await service.get(doug[idProp])
assert.strictEqual(updatedDoug.name, 'Doug', 'Doug was not updated')
})
test('.update + NotFound', async () => {
try {
await service.update('568225fbfe21222432e836ff', {
name: 'NotFound'
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.update + NotFound (integer)', async () => {
try {
await service.update(123456789, {
name: 'NotFound'
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.update + query + NotFound', async () => {
const dave = await service.create({ name: 'Dave' })
try {
await service.update(dave[idProp], { name: 'UpdatedDave' }, { query: { name: 'NotDave' } })
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
await service.remove(dave[idProp])
})
test('.update + id + query id', async () => {
const alice = await service.create({
name: 'Alice',
age: 12
})
try {
await service.update(
doug[idProp],
{
name: 'Dougler',
age: 33
},
{
query: { [idProp]: alice[idProp] }
}
)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
await service.remove(alice[idProp])
})
})
describe('patch', () => {
test('.patch', async () => {
const originalData = { [idProp]: doug[idProp], name: 'PatchDoug' }
const originalCopy = Object.assign({}, originalData)
const data = await service.patch(doug[idProp], originalData)
assert.deepStrictEqual(originalData, originalCopy, 'original data was not modified')
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id matches`)
assert.strictEqual(data.name, 'PatchDoug', 'data.name matches')
assert.strictEqual(data.age, 32, 'data.age matches')
})
test('.patch + $select', async () => {
const originalData = { [idProp]: doug[idProp], name: 'PatchDoug' }
const data = await service.patch(doug[idProp], originalData, {
query: { $select: ['name'] }
})
assert.strictEqual(data[idProp].toString(), doug[idProp].toString(), `${idProp} id property matches`)
assert.strictEqual(data.name, 'PatchDoug', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
})
test('.patch + id + query', async () => {
try {
await service.patch(
doug[idProp],
{
name: 'id patched doug'
},
{
query: { name: 'Tester' }
}
)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
})
test('.patch multiple', async () => {
try {
await service.patch(null, {})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(
error.name,
'MethodNotAllowed',
'Removing multiple without option set throws MethodNotAllowed'
)
}
const params = {
query: { created: true }
}
const dave = await service.create({
name: 'Dave',
age: 29,
created: true
})
const david = await service.create({
name: 'David',
age: 3,
created: true
})
service.options.multi = ['patch']
const data = await service.patch(
null,
{
age: 2
},
params
)
assert.strictEqual(data.length, 2, 'returned two entries')
assert.strictEqual(data[0].age, 2, 'First entry age was updated')
assert.strictEqual(data[1].age, 2, 'Second entry age was updated')
await service.remove(dave[idProp])
await service.remove(david[idProp])
})
test('.patch multiple no pagination', async () => {
try {
await service.remove(doug[idProp])
} catch (error: any) {}
const count = 14
const defaultPaginate = 10
assert.ok(count > defaultPaginate, 'count is bigger than default pagination')
const multiBefore = service.options.multi
const paginateBefore = service.options.paginate
let ids: any[]
try {
service.options.multi = true
service.options.paginate = {
default: defaultPaginate,
max: 100
}
const emptyItems = await service.find({ paginate: false })
assert.strictEqual(emptyItems.length, 0, 'no items before')
const createdItems = await service.create(
Array.from(Array(count)).map((_, i) => ({
name: `name-${i}`,
age: 3,
created: true
}))
)
assert.strictEqual(createdItems.length, count, `created ${count} items`)
ids = createdItems.map((item: any) => item[idProp])
const foundItems = await service.find({ paginate: false })
assert.strictEqual(foundItems.length, count, `created ${count} items`)
const foundPaginatedItems = await service.find({})
assert.strictEqual(foundPaginatedItems.data.length, defaultPaginate, 'found paginated data')
const allItems = await service.patch(null, { age: 4 }, { query: { created: true } })
assert.strictEqual(allItems.length, count, `patched all ${count} items`)
} finally {
service.options.multi = multiBefore
service.options.paginate = paginateBefore
if (ids) {
await Promise.all(ids.map((id) => service.remove(id)))
}
}
})
test('.patch multi query same', async () => {
const service = app.service(serviceName)
const multiBefore = service.options.multi
service.options.multi = true
const params = {
query: { age: { $lt: 10 } }
}
const dave = await service.create({
name: 'Dave',
age: 8,
created: true
})
const david = await service.create({
name: 'David',
age: 4,
created: true
})
const data = await service.patch(
null,
{
age: 2
},
params
)
assert.strictEqual(data.length, 2, 'returned two entries')
assert.strictEqual(data[0].age, 2, 'First entry age was updated')
assert.strictEqual(data[1].age, 2, 'Second entry age was updated')
await service.remove(dave[idProp])
await service.remove(david[idProp])
service.options.multi = multiBefore
})
test('.patch multi query changed', async () => {
const service = app.service(serviceName)
const multiBefore = service.options.multi
service.options.multi = true
const params = {
query: { age: 10 }
}
const dave = await service.create({
name: 'Dave',
age: 10,
created: true
})
const david = await service.create({
name: 'David',
age: 10,
created: true
})
const data = await service.patch(
null,
{
age: 2
},
params
)
assert.strictEqual(data.length, 2, 'returned two entries')
assert.strictEqual(data[0].age, 2, 'First entry age was updated')
assert.strictEqual(data[1].age, 2, 'Second entry age was updated')
await service.remove(dave[idProp])
await service.remove(david[idProp])
service.options.multi = multiBefore
})
test('.patch + NotFound', async () => {
try {
await service.patch('568225fbfe21222432e836ff', {
name: 'PatchDoug'
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.patch + NotFound (integer)', async () => {
try {
await service.patch(123456789, {
name: 'PatchDoug'
})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
})
test('.patch + query + NotFound', async () => {
const dave = await service.create({ name: 'Dave' })
try {
await service.patch(dave[idProp], { name: 'PatchedDave' }, { query: { name: 'NotDave' } })
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Error is a NotFound Feathers error')
}
await service.remove(dave[idProp])
})
test('.patch + id + query id', async () => {
const alice = await service.create({
name: 'Alice',
age: 12
})
try {
await service.patch(
doug[idProp],
{
age: 33
},
{
query: { [idProp]: alice[idProp] }
}
)
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(error.name, 'NotFound', 'Got a NotFound Feathers error')
}
await service.remove(alice[idProp])
})
})
describe('create', () => {
test('.create', async () => {
const originalData = {
name: 'Bill',
age: 40
}
const originalCopy = Object.assign({}, originalData)
const data = await service.create(originalData)
assert.deepStrictEqual(originalData, originalCopy, 'original data was not modified')
assert.ok(data instanceof Object, 'data is an object')
assert.strictEqual(data.name, 'Bill', 'data.name matches')
await service.remove(data[idProp])
})
test('.create ignores query', async () => {
const originalData = {
name: 'Billy',
age: 42
}
const data = await service.create(originalData, {
query: {
name: 'Dave'
}
})
assert.strictEqual(data.name, 'Billy', 'data.name matches')
await service.remove(data[idProp])
})
test('.create + $select', async () => {
const originalData = {
name: 'William',
age: 23
}
const data = await service.create(originalData, {
query: { $select: ['name'] }
})
assert.ok(idProp in data, 'data has id')
assert.strictEqual(data.name, 'William', 'data.name matches')
assert.ok(!data.age, 'data.age is falsy')
await service.remove(data[idProp])
})
test('.create multi', async () => {
try {
await service.create([], {})
throw new Error('Should never get here')
} catch (error: any) {
assert.strictEqual(
error.name,
'MethodNotAllowed',
'Removing multiple without option set throws MethodNotAllowed'
)
}
const items = [
{
name: 'Gerald',
age: 18
},
{
name: 'Herald',
age: 18
}
]
service.options.multi = ['create', 'patch']
const data = await service.create(items)
assert.ok(Array.isArray(data), 'data is an array')
assert.ok(typeof data[0][idProp] !== 'undefined', 'id is set')
assert.strictEqual(data[0].name, 'Gerald', 'first name matches')
assert.ok(typeof data[1][idProp] !== 'undefined', 'id is set')
assert.strictEqual(data[1].name, 'Herald', 'second name macthes')
await service.remove(data[0][idProp])
await service.remove(data[1][idProp])
})
})
describe("doesn't call public methods internally", () => {
let throwing: any
before(() => {
throwing = Object.assign(Object.create(app.service(serviceName)), {
get store() {
return app.service(serviceName).store
},
find() {
throw new Error('find method called')
},
get() {
throw new Error('get method called')
},
create() {
throw new Error('create method called')
},
update() {
throw new Error('update method called')
},
patch() {
throw new Error('patch method called')
},
remove() {
throw new Error('remove method called')
}
})
})
test('internal .find', () => app.service(serviceName).find.call(throwing))
test('internal .get', () => service.get.call(throwing, doug[idProp]))
test('internal .create', async () => {
const bob = await service.create.call(throwing, {
name: 'Bob',
age: 25
})
await service.remove(bob[idProp])
})
test('internal .update', () =>
service.update.call(throwing, doug[idProp], {
name: 'Dougler'
}))
test('internal .patch', () =>
service.patch.call(throwing, doug[idProp], {
name: 'PatchDoug'
}))
test('internal .remove', () => service.remove.call(throwing, doug[idProp]))
})
})
}