prismock icon indicating copy to clipboard operation
prismock copied to clipboard

Nested updates not enforcing AND clause

Open JoeRoddy opened this issue 6 months ago • 1 comments

Again, great work on this library! It is massively valuable!

We're running into an issue with prismock not enforcing an AND clause in nested updates. (It might also have something to do with nesting some's and OR's inside of it)

Imagine a schema with user groups, and groupRoles for permissions. Psuedocode, but I think you'll get the idea

model User {}

model Group {
  users User[]
  groupRoles GroupRole[]
}

model GroupRole {
  // Owner or Member
  role String 
  userId String
  user User
  groupId String
  group Group
}

We run the following code:

  // create a group with an owner (admin) and a member
  const group = await db.group.create({
    data: {
      groupRoles: {
        create: [
          {
            role: 'Owner',
            userId: user1.id,
          },
          {
            role: 'Member',
            userId: user2.id,
          },
        ],
      },
    },
  });

  const user2Role = await db.groupRole.findFirst(...)  

  const userMakingQuery = user2;

   // update a group role, should only work if the user performing the query is the grp owner
   await db.group.update({
    where: { id: group.id },
    data: {
      groupRoles: {
        update: {
          data: { role: 'Owner' },
          where: {
            id: user2Role.id,
            // the following enforces that only group owners may manage group roles
            // if the user is not the group owner, this query should fail
            AND: [
              {
                group: {
                  groupRoles: {
                    some: {
                      OR: [{ role: 'Owner', userId: userMakingQuery.id }],
                    },
                  },
                },
              },
            ],
          },
        },
      },
    },
  });

The AND clause in question may look odd (nesting AND, OR, some, etc), but changing it is not really an option. The query is dynamically build by our Authorization library Casl

When we run the above code with Prisma, we get an error (desired behavior):

Invalid `prisma.group.update()` invocation:

An operation failed because it depends on one or more records that were required but not found. No 'GroupRole' record was found for a nested update on relation 'GroupToGroupRole'.

When we run it with Prismock, there is no error, and we're able to validate that the update persisted. (undesired, inconsistent wiht Prisma)

JoeRoddy avatar Aug 22 '24 16:08 JoeRoddy