Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update - from patch to fully replace #387

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion apps/velo-external-db/test/e2e/app_data.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
})


test('update undefined to number columns should insert nulls', async() => {
test('update explicit null to number columns should insert nulls', async() => {
await schema.givenCollection(ctx.collectionName, ctx.numberColumns, authOwner)
await data.givenItems([ctx.numberItem], ctx.collectionName, authAdmin)
ctx.numberItem[ctx.numberColumns[0].name] = null
Expand All @@ -226,6 +226,28 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
})


test('update partial item should insert null for all the non-system fields', async() => {
await schema.givenCollection(ctx.collectionName, ctx.numberColumns, authOwner)
await data.givenItems([ctx.numberItem], ctx.collectionName, authOwner)

const itemToUpdate = {
_id: ctx.numberItem._id,
[ctx.numberColumns[0].name]: ctx.randomNumberColumnValue
}

await axios.post('/data/update', { collectionName: ctx.collectionName, item: itemToUpdate }, authAdmin)

await expect(data.expectAllDataIn(ctx.collectionName, authAdmin)).resolves.toEqual({
items: [
expect.objectContaining({
_id: ctx.numberItem._id,
[ctx.numberColumns[0].name]: ctx.randomNumberColumnValue,
[ctx.numberColumns[1].name]: null,
})
], totalCount: 1
})
})

const ctx = {
collectionName: Uninitialized,
column: Uninitialized,
Expand All @@ -238,6 +260,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
numberItem: Uninitialized,
anotherNumberItem: Uninitialized,
pastVeloDate: Uninitialized,
randomNumberColumnValue: Uninitialized,
}

afterAll(async() => await teardownApp())
Expand All @@ -254,5 +277,6 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
ctx.numberItem = genCommon.randomNumberEntity(ctx.numberColumns)
ctx.anotherNumberItem = genCommon.randomNumberEntity(ctx.numberColumns)
ctx.pastVeloDate = genCommon.pastVeloDate()
ctx.randomNumberColumnValue = chance.integer({ min: 0, max: 100 })
})
})
2 changes: 1 addition & 1 deletion libs/velo-external-db-core/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@wix-velo/velo-external-db-core",
"version": "1.2.4",
"version": "2.0.0",
"type": "commonjs"
}
7 changes: 0 additions & 7 deletions libs/velo-external-db-core/src/converters/item_transformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,10 @@ class ItemTransformer {
return items.map(i => this.prepareForInsert(i, fields))
}

prepareItemsForUpdate(items, fields) {
return items.map(i => this.prepareForUpdate(i, fields))
}

prepareForInsert(item, fields) {
return this.unpackDates(fields.reduce((pv, f) => ({ ...pv, [f.field]: item[f.field] || this.defaultValueFor(f) }), {}))
}

prepareForUpdate(item, fields) {
return this.unpackDates(fields.reduce((pv, f) => f.field in item ? ({ ...pv, [f.field]: item[f.field] }) : pv, {}))
}

patchItemsBooleanFields(items, fields) {
return items.map(i => this.patchBoolean(i, fields.filter(f => f.type === 'boolean')))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,7 @@ describe('Item Transformer', () => {
})
})

describe('prepare for update', () => {
test('prepare for update will remove non existing fields', async() => {
expect(env.itemTransformer.prepareForUpdate({ ...ctx.obj, someProp: 'whatever' }, ctx.objSchemaFields)).toEqual( ctx.obj )
})

test('prepare for insert will unpack velo date', () => {
const objWithVeloDate = { ...ctx.obj, [ctx.property]: ctx.veloDate }
expect(env.itemTransformer.prepareForUpdate(objWithVeloDate, [...ctx.objSchemaFields, { field: ctx.property, type: 'date' }])).toEqual( { ...ctx.obj, [ctx.property]: new Date(ctx.veloDate.$date) } )
})
})

