Skip to content

Commit

Permalink
refactor: DataItemModificationResult
Browse files Browse the repository at this point in the history
  • Loading branch information
MXPOL committed Dec 10, 2023
1 parent 16ea92b commit 0b3b7bc
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 64 deletions.
59 changes: 31 additions & 28 deletions apps/velo-external-db/test/e2e/app_data.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import each from 'jest-each'
import * as Chance from 'chance'
import { Uninitialized, gen as genCommon, testIfSupportedOperationsIncludes } from '@wix-velo/test-commons'
import { InputField, SchemaOperations, Item } from '@wix-velo/velo-external-db-types'
import { dataSpi } from '@wix-velo/velo-external-db-core'
import { dataSpi, dataConvertUtils } from '@wix-velo/velo-external-db-core'
import { authAdmin, authOwner, authVisitor } from '@wix-velo/external-db-testkit'
import * as gen from '../gen'
import * as schema from '../drivers/schema_api_rest_test_support'
Expand Down Expand Up @@ -73,7 +73,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()

const response = await axiosInstance.post('/items/insert', data.insertRequest(ctx.collectionName, ctx.items), authAdmin)

expect(response.data).toEqual({ results: expect.toIncludeSameMembers(ctx.items) })
expect(response.data).toEqual({ results: expect.toIncludeSameMembers(ctx.items.map(item => ({ item }))) })

