Skip to content

Commit

Permalink
Merge pull request #1104 from carterbush/fix-update-compound
Browse files Browse the repository at this point in the history
fix: compound id issue with default name
  • Loading branch information
morintd authored Dec 10, 2024
2 parents 9949453 + 0feb39d commit 23df349
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 16 deletions.
11 changes: 11 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ model User {
profile Profile?
service Service[]
subscriptions Subscription[]
reactions Reaction[]
}

model Profile {
Expand Down Expand Up @@ -90,3 +91,13 @@ model Subscription {
blog Blog @relation(fields: [blogId], references: [id])
blogId Int
}

model Reaction {
userId Int
emoji String
value Int
user User @relation(fields: [userId], references: [id])
@@id([userId, emoji])
}
46 changes: 35 additions & 11 deletions src/__tests__/client/client-custom.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
import { DMMF } from '@prisma/generator-helper';

import { seededUsers } from '../../../testing';
import { generateDMMF, generatePrismockSync } from '../../lib/prismock';
import { fetchGenerator, generateDMMF, generatePrismockSync, getProvider } from '../../lib/prismock';
import { PrismockClient, PrismockClientType } from '../../lib/client';

describe('client (custom)', () => {
let provider: string | undefined;

beforeAll(async () => {
const generator = await fetchGenerator();
provider = getProvider(generator);
generator.stop();
});

describe('generatePrismock', () => {
it('Should get data', async () => {
const prismock = new PrismockClient() as PrismockClientType;
await prismock.user.createMany({ data: seededUsers.map(({ id, ...user }) => ({ ...user, parameters: {} })) });

const data = prismock.getData();

expect({
...data,
user: data.user.map(({ id, ...user }) => user),
}).toEqual({
const expected = {
user: seededUsers.map(({ id, ...user }) => user),
blog: [],
post: [],
profile: [],
service: [],
subscription: [],
});
};

if (provider !== 'mongodb') {
Object.assign(expected, {
reaction: [],
});
}

expect({
...data,
user: data.user.map(({ id, ...user }) => user),
}).toEqual(expected);
});
});

Expand All @@ -40,17 +56,25 @@ describe('client (custom)', () => {

const data = prismock.getData();

expect({
...data,
user: data.user.map(({ id, ...user }) => user),
}).toEqual({
const expected = {
user: seededUsers.map(({ id, ...user }) => user),
blog: [],
post: [],
profile: [],
service: [],
subscription: [],
});
};

if (provider !== 'mongodb') {
Object.assign(expected, {
reaction: [],
});
}

expect({
...data,
user: data.user.map(({ id, ...user }) => user),
}).toEqual(expected);
});
});
});
17 changes: 16 additions & 1 deletion src/__tests__/find/find-unique.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// @ts-nocheck
import { PrismaClient, User } from '@prisma/client';

import { resetDb, seededUsers, simulateSeed, seededBlogs, seededServices } from '../../../testing';
import { resetDb, seededUsers, simulateSeed, seededBlogs, seededServices, seededReactions } from '../../../testing';
import { PrismockClient, PrismockClientType } from '../../lib/client';
import { fetchGenerator, getProvider } from '../../lib/prismock';

Expand Down Expand Up @@ -61,5 +61,20 @@ describe('find', () => {
expect(mockService).toEqual(expected);
}
});

it('Should return corresponding item based on @@id with default name', async () => {
if (provider !== 'mongodb') {
const expected = seededReactions[0];
const realService = await prisma.reaction.findUnique({
where: { userId_emoji: { userId: expected.userId, emoji: expected.emoji } },
});
const mockService = await prismock.reaction.findUnique({
where: { userId_emoji: { userId: expected.userId, emoji: expected.emoji } },
});

expect(realService).toEqual(expected);
expect(mockService).toEqual(expected);
}
});
});
});
2 changes: 1 addition & 1 deletion src/__tests__/update/update-many.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PrismaClient } from '@prisma/client';
import { resetDb, simulateSeed, buildUser, formatEntries, generateId } from '../../../testing';
import { PrismockClient, PrismockClientType } from '../../lib/client';

jest.setTimeout(15000);
jest.setTimeout(40000);

describe('updateMany', () => {
let prismock: PrismockClientType;
Expand Down
105 changes: 104 additions & 1 deletion src/__tests__/update/update.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
/* eslint-disable no-console */
/* eslint-disable jest/no-conditional-expect */
/* eslint-disable @typescript-eslint/ban-ts-comment */
// @ts-nocheck
import { PrismaClient, Service } from '@prisma/client';
import { version as clientVersion } from '@prisma/client/package.json';

import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';

import { buildUser, formatEntries, formatEntry, resetDb, seededServices, seededUsers, simulateSeed } from '../../../testing';
import {
buildUser,
formatEntries,
formatEntry,
resetDb,
seededReactions,
seededServices,
seededUsers,
simulateSeed,
} from '../../../testing';
import { PrismockClient, PrismockClientType } from '../../lib/client';
import { Item } from '../../lib/delegate';
import { fetchGenerator, getProvider } from '../../lib/prismock';
Expand Down Expand Up @@ -129,4 +140,96 @@ describe('update', () => {
});
}
});