describe('unpack dates', () => {
test('unpack dates will duplicate object and do nothing is date is not there', async() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ describe ('Schema Aware Data Service', () => {

test('update will prepare item for update and call data service with the prepared item', async() => {
schema.givenDefaultSchemaFor(ctx.collectionName)
patcher.givenPreparedItemsForUpdateWith([ctx.preparedEntity], [ctx.entityWithExtraProps])
patcher.givenPreparedItemsForInsertWith([ctx.preparedEntity], [ctx.entityWithExtraProps])
data.givenUpdateResult(ctx.preparedEntity, ctx.collectionName)

return expect(env.schemaAwareDataService.update(ctx.collectionName, ctx.entityWithExtraProps)).resolves.toEqual({ item: ctx.preparedEntity })
})

test('bulk update will prepare items for update and call data service with the prepared items', async() => {
schema.givenDefaultSchemaFor(ctx.collectionName)
patcher.givenPreparedItemsForUpdateWith(ctx.preparedEntities, ctx.entitiesWithExtraProps)
patcher.givenPreparedItemsForInsertWith(ctx.preparedEntities, ctx.entitiesWithExtraProps)
data.givenBulkUpdateResult(ctx.preparedEntities, ctx.collectionName)

return expect(env.schemaAwareDataService.bulkUpdate(ctx.collectionName, ctx.entitiesWithExtraProps)).resolves.toEqual({ items: ctx.preparedEntities })
Expand Down
12 changes: 4 additions & 8 deletions libs/velo-external-db-core/src/service/schema_aware_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ export default class SchemaAwareDataService {
}

async update(collectionName: string, item: Item) {
const prepared = await this.prepareItemsForUpdate(collectionName, [item])
const fields = await this.schemaInformation.schemaFieldsFor(collectionName)
const prepared = await this.prepareItemsForInsert(fields, [item])
return await this.dataService.update(collectionName, prepared[0])
}

async bulkUpdate(collectionName: string, items: Item[]) {
const prepared = await this.prepareItemsForUpdate(collectionName, items)
const fields = await this.schemaInformation.schemaFieldsFor(collectionName)
const prepared = await this.prepareItemsForInsert(fields, items)
return await this.dataService.bulkUpdate(collectionName, prepared)
}

Expand Down Expand Up @@ -98,12 +100,6 @@ export default class SchemaAwareDataService {
this.queryValidator.validateProjection(schemaFields, projection)
}

async prepareItemsForUpdate(collectionName: string, items: Item[]): Promise<Item[]> {
const fields = await this.schemaInformation.schemaFieldsFor(collectionName)

return this.itemTransformer.prepareItemsForUpdate(items, fields)
}

async prepareItemsForInsert(fields: any, items: any[]): Promise<Item[]> {
return this.itemTransformer.prepareItemsForInsert(items, fields)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { SystemFields } from '@wix-velo/velo-external-db-commons'

export const itemTransformer = {
prepareItemsForInsert: jest.fn(),
prepareItemsForUpdate: jest.fn(),
patchItems: jest.fn()
}

Expand All @@ -13,17 +12,13 @@ export const givenPreparedItemsForInsertWith = (prepared: any, items: any) =>
when(itemTransformer.prepareItemsForInsert).calledWith(items, systemFields)
.mockReturnValue(prepared)

export const givenPreparedItemsForUpdateWith = (prepared: any, items: any) =>
when(itemTransformer.prepareItemsForUpdate).calledWith(items, systemFields)
.mockReturnValue(prepared)

export const givenPatchedBooleanFieldsWith = (patched: any, items: any, fields?: { field: string, type: string, subtype?: string }[]) =>
when(itemTransformer.patchItems).calledWith(items, fields || systemFields)
.mockReturnValue(patched)

export const reset = () => {
itemTransformer.prepareItemsForInsert.mockClear()
itemTransformer.prepareItemsForUpdate.mockClear()
itemTransformer.patchItems.mockClear()
}