await expect(data.queryCollectionAsArray(ctx.collectionName, [], undefined, authOwner)).resolves.toEqual({
items: expect.toIncludeSameMembers(ctx.items),
Expand All @@ -87,14 +87,10 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
const response = await axiosInstance.post('/items/insert', data.insertRequest(ctx.collectionName, ctx.items), authAdmin)


expect(response.data.results).toEqual([
ctx.items[0],
{
errorCode: 409,
errorMessage: expect.toInclude('Item already exists'),
data: expect.any(Object)
},
...ctx.items.slice(2, ctx.items.length),
expect(response.data.results).toStrictEqual([
dataConvertUtils.asWixData(ctx.items[0]),
{ error: { errorCode: 409, errorMessage: expect.toInclude('Item already exists'), data: expect.any(Object) } },
...(ctx.items.slice(2, ctx.items.length).map(dataConvertUtils.asWixData)),
])

await expect(data.queryCollectionAsArray(ctx.collectionName, [], undefined, authOwner)).resolves.toEqual({
Expand Down Expand Up @@ -144,12 +140,12 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
testIfSupportedOperationsIncludes(supportedOperations, [ DeleteImmediately ])('bulk delete api', async() => {
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
await data.givenItems(ctx.items, ctx.collectionName, authAdmin)
await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
const response = await axiosInstance.post('/items/remove', {
collectionId: ctx.collectionName, itemIds: ctx.items.map(i => i._id)
}, authAdmin)

expect(response.data.results).toEqual(expect.toIncludeSameMembers(ctx.items))
expect(response.data.results).toEqual(expect.toIncludeSameMembers(ctx.items.map(dataConvertUtils.asWixData)))
await expect(data.queryCollectionAsArray(ctx.collectionName, [], undefined, authOwner)).resolves.toEqual({
items: [],
pagingMetadata: data.pagingMetadata(0, 0)
Expand All @@ -164,12 +160,14 @@ await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
collectionId: ctx.collectionName, itemIds: ctx.items.map(i => i._id)
}, authAdmin)

expect(response.data.results).toEqual([
ctx.items[0],
expect(response.data.results).toStrictEqual([
dataConvertUtils.asWixData(ctx.items[0]),
...ctx.items.slice(1, ctx.items.length).map(_i => ({
errorCode: 404,
errorMessage: expect.toInclude('Item doesn\'t exists'),
data: expect.any(Object)
error: {
errorCode: 404,
errorMessage: expect.toInclude('Item doesn\'t exists'),
data: expect.any(Object)
}
}))
])

Expand Down Expand Up @@ -229,7 +227,7 @@ await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
await data.givenItems(ctx.items, ctx.collectionName, authAdmin)
const response = await axiosInstance.post('/items/update', data.updateRequest(ctx.collectionName, ctx.modifiedItems), authAdmin)

expect(response.data.results).toEqual(ctx.modifiedItems)
expect(response.data.results).toEqual(ctx.modifiedItems.map(dataConvertUtils.asWixData))

await expect(data.queryCollectionAsArray(ctx.collectionName, [], undefined, authOwner)).resolves.toEqual({
items: expect.toIncludeSameMembers(ctx.modifiedItems),
Expand All @@ -243,11 +241,13 @@ await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
const response = await axiosInstance.post('/items/update', data.updateRequest(ctx.collectionName, ctx.modifiedItems), authAdmin)

expect(response.data.results).toEqual([
...ctx.modifiedItems.slice(0, ctx.items.length - 1),
{
errorCode: 404,
errorMessage: expect.toInclude('Item doesn\'t exists'),
data: expect.any(Object)
...(ctx.modifiedItems.slice(0, ctx.items.length - 1).map(dataConvertUtils.asWixData)),
{
error: {
errorCode: 404,
errorMessage: expect.toInclude('Item doesn\'t exists'),
data: expect.any(Object)
}
}
])

Expand Down Expand Up @@ -337,11 +337,14 @@ await data.givenItems([ ctx.items[1] ], ctx.collectionName, authAdmin)
const response = await axiosInstance.post('/items/insert', data.insertRequest(ctx.collectionName, [ctx.item]), authAdmin)

expect(response.data).toEqual(expect.objectContaining({
results: [{
errorCode: 409,
errorMessage: expect.toInclude('Item already exists'),
data: expect.any(Object)
}
results: [
{
error: {
errorCode: 409,
errorMessage: expect.toInclude('Item already exists'),
data: expect.any(Object)
}
}
]
}))
})
Expand Down
38 changes: 22 additions & 16 deletions apps/velo-external-db/test/e2e/app_data_hooks.e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { authOwner, errorResponseWith } from '@wix-velo/external-db-testkit'
import { testIfSupportedOperationsIncludes, testSupportedOperations } from '@wix-velo/test-commons'
import { dataSpi, types as coreTypes, collectionSpi } from '@wix-velo/velo-external-db-core'
import { DataOperation, InputField, ItemWithId, SchemaOperations } from '@wix-velo/velo-external-db-types'
import { dataSpi, types as coreTypes, collectionSpi, dataConvertUtils } from '@wix-velo/velo-external-db-core'
import { DataOperation, InputField, Item, ItemWithId, SchemaOperations } from '@wix-velo/velo-external-db-types'
import { Uninitialized, gen as genCommon } from '@wix-velo/test-commons'
import { initApp, teardownApp, dbTeardown, setupDb, currentDbImplementationName, env, supportedOperations } from '../resources/e2e_resources'
import gen = require('../gen')
Expand Down Expand Up @@ -187,7 +187,7 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
beforeAll: (payload: dataSpi.InsertRequest | dataSpi.UpdateRequest, requestContext: coreTypes.RequestContext, _serviceContext) => {
if (requestContext.operation !== DataOperation.query) {
return {
...payload, items: payload.items.map(item => ({
...payload, items: payload.items.map( item => ({
...item,
[ctx.afterAllColumn.name]: true,
[ctx.afterWriteColumn.name]: false,
Expand Down Expand Up @@ -460,29 +460,35 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
afterAll: (payload: coreTypes.InsertResponse | coreTypes.UpdateResponse | coreTypes.RemoveResponse, requestContext: coreTypes.RequestContext, _serviceContext) => {
if (requestContext.operation !== DataOperation.query) {
return {
...payload, results: payload.results.map(item => ({
...item,
[ctx.afterAllColumn.name]: true,
[ctx.afterWriteColumn.name]: false,
[ctx.afterHookColumn.name]: false,
...payload, results: payload.results.map(({ item }: { item: Item }) => ({
item: {
...item,
[ctx.afterAllColumn.name]: true,
[ctx.afterWriteColumn.name]: false,
[ctx.afterHookColumn.name]: false,
}
}))
}
}
},
afterWrite: (payload: coreTypes.InsertResponse | coreTypes.UpdateResponse | coreTypes.RemoveResponse, _requestContext, _serviceContext) => {
return {
...payload, results: payload.results.map(item => ({
...item,
[ctx.afterWriteColumn.name]: true,
[ctx.afterHookColumn.name]: false,
...payload, results: payload.results.map(({ item }: { item: Item }) => ({
item: {
...item,
[ctx.afterWriteColumn.name]: true,
[ctx.afterHookColumn.name]: false,
}
}))
}
},
[hookName]: (payload, _requestContext, _serviceContext) => {
return {
...payload, results: payload.results.map(item => ({
...item,
[ctx.afterHookColumn.name]: true,
...payload, results: payload.results.map(({ item }: { item: Item }) => ({
item: {
...item,
[ctx.afterHookColumn.name]: true,
}
}))
}
}
Expand All @@ -497,7 +503,7 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
[ctx.afterAllColumn.name]: true,
[ctx.afterWriteColumn.name]: true,
[ctx.afterHookColumn.name]: true,
}]
}].map(dataConvertUtils.asWixData)
})
})
})
Expand Down
4 changes: 2 additions & 2 deletions libs/velo-external-db-core/src/converters/data_utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ const chance = Chance()

describe('Converters', () => {
test('pack dates will duplicate object and do nothing is date is not there', async() => {
expect(asWixData(ctx.obj)).toMatchObject(ctx.obj)
expect(asWixData(ctx.obj)).toMatchObject({ item: ctx.obj })
})

test('pack dates will take all properties with date and convert them to velo date', async() => {
const objWithJsDates = { ...ctx.obj, [ctx.property]: dateTimeProvider.currentDateTime(),
[ctx.anotherProperty]: dateTimeProvider.currentDateTime() }

expect(asWixData(objWithJsDates)).toMatchObject( { ...ctx.obj, [ctx.property]: { $date: dateTimeProvider.currentDateTime().toISOString() },
expect(asWixData(objWithJsDates).item).toMatchObject( { ...ctx.obj, [ctx.property]: { $date: dateTimeProvider.currentDateTime().toISOString() },
[ctx.anotherProperty]: { $date: dateTimeProvider.currentDateTime().toISOString() } } )
})

Expand Down
2 changes: 1 addition & 1 deletion libs/velo-external-db-core/src/converters/data_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as crypto from 'crypto'


export const asWixData = (item: Item) => {
return generateIdsIfNeeded(packDates(item))
return { item: generateIdsIfNeeded(packDates(item)) }
}

export const generateIdsIfNeeded = (item: Item): ItemWithId => {
Expand Down
1 change: 1 addition & 0 deletions libs/velo-external-db-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export * as types from './types'
export * as dataSpi from './spi-model/data_source'
export * as collectionSpi from './spi-model/collection'
export * as schemaUtils from '../src/utils/schema_utils'
export * as dataConvertUtils from './converters/data_utils'
export * as convertersUtils from './converters/utils'
export { config } from './roles-config.json'
export { DataService, SchemaService, OperationService, CacheableSchemaInformation, FilterTransformer, AggregationTransformer, QueryValidator, SchemaAwareDataService, ItemTransformer, Hooks, ServiceContext, CollectionCapability, decodeBase64 }
9 changes: 5 additions & 4 deletions libs/velo-external-db-core/src/service/data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as driver from '../../test/drivers/data_provider_test_support'
import { SystemFields } from '@wix-velo/velo-external-db-commons'
import Chance = require('chance')
import { getByIdFilterFor } from '../utils/data_utils'
import { asWixData } from '../converters/data_utils'
import { HttpStatusCode } from '../spi-model/errors'
const chance = new Chance()

Expand Down Expand Up @@ -70,13 +71,13 @@ describe('Data Service', () => {
test('bulk insert will insert data into db', async() => {
driver.expectInsertFor(ctx.entities, ctx.collectionName, ctx.defaultProjection)

return expect(env.dataService.bulkInsert(ctx.collectionName, ctx.entities, ctx.defaultProjection)).resolves.toEqual({ items: ctx.entities })
return expect(env.dataService.bulkInsert(ctx.collectionName, ctx.entities, ctx.defaultProjection)).resolves.toEqual({ items: ctx.entities.map(asWixData) })
})

test('insert already item will return error object', async() => {
driver.expectInsertAlreadyExistsFor([ctx.entity], ctx.collectionName, ctx.defaultProjection)

return expect(env.dataService.insert(ctx.collectionName, ctx.entity, ctx.defaultProjection)).resolves.toEqual({ item: { errorCode: HttpStatusCode.ALREADY_EXISTS, errorMessage: expect.any(String), data: expect.any(Object) } })
return expect(env.dataService.insert(ctx.collectionName, ctx.entity, ctx.defaultProjection)).resolves.toEqual({ error: { errorCode: HttpStatusCode.ALREADY_EXISTS, errorMessage: expect.any(String), data: expect.any(Object) } })
})

test('update will update data into db', async() => {
Expand All @@ -88,7 +89,7 @@ describe('Data Service', () => {
test('bulk update will update data into db', async() => {
driver.expectUpdateFor(ctx.entities, ctx.collectionName)

return expect(env.dataService.bulkUpdate(ctx.collectionName, ctx.entities)).resolves.toEqual({ items: ctx.entities })
return expect(env.dataService.bulkUpdate(ctx.collectionName, ctx.entities)).resolves.toEqual({ items: ctx.entities.map(asWixData) })
})

test('delete by item id', async() => {
Expand All @@ -101,7 +102,7 @@ describe('Data Service', () => {
driver.givenItemsById(ctx.entities, ctx.collectionName, '', 0, 1, ctx.defaultProjection)
driver.expectDeleteFor(ctx.itemIds, ctx.collectionName)

return expect(env.dataService.bulkDelete(ctx.collectionName, ctx.entities.map((e: any) => e._id), ctx.defaultProjection)).resolves.toEqual({ items: ctx.entities })
return expect(env.dataService.bulkDelete(ctx.collectionName, ctx.entities.map((e: any) => e._id), ctx.defaultProjection)).resolves.toEqual({ items: ctx.entities.map(asWixData) })
})

// eslint-disable-next-line jest/expect-expect
Expand Down
15 changes: 7 additions & 8 deletions libs/velo-external-db-core/src/service/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export default class DataService {
const totalCount = returnTotalCount? this.storage.count(collectionName, _filter) : undefined

return {
items: (await items).map(asWixData),
items: (await items).map(item => asWixData(item).item),
totalCount: await totalCount
}
}

async getById(collectionName: string, itemId: string, projection: any) {
const item = await this.storage.find(collectionName, getByIdFilterFor(itemId), '', 0, 1, projection)
return { item: item[0] ? asWixData(item[0]) : null }
return item[0] ? asWixData(item[0]) : { item: null }
}

async count(collectionName: string, filter: Filter) {
Expand All @@ -32,7 +32,7 @@ export default class DataService {

async insert(collectionName: string, item: Item, fields?: ResponseField[]) {
const resp = await this.bulkInsert(collectionName, [item], fields)
return { item: resp.items[0] }
return resp.items[0]
}

async bulkUpsert(collectionName: string, items: Item[], fields?: ResponseField[]) {
Expand All @@ -51,7 +51,7 @@ export default class DataService {

async update(collectionName: string, item: Item) {
const resp = await this.bulkUpdate(collectionName, [item])
return { item: resp.items[0] }
return resp.items[0]
}

async bulkUpdate(collectionName: string, _items: Item[]) {
Expand All @@ -66,12 +66,12 @@ export default class DataService {

async delete(collectionName: string, itemId: string, fields: any) {
const { items } = await this.bulkDelete(collectionName, [itemId], fields)
return { item: items[0] }
return items[0]
}

async bulkDelete(collectionName: string, itemIds: string[], fields: any) {
const items = await Promise.all(itemIds.map(itemId => this.getById(collectionName, itemId, fields)
.then(({ item }) => item ? item : Promise.reject(new domainErrors.ItemDoesNotExists(`Item doesn't exists: ${itemId}`, collectionName, itemId)))
.then(({ item }) => item ? asWixData(item) : Promise.reject(new domainErrors.ItemDoesNotExists(`Item doesn't exists: ${itemId}`, collectionName, itemId)))
.catch(e => domainToSpiErrorObjectTranslator(e))
))

Expand All @@ -89,8 +89,7 @@ export default class DataService {
async aggregate(collectionName: string, filter: Filter, aggregation: Aggregation, sort?: Sort[], skip?: number, limit?: number, returnTotalCount?: boolean) {
const totalCount = returnTotalCount ? this.storage.count(collectionName, filter) : undefined
return {
items: ((await this.storage.aggregate?.(collectionName, filter, aggregation, sort, skip, limit)) || [])
.map( asWixData ),
items: ((await this.storage.aggregate?.(collectionName, filter, aggregation, sort, skip, limit)) || []).map(item => asWixData(item).item),
totalCount: await totalCount
}
}
Expand Down
2 changes: 1 addition & 1 deletion libs/velo-external-db-core/src/spi-model/data_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export interface InsertResponse {

// Item that was inserted, updated or removed. MUST be empty in case of error.
// Error indicating why operation failed for a particular item. MUST be empty in case of success.
export type DataItemModificationResult = Item | ApplicationError;
export type DataItemModificationResult = { item: Item } | { error: ApplicationError };

export interface Item {
[fieldName: string]: string | boolean;
Expand Down
Loading

0 comments on commit 0b3b7bc

Please sign in to comment.