tests_m-to-n.ts•43.8 kB
import { AdapterProviders, Providers, RelationModes } from '../_utils/providers'
import { checkIfEmpty } from '../_utils/relationMode/checkIfEmpty'
import { ConditionalError } from '../_utils/relationMode/conditionalError'
import testMatrix from './_matrix'
/* eslint-disable @typescript-eslint/no-unused-vars, jest/no-identical-title */
// @ts-ignore this is just for type checks
declare let prisma: import('./generated/prisma/client').PrismaClient
// @ts-ignore
const describeIf = (condition: boolean) => (condition ? describe : describe.skip)
// m:n relation (SQL database)
async function createXPostsWith2CategoriesSQLDb({ count, postModel }) {
  const prismaPromises: any = []
  for (let i = 0; i < count; i++) {
    // We want to start at 1
    const id = (i + 1).toString()
    const prismaPromise = prisma[postModel].create({
      data: {
        id: id,
        categories: {
          create: [
            {
              category: {
                create: {
                  id: `${id}-cat-a`,
                },
              },
            },
            {
              category: {
                create: {
                  id: `${id}-cat-b`,
                },
              },
            },
          ],
        },
      },
      include: {
        categories: true,
      },
    })
    prismaPromises.push(prismaPromise)
  }
  return await prisma.$transaction(prismaPromises)
}
// If no change
// We hardcode the expected result to avoid repetition
const expectedFindManyPostModelIfNoChange = [
  {
    id: '1',
    published: null,
  },
  {
    id: '2',
    published: null,
  },
]
const expectedFindManyCategoryModelIfNoChange = [
  {
    id: '1-cat-a',
    published: null,
  },
  {
    id: '1-cat-b',
    published: null,
  },
  {
    id: '2-cat-a',
    published: null,
  },
  {
    id: '2-cat-b',
    published: null,
  },
]
const expectedFindManyCategoriesOnPostsModelIfNoChange = [
  {
    categoryId: '1-cat-a',
    postId: '1',
  },
  {
    categoryId: '1-cat-b',
    postId: '1',
  },
  {
    categoryId: '2-cat-a',
    postId: '2',
  },
  {
    categoryId: '2-cat-b',
    postId: '2',
  },
]
testMatrix.setupTestSuite(
  (suiteConfig, suiteMeta) => {
    const conditionalError = ConditionalError.new()
      .with('provider', suiteConfig.provider)
      .with('driverAdapter', suiteConfig.driverAdapter)
      // @ts-ignore
      .with('relationMode', suiteConfig.relationMode || 'foreignKeys')
    const onUpdate = suiteConfig.onUpdate
    const onDelete = suiteConfig.onDelete
    const isMongoDB = suiteConfig.provider === Providers.MONGODB
    const isRelationMode_prisma = isMongoDB || suiteConfig.relationMode === RelationModes.PRISMA
    const isRelationMode_foreignKeys = !isRelationMode_prisma
    const isSchemaUsingMap = suiteConfig.isSchemaUsingMap
    // Looking at CI results
    // 30s was often not enough for vitess
    // so we put it back to 60s for now in this case
    if (suiteConfig.driverAdapter === AdapterProviders.VITESS_8) {
      jest.setTimeout(60_000)
    }
    /**
     * m:n relationship
     */
    describeIf(!isMongoDB)('m:n mandatory (explicit) - SQL Databases', () => {
      const postModel = 'PostManyToMany'
      const categoryModel = 'CategoryManyToMany'
      const categoriesOnPostsModel = 'CategoriesOnPostsManyToMany'
      beforeEach(async () => {
        const prismaPromises = [
          prisma[categoriesOnPostsModel].deleteMany(),
          prisma[postModel].deleteMany(),
          prisma[categoryModel].deleteMany(),
        ]
        await prisma.$transaction(prismaPromises)
      })
      describe('[create]', () => {
        test('[create] category alone should succeed', async () => {
          await prisma[categoryModel].create({
            data: {
              id: '1',
            },
          })
          expect(await prisma[categoryModel].findMany()).toEqual([
            {
              id: '1',
              published: null,
            },
          ])
        })
        test('[create] post alone should succeed', async () => {
          await prisma[postModel].create({
            data: {
              id: '1',
            },
          })
          expect(await prisma[postModel].findMany()).toEqual([
            {
              id: '1',
              published: null,
            },
          ])
        })
        testIf(isRelationMode_prisma)(
          '[create] categoriesOnPostsModel with non-existing post and category id should succeed with prisma emulation',
          async () => {
            await expect(
              prisma[categoriesOnPostsModel].create({
                data: {
                  postId: '99',
                  categoryId: '99',
                },
              }),
            ).resolves.toBeTruthy()
            expect(await prisma[categoriesOnPostsModel].findMany()).toEqual([
              {
                postId: '99',
                categoryId: '99',
              },
            ])
          },
        )
        testIf(isRelationMode_foreignKeys)(
          '[create] categoriesOnPostsModel with non-existing post and category id should throw with foreignKeys',
          async () => {
            await expect(
              prisma[categoriesOnPostsModel].create({
                data: {
                  postId: '99',
                  categoryId: '99',
                },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snapshot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can be less specific here
                  `Foreign key constraint violated`
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`postId`)',
                      [Providers.SQLSERVER]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                    },
                  }),
            )
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([])
          },
        )
        test('[create] create post [nested] [create] categories [nested] [create] category should succeed', async () => {
          await prisma[postModel].create({
            data: {
              id: '1',
              categories: {
                create: [
                  {
                    category: {
                      create: {
                        id: '1-cat-a',
                      },
                    },
                  },
                ],
              },
            },
          })
          expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual([
            {
              id: '1',
              published: null,
            },
          ])
          expect(
            await prisma[categoryModel].findMany({
              orderBy: { id: 'asc' },
            }),
          ).toEqual([
            {
              id: '1-cat-a',
              published: null,
            },
          ])
          expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
            {
              categoryId: '1-cat-a',
              postId: '1',
            },
          ])
        })
      })
      describe('[update]', () => {
        beforeEach(async () => {
          await checkIfEmpty(categoryModel, postModel, categoriesOnPostsModel)
          await createXPostsWith2CategoriesSQLDb({
            count: 2,
            postModel,
          })
        })
        test('[update] (post) optional boolean field should succeed', async () => {
          await prisma[postModel].update({
            where: {
              id: '1',
            },
            data: {
              published: true,
            },
          })
          expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual([
            {
              id: '1',
              // the update
              published: true,
            },
            {
              id: '2',
              published: null,
            },
          ])
          expect(
            await prisma[categoryModel].findMany({
              orderBy: { id: 'asc' },
            }),
          ).toEqual(expectedFindManyCategoryModelIfNoChange)
          expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
            expectedFindManyCategoriesOnPostsModelIfNoChange,
          )
        })
        test('[update] (category): optional boolean field should succeed', async () => {
          await prisma[categoryModel].update({
            where: {
              id: '1-cat-a',
            },
            data: {
              published: true,
            },
          })
          expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
            expectedFindManyPostModelIfNoChange,
          )
          expect(
            await prisma[categoryModel].findMany({
              orderBy: { id: 'asc' },
            }),
          ).toEqual([
            {
              id: '1-cat-a',
              // The update
              published: true,
            },
            {
              id: '1-cat-b',
              published: null,
            },
            {
              id: '2-cat-a',
              published: null,
            },
            {
              id: '2-cat-b',
              published: null,
            },
          ])
          expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
            expectedFindManyCategoriesOnPostsModelIfNoChange,
          )
        })
        testIf(isRelationMode_foreignKeys)(
          'relationMode=foreignKeys - [update] categoriesOnPostsModel with non-existing postId should throw',
          async () => {
            await expect(
              prisma[categoriesOnPostsModel].update({
                where: {
                  postId_categoryId: {
                    categoryId: '1-cat-a',
                    postId: '1',
                  },
                },
                data: {
                  postId: '99',
                },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snapshot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can be less specific here
                  `Foreign key constraint violated`
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`postId`)',
                      [Providers.SQLSERVER]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                    },
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          },
        )
        testIf(isRelationMode_prisma)(
          'relationMode=prisma - [update] categoriesOnPostsModel with non-existing postId should succeed',
          async () => {
            // TODO! Why is it behaving the same for all actions?
            await prisma[categoriesOnPostsModel].update({
              where: {
                postId_categoryId: {
                  categoryId: '1-cat-a',
                  postId: '1',
                },
              },
              data: {
                postId: '99',
              },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-a',
                postId: '99',
              },
              {
                categoryId: '1-cat-b',
                postId: '1',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          },
        )
        testIf(isRelationMode_foreignKeys)(
          'relationMode=foreignKeys - [update] categoriesOnPostsModel with non-existing categoryId should throw',
          async () => {
            await expect(
              prisma[categoriesOnPostsModel].update({
                where: {
                  postId_categoryId: {
                    categoryId: '1-cat-a',
                    postId: '1',
                  },
                },
                data: {
                  categoryId: '99',
                },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snapshot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can be less specific here
                  `Foreign key constraint violated`
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`categoryId`)',
                      [Providers.SQLSERVER]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                    },
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          },
        )
        testIf(isRelationMode_prisma)(
          'relationMode=prisma - [update] categoriesOnPostsModel with non-existing categoryId should succeed',
          async () => {
            // TODO! Why is it behaving the same for all actions?
            await prisma[categoriesOnPostsModel].update({
              where: {
                postId_categoryId: {
                  categoryId: '1-cat-a',
                  postId: '1',
                },
              },
              data: {
                categoryId: '99',
              },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-b',
                postId: '1',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
              {
                categoryId: '99',
                postId: '1',
              },
            ])
          },
        )
        describeIf(['DEFAULT', 'Cascade'].includes(onUpdate))(`onUpdate: DEFAULT, Cascade`, () => {
          test('[update] post id should succeed', async () => {
            await prisma[postModel].update({
              where: {
                id: '1',
              },
              data: {
                id: '3',
              },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual([
              {
                id: '2',
                published: null,
              },
              {
                // The update
                id: '3',
                published: null,
              },
            ])
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-a',
                // The update
                postId: '3',
              },
              {
                categoryId: '1-cat-b',
                // The update
                postId: '3',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
          test('[update] category id should succeed', async () => {
            await prisma[categoryModel].update({
              where: {
                id: '1-cat-a',
              },
              data: {
                id: '1-cat-a-updated',
              },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual([
              {
                // The update
                id: '1-cat-a-updated',
                published: null,
              },
              {
                id: '1-cat-b',
                published: null,
              },
              {
                id: '2-cat-a',
                published: null,
              },
              {
                id: '2-cat-b',
                published: null,
              },
            ])
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                // The update
                categoryId: '1-cat-a-updated',
                postId: '1',
              },
              {
                categoryId: '1-cat-b',
                postId: '1',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
        })
        describeIf(['Restrict', 'NoAction'].includes(onUpdate))(`onUpdate: Restrict, NoAction`, () => {
          test('[update] post id should throw', async () => {
            await expect(
              prisma[postModel].update({
                where: {
                  id: '1',
                },
                data: {
                  id: '3',
                },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snapshot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can ignore the error message here
                  undefined
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`postId`)',
                      [Providers.SQLSERVER]:
                        onUpdate === 'Restrict'
                          ? // Restrict
                            'Foreign key constraint violated on the fields: (`postId`)'
                          : // NoAction
                            'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                    },
                    prisma:
                      "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToPostManyToMany' between the `CategoriesOnPostsManyToMany` and `PostManyToMany` models.",
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          })
          test('[update] category id should throw', async () => {
            await expect(
              prisma[categoryModel].update({
                where: {
                  id: '1-cat-a',
                },
                data: {
                  id: '1-cat-a-updated',
                },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snapshot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can ignore the error message here
                  undefined
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`categoryId`)',
                      [Providers.SQLSERVER]:
                        onUpdate === 'Restrict'
                          ? // Restrict
                            'Foreign key constraint violated on the fields: (`postId`)'
                          : // NoAction
                            'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                    },
                    prisma:
                      "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToCategoryManyToMany' between the `CategoriesOnPostsManyToMany` and `CategoryManyToMany` models.",
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          })
        })
        describeIf(['SetNull', 'SetDefault'].includes(onUpdate))(`onUpdate: SetNull, SetDefault`, () => {
          test('[update] post id should succeed', async () => {
            await prisma[postModel].update({
              where: {
                id: '1',
              },
              data: {
                id: '3',
              },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual([
              {
                id: '2',
                published: null,
              },
              {
                id: '3',
                published: null,
              },
            ])
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-a',
                postId: '3',
              },
              {
                categoryId: '1-cat-b',
                postId: '3',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
          test('[update] category id should succeed', async () => {
            const result = await prisma[categoryModel].update({
              where: {
                id: '1-cat-a',
              },
              data: {
                id: '1-cat-a-updated',
              },
            })
            expect(result).toMatchObject({ id: '1-cat-a-updated', published: null })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual([
              {
                id: '1-cat-a-updated',
                published: null,
              },
              {
                id: '1-cat-b',
                published: null,
              },
              {
                id: '2-cat-a',
                published: null,
              },
              {
                id: '2-cat-b',
                published: null,
              },
            ])
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-a-updated',
                postId: '1',
              },
              {
                categoryId: '1-cat-b',
                postId: '1',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
        })
        test('[update] categoriesOnPostsModel postId should succeed', async () => {
          await prisma[categoriesOnPostsModel].update({
            where: {
              postId_categoryId: {
                categoryId: '1-cat-a',
                postId: '1',
              },
            },
            data: {
              postId: '2',
            },
          })
          expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
            expectedFindManyPostModelIfNoChange,
          )
          expect(
            await prisma[categoryModel].findMany({
              orderBy: { id: 'asc' },
            }),
          ).toEqual(expectedFindManyCategoryModelIfNoChange)
          expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
            {
              categoryId: '1-cat-a',
              // the updated postId
              postId: '2',
            },
            {
              categoryId: '1-cat-b',
              postId: '1',
            },
            {
              categoryId: '2-cat-a',
              postId: '2',
            },
            {
              categoryId: '2-cat-b',
              postId: '2',
            },
          ])
        })
      })
      describe('[delete]', () => {
        beforeEach(async () => {
          await checkIfEmpty(categoryModel, postModel, categoriesOnPostsModel)
          await createXPostsWith2CategoriesSQLDb({
            count: 2,
            postModel,
          })
        })
        describeIf(['DEFAULT', 'Restrict', 'NoAction'].includes(onDelete))(
          `onDelete: DEFAULT, Restrict, NoAction`,
          () => {
            test('[delete] post should throw', async () => {
              await expect(
                prisma[postModel].delete({
                  where: { id: '1' },
                }),
              ).rejects.toThrow(
                isSchemaUsingMap
                  ? // The snaphsot changes when using @@map/@map, though only the name of the table/field is different
                    // So we can ignore the error message here
                    undefined
                  : conditionalError.snapshot({
                      foreignKeys: {
                        [Providers.POSTGRESQL]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                        [Providers.COCKROACHDB]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                        [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`postId`)',
                        [Providers.SQLSERVER]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                        [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                        [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                      },
                      prisma:
                        "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToPostManyToMany' between the `CategoriesOnPostsManyToMany` and `PostManyToMany` models.",
                    }),
              )
              expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
                expectedFindManyPostModelIfNoChange,
              )
              expect(
                await prisma[categoryModel].findMany({
                  orderBy: { id: 'asc' },
                }),
              ).toEqual(expectedFindManyCategoryModelIfNoChange)
              expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
                expectedFindManyCategoriesOnPostsModelIfNoChange,
              )
            })
            test('[delete] category should throw', async () => {
              await expect(
                prisma[categoryModel].delete({
                  where: { id: '1-cat-a' },
                }),
              ).rejects.toThrow(
                isSchemaUsingMap
                  ? // The snaphsot changes when using @@map/@map, though only the name of the table/field is different
                    // So we can ignore the error message here
                    undefined
                  : conditionalError.snapshot({
                      foreignKeys: {
                        [Providers.POSTGRESQL]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                        [Providers.COCKROACHDB]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                        [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`categoryId`)',
                        [Providers.SQLSERVER]:
                          'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                        [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                        [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                      },
                      prisma:
                        "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToCategoryManyToMany' between the `CategoriesOnPostsManyToMany` and `CategoryManyToMany` models.",
                    }),
              )
              expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
                expectedFindManyPostModelIfNoChange,
              )
              expect(
                await prisma[categoryModel].findMany({
                  orderBy: { id: 'asc' },
                }),
              ).toEqual(expectedFindManyCategoryModelIfNoChange)
              expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
                expectedFindManyCategoriesOnPostsModelIfNoChange,
              )
            })
          },
        )
        // TODO check why SetDefault works because we don't have @default in the schema
        // Note: The test suite does not test `SetNull` with providers that errors during migration
        // see _utils/relationMode/computeMatrix.ts
        describeIf(['SetNull', 'SetDefault'].includes(onDelete))(`onDelete: SetNull, SetDefault`, () => {
          test('[delete] post should throw', async () => {
            await expect(
              prisma[postModel].delete({
                where: { id: '1' },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snaphsot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can ignore the error message here
                  undefined
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`postId`)',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                      [Providers.SQLSERVER]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_postId_fkey`',
                    },
                    prisma:
                      "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToPostManyToMany' between the `CategoriesOnPostsManyToMany` and `PostManyToMany` models.",
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          })
          test('[delete] category should throw', async () => {
            await expect(
              prisma[categoryModel].delete({
                where: { id: '1-cat-a' },
              }),
            ).rejects.toThrow(
              isSchemaUsingMap
                ? // The snaphsot changes when using @@map/@map, though only the name of the table/field is different
                  // So we can ignore the error message here
                  undefined
                : conditionalError.snapshot({
                    foreignKeys: {
                      [Providers.POSTGRESQL]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.MYSQL]: 'Foreign key constraint violated on the fields: (`categoryId`)',
                      [Providers.SQLITE]: 'Foreign key constraint violated on the foreign key',
                      [AdapterProviders.JS_D1]: 'D1_ERROR: FOREIGN KEY constraint failed',
                      [Providers.SQLSERVER]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                      [Providers.COCKROACHDB]:
                        'Foreign key constraint violated on the constraint: `CategoriesOnPostsManyToMany_categoryId_fkey`',
                    },
                    prisma:
                      "The change you are trying to make would violate the required relation 'CategoriesOnPostsManyToManyToCategoryManyToMany' between the `CategoriesOnPostsManyToMany` and `CategoryManyToMany` models.",
                  }),
            )
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual(
              expectedFindManyCategoriesOnPostsModelIfNoChange,
            )
          })
        })
        describeIf(['Cascade'].includes(onDelete))('onDelete: Cascade', () => {
          test('[delete] post should succeed', async () => {
            await prisma[postModel].delete({
              where: { id: '1' },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual([
              {
                id: '2',
                published: null,
              },
            ])
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual(expectedFindManyCategoryModelIfNoChange)
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
          test('[delete] category should succeed', async () => {
            await prisma[categoryModel].delete({
              where: { id: '1-cat-a' },
            })
            expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
              expectedFindManyPostModelIfNoChange,
            )
            expect(
              await prisma[categoryModel].findMany({
                orderBy: { id: 'asc' },
              }),
            ).toEqual([
              {
                id: '1-cat-b',
                published: null,
              },
              {
                id: '2-cat-a',
                published: null,
              },
              {
                id: '2-cat-b',
                published: null,
              },
            ])
            expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
              {
                categoryId: '1-cat-b',
                postId: '1',
              },
              {
                categoryId: '2-cat-a',
                postId: '2',
              },
              {
                categoryId: '2-cat-b',
                postId: '2',
              },
            ])
          })
        })
        test('[delete] categoriesOnPosts should succeed', async () => {
          await prisma[categoriesOnPostsModel].delete({
            where: {
              postId_categoryId: {
                categoryId: '1-cat-a',
                postId: '1',
              },
            },
          })
          expect(await prisma[postModel].findMany({ orderBy: { id: 'asc' } })).toEqual(
            expectedFindManyPostModelIfNoChange,
          )
          expect(
            await prisma[categoryModel].findMany({
              orderBy: { id: 'asc' },
            }),
          ).toEqual(expectedFindManyCategoryModelIfNoChange)
          expect(await prisma[categoriesOnPostsModel].findMany({ orderBy: { categoryId: 'asc' } })).toEqual([
            {
              categoryId: '1-cat-b',
              postId: '1',
            },
            {
              categoryId: '2-cat-a',
              postId: '2',
            },
            {
              categoryId: '2-cat-b',
              postId: '2',
            },
          ])
        })
      })
    })
  },
  // Use `optOut` to opt out from testing the default selected providers
  // otherwise the suite will require all providers to be specified.
  {
    optOut: {
      from: [
        Providers.MONGODB,
        Providers.SQLSERVER,
        Providers.MYSQL,
        Providers.POSTGRESQL,
        Providers.COCKROACHDB,
        Providers.SQLITE,
      ],
      reason: 'Only testing xyz provider(s) so opting out of xxx',
    },
  },
)