From 50742fca01877f33c2473f48ef38f79dab423a7c Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:08:55 -0700 Subject: [PATCH] test(regression): add regression test for issue #2410 Verify that PolicyPlugin generates valid SQL when related models share identical field names both protected by @deny rules. Co-Authored-By: Claude Sonnet 4.6 --- tests/regression/test/issue-2410.test.ts | 74 ++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tests/regression/test/issue-2410.test.ts diff --git a/tests/regression/test/issue-2410.test.ts b/tests/regression/test/issue-2410.test.ts new file mode 100644 index 000000000..8840a8b5f --- /dev/null +++ b/tests/regression/test/issue-2410.test.ts @@ -0,0 +1,74 @@ +import { createPolicyTestClient } from '@zenstackhq/testtools'; +import { describe, expect, it } from 'vitest'; + +// https://github.com/zenstackhq/zenstack/issues/2410 +describe('Regression for issue #2410', () => { + it('should not generate invalid SQL when related models share identical @deny field names', async () => { + const db = await createPolicyTestClient( + ` +model User { + id String @id @default(cuid()) + role String + + @@allow('all', true) +} + +model Thread { + id String @id @default(cuid()) + title String + apiKeyId String @deny('all', auth().role != 'ADMIN') + questions Question[] + + @@allow('all', true) +} + +model Question { + id String @id @default(cuid()) + content String + apiKeyId String @deny('all', auth().role != 'ADMIN') + threadId String + thread Thread @relation(fields: [threadId], references: [id]) + + @@allow('all', true) +} + `, + ); + + const admin = { id: 'admin-1', role: 'ADMIN' }; + const user = { id: 'user-1', role: 'USER' }; + + const thread = await db.$setAuth(admin).thread.create({ + data: { + title: 'Test Thread', + apiKeyId: 'key-1', + questions: { + create: [{ content: 'Q1', apiKeyId: 'key-1' }], + }, + }, + }); + + // updating a non-denied field on the Thread should succeed for any role + await expect( + db.$setAuth(user).thread.update({ + where: { id: thread.id }, + data: { title: 'Updated Thread' }, + }), + ).toResolveTruthy(); + + // updating a denied field should be rejected for non-admin + await expect( + db.$setAuth(user).thread.update({ + where: { id: thread.id }, + data: { apiKeyId: 'key-2' }, + }), + ).toBeRejectedByPolicy(); + + // updating a denied field should succeed for admin + await expect( + db.$setAuth(admin).thread.update({ + where: { id: thread.id }, + data: { apiKeyId: 'key-2' }, + }), + ).toResolveTruthy(); + }); +});