describe('Update using compound id with default name', () => {
const expectedNewValue = 100;

beforeAll(async () => {
if (provider !== 'mongodb') {
const updatedReaction = seededReactions[0];
const untouchedReaction = seededReactions[1];

await prisma.reaction.update({
where: {
userId_emoji: {
userId: updatedReaction.userId,
emoji: updatedReaction.emoji,
},
},
data: {
value: expectedNewValue,
},
});
await prismock.reaction.update({
where: {
userId_emoji: {
userId: updatedReaction.userId,
emoji: updatedReaction.emoji,
},
},
data: {
value: expectedNewValue,
},
});
}
});

it('Should update expected entry', async () => {
if (provider !== 'mongodb') {
const updatedReaction = seededReactions[0];
const untouchedReaction = seededReactions[1];

const realResult = await prisma.reaction.findUnique({
where: {
userId_emoji: {
userId: updatedReaction.userId,
emoji: updatedReaction.emoji,
},
},
});
const mockResult = await prismock.reaction.findUnique({
where: {
userId_emoji: {
userId: updatedReaction.userId,
emoji: updatedReaction.emoji,
},
},
});

expect(realResult.value).toEqual(expectedNewValue);
expect(mockResult.value).toEqual(expectedNewValue);
} else {
console.log('[SKIPPED] compound ID not supported on MongoDB');
}
});

it('Should not update other data', async () => {
if (provider !== 'mongodb') {
const updatedReaction = seededReactions[0];
const untouchedReaction = seededReactions[1];

const realResult = await prisma.reaction.findUnique({
where: {
userId_emoji: {
userId: untouchedReaction.userId,
emoji: untouchedReaction.emoji,
},
},
});
const mockResult = await prismock.reaction.findUnique({
where: {
userId_emoji: {
userId: untouchedReaction.userId,
emoji: untouchedReaction.emoji,
},
},
});

expect(realResult.value).toEqual(untouchedReaction.value);
expect(mockResult.value).toEqual(untouchedReaction.value);
} else {
console.log('[SKIPPED] compound ID not supported on MongoDB');
}
});
});
});
5 changes: 4 additions & 1 deletion src/lib/operations/find/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ export const matchMultiple = (item: Item, where: FindWhereArgs, current: Delegat
}

const compositeIndex =
current.model.uniqueIndexes.map((index) => index.name).includes(child) || current.model.primaryKey?.name === child;
current.model.uniqueIndexes.map((index) => index.name).includes(child) ||
current.model.primaryKey?.name === child ||
current.model.primaryKey?.fields.join('_');

if (compositeIndex) {
return matchMultiple(item, where[child] as FindWhereArgs, current, delegates);
}
Expand Down
16 changes: 15 additions & 1 deletion testing/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { exec } from 'child_process';

import { Blog, Post, PrismaClient, Role, Service, Subscription, User } from '@prisma/client';
import { Blog, Post, PrismaClient, Reaction, Role, Service, Subscription, User } from '@prisma/client';
import dotenv from 'dotenv';
import { createId } from '@paralleldrive/cuid2';

Expand All @@ -10,6 +10,10 @@ export const seededUsers = [buildUser(1), buildUser(2, { warnings: 5 }), buildUs
export const seededBlogs = [buildBlog(1, { title: 'blog-1' }), buildBlog(2, { title: 'blog-2', userId: seededUsers[0].id })];
export const seededPosts = [buildPost(1, { authorId: 1, blogId: 1 }), buildPost(2, { authorId: 2, blogId: 2 })];
export const seededServices = [buildService({ userId: 1, name: 'facebook' })];
export const seededReactions = [
buildReaction({ userId: 1, emoji: 'thumbsup' }),
buildReaction({ userId: 1, emoji: 'rocket' }),
];

export async function simulateSeed(prisma: PrismaClient) {
await prisma.user.createMany({ data: seededUsers.map(({ id, ...user }) => user) });
Expand All @@ -18,6 +22,7 @@ export async function simulateSeed(prisma: PrismaClient) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore MySQL / Tags
await prisma.service.createMany({ data: seededServices });
await prisma.reaction.createMany({ data: seededReactions });
}

export async function resetDb() {
Expand Down Expand Up @@ -85,6 +90,15 @@ export function buildSubscription(id: number, subscription: Partial<Subscription
};
}

export function buildReaction(reaction: Pick<Reaction, 'userId' | 'emoji'>) {
const { userId, emoji } = reaction;
return {
userId,
emoji,
value: 0,
};
}

export function isUUID(maybeUUID: string) {
const regexUUID = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
return regexUUID.test(maybeUUID);
Expand Down
11 changes: 11 additions & 0 deletions testing/mysql/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ model User {
profile Profile?
service Service[]
subscriptions Subscription[]
reactions Reaction[]
}

model Profile {
Expand Down Expand Up @@ -90,3 +91,13 @@ model Subscription {
blog Blog @relation(fields: [blogId], references: [id])
blogId Int
}

model Reaction {
userId Int
emoji String
value Int
user User @relation(fields: [userId], references: [id])
@@id([userId, emoji])
}

0 comments on commit 23df349

Please sign in to comment.