Skip to content

Commit cbeea40

Browse files
committed
feat: add test suite for checking identifierField
1 parent 85dd728 commit cbeea40

2 files changed

Lines changed: 176 additions & 3 deletions

File tree

packages/core/src/builder.handler.spec.ts

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,179 @@ describe('ApiHandler', () => {
126126
})
127127
})
128128

129+
describe('Check for __id field', () => {
130+
const postCollection = builder.collection('postTs', {
131+
slug: 'post',
132+
fields: builder.fields('postTs', (fb) => ({
133+
idField: fb.columns('idTs', {
134+
type: 'text',
135+
create: 'hidden',
136+
update: 'hidden',
137+
}),
138+
nameField: fb.columns('nameTs', {
139+
type: 'text',
140+
}),
141+
})),
142+
identifierColumn: 'nameTs',
143+
})
144+
145+
it('should (C) create successfully', async () => {
146+
const postData = mockPostData[0]
147+
148+
mockDb.query.postTs.findFirst = vi.fn().mockResolvedValueOnce({
149+
__pk: postData.id,
150+
__id: postData.name,
151+
idTs: postData.id,
152+
nameTs: postData.name,
153+
})
154+
155+
const { insertMock, valuesMock } = prepareInsertMock(
156+
vi.fn().mockResolvedValueOnce([{ idTs: postData.id, nameTs: postData.name }])
157+
)
158+
159+
const result = await postCollection.admin.api.create({
160+
slug: postCollection.slug,
161+
fields: postCollection.fields,
162+
context: { db: mockDb as any },
163+
data: {
164+
nameField: postData.name,
165+
},
166+
})
167+
168+
expect(insertMock).toHaveBeenCalledTimes(1)
169+
expect(valuesMock).not.toHaveBeenCalledWith([
170+
{
171+
idTs: expect.anything(),
172+
nameTs: postData.name,
173+
},
174+
])
175+
expect(mockDb.query.postTs.findFirst).toHaveBeenCalledWith(
176+
expect.objectContaining({
177+
columns: {
178+
idTs: true,
179+
nameTs: true,
180+
},
181+
where: eq(postCollection.fields.idField._.column, postData.id),
182+
extras: {
183+
__pk: sql<string | number>`${schema.postTs.idTs}`.as('__pk'),
184+
__id: sql<string | number>`${schema.postTs.nameTs}`.as('__id'),
185+
},
186+
})
187+
)
188+
expect(tx.insert).toHaveBeenCalledTimes(1)
189+
expect(result).toEqual({ __pk: postData.id, __id: postData.name })
190+
})
191+
192+
it('should (R) read successfully', async () => {
193+
const postData = mockPostData[0]
194+
195+
mockDb.query.postTs.findFirst = vi.fn().mockResolvedValueOnce({
196+
__pk: postData.id,
197+
__id: postData.name,
198+
idTs: postData.id,
199+
nameTs: postData.name,
200+
})
201+
202+
const result = await postCollection.admin.api.findOne({
203+
slug: postCollection.slug,
204+
fields: postCollection.fields,
205+
context: { db: mockDb as any },
206+
id: postData.id,
207+
})
208+
209+
expect(mockDb.query.postTs.findFirst).toBeCalledTimes(1)
210+
expect(mockDb.query.postTs.findFirst).toHaveBeenCalledWith(
211+
expect.objectContaining({
212+
columns: {
213+
idTs: true,
214+
nameTs: true,
215+
},
216+
where: eq(postCollection.fields.idField._.column, postData.id),
217+
extras: {
218+
__pk: sql<string | number>`${schema.postTs.idTs}`.as('__pk'),
219+
__id: sql<string | number>`${schema.postTs.nameTs}`.as('__id'),
220+
},
221+
})
222+
)
223+
expect(result).toEqual({
224+
__pk: postData.id,
225+
__id: postData.name,
226+
idField: postData.id,
227+
nameField: postData.name,
228+
})
229+
})
230+
231+
it('should (U) update successfully', async () => {
232+
const postData = mockPostData[0]
233+
const updatedPostData = mockPostData[1]
234+
235+
mockDb.query.postTs.findFirst = vi.fn().mockResolvedValueOnce({
236+
__pk: postData.id,
237+
__id: postData.name,
238+
idTs: updatedPostData.id,
239+
nameTs: updatedPostData.name,
240+
})
241+
242+
const { setMock, updateMock, whereUpdateMock } = prepareUpdateWhereMock(
243+
vi.fn().mockResolvedValueOnce([{ idTs: postData.id, nameTs: postData.name }])
244+
)
245+
246+
const result = await postCollection.admin.api.update({
247+
id: postData.id,
248+
context: { db: mockDb as any },
249+
slug: postCollection.slug,
250+
fields: postCollection.fields,
251+
data: {
252+
nameField: updatedPostData.name,
253+
},
254+
})
255+
256+
expect(updateMock).toHaveBeenCalledTimes(1)
257+
expect(whereUpdateMock).toBeCalledWith(
258+
eq(postCollection.fields.idField._.column, postData.id)
259+
)
260+
expect(mockDb.query.postTs.findFirst).toHaveBeenCalledWith(
261+
expect.objectContaining({
262+
columns: {
263+
idTs: true,
264+
nameTs: true,
265+
},
266+
where: eq(postCollection.fields.idField._.column, postData.id),
267+
extras: {
268+
__pk: sql<string | number>`${schema.postTs.idTs}`.as('__pk'),
269+
__id: sql<string | number>`${schema.postTs.nameTs}`.as('__id'),
270+
},
271+
})
272+
)
273+
expect(setMock).toHaveBeenCalledWith({ nameTs: updatedPostData.name })
274+
expect(result).toEqual({ __pk: postData.id, __id: postData.name })
275+
})
276+
277+
it('should (D) delete successfully', async () => {
278+
const { deleteMock, whereMock } = prepareDeleteMock(vi.fn().mockResolvedValueOnce([]))
279+
tx.delete = deleteMock
280+
mockDb.delete = deleteMock
281+
282+
const result = await postCollection.admin.api.delete({
283+
slug: postCollection.slug,
284+
fields: postCollection.fields,
285+
context: { db: mockDb as any },
286+
ids: [mockPostData[0].name, mockPostData[1].name, mockPostData[2].name],
287+
})
288+
289+
expect(deleteMock).toHaveBeenCalledTimes(1)
290+
expect(whereMock).toHaveBeenCalledTimes(1)
291+
expect(whereMock).toHaveBeenCalledWith(
292+
or(
293+
eq(postCollection.fields.nameField._.column, mockPostData[0].name),
294+
eq(postCollection.fields.nameField._.column, mockPostData[1].name),
295+
eq(postCollection.fields.nameField._.column, mockPostData[2].name)
296+
)
297+
)
298+
expect(result).toEqual(undefined)
299+
})
300+
})
301+
129302
describe('with no relation case', () => {
130303
const postCollection = builder.collection('postTs', {
131304
slug: 'post',

packages/core/src/builder.handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ import {
3131
getPrimaryColumn,
3232
getTableFromSchema,
3333
isRelationField,
34-
mapValueToTsValue,
34+
mapValueToTsValue as mapFieldValueToTsValue,
3535
} from './utils'
3636

37+
// TODO: Recheck that one-to-one relations are working correctly
3738
export function createDefaultApiHandlers<
3839
TContext extends MinimalContext = MinimalContext,
3940
TFields extends Fields<any> = Fields<any>,
@@ -328,7 +329,6 @@ class ApiHandler {
328329
return [[relationFieldTsName, null]]
329330
}
330331

331-
// TODO: map key from field to ts
332332
switch (field.type) {
333333
case 'connectOrCreate': {
334334
// NOTE: Find if connect value exists in the referenced table or not
@@ -416,7 +416,7 @@ class ApiHandler {
416416
) => {
417417
const referenceFieldName = this.findReferencedColumnFromManyRelation(relation)
418418
const payload = {
419-
...mapValueToTsValue(fields, value),
419+
...mapFieldValueToTsValue(fields, value),
420420
[referenceFieldName]: id,
421421
}
422422

0 commit comments

Comments
 (0)