From 30f35992cc74836800fe980de3b20c75174d0c8e Mon Sep 17 00:00:00 2001 From: Alessandro Magionami Date: Tue, 7 Jan 2025 16:42:12 +0100 Subject: [PATCH 1/4] feat(workspaces): filter discoverable workspaces with existing requests --- .../workspaces/repositories/workspaces.ts | 7 + .../tests/integration/repositories.spec.ts | 591 ++++++++++-------- 2 files changed, 330 insertions(+), 268 deletions(-) diff --git a/packages/server/modules/workspaces/repositories/workspaces.ts b/packages/server/modules/workspaces/repositories/workspaces.ts index 8741096b08..ec33dd4725 100644 --- a/packages/server/modules/workspaces/repositories/workspaces.ts +++ b/packages/server/modules/workspaces/repositories/workspaces.ts @@ -38,6 +38,7 @@ import { WorkspaceInvalidRoleError } from '@/modules/workspaces/errors/workspace import { WorkspaceAcl as DbWorkspaceAcl, WorkspaceDomains, + WorkspaceJoinRequests, Workspaces } from '@/modules/workspaces/helpers/db' import { @@ -93,6 +94,12 @@ export const getUserDiscoverableWorkspacesFactory = 'acl.workspaceId', 'workspaces.id' ) + .leftJoin( + WorkspaceJoinRequests.name, + WorkspaceJoinRequests.col.workspaceId, + Workspaces.col.id + ) + .whereNull(WorkspaceJoinRequests.col.workspaceId) .whereIn('domain', domains) .where('discoverabilityEnabled', true) .where('verified', true) diff --git a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts index 4e6b2201b2..24e0099dd3 100644 --- a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts @@ -43,6 +43,7 @@ import { } from '@/modules/core/repositories/streams' import { omit } from 'lodash' import { createAndStoreTestWorkspaceFactory } from '@/test/speckle-helpers/workspaces' +import { WorkspaceJoinRequests } from '@/modules/workspacesCore/helpers/db' const getWorkspace = getWorkspaceFactory({ db }) const getWorkspaceBySlug = getWorkspaceBySlugFactory({ db }) @@ -771,317 +772,371 @@ describe('Workspace repositories', () => { expect(workspaces.length).to.equal(1) }) - }) - describe('getWorkspaceDomainsFactory creates a function, that', () => { - it('returns a workspace with domains', async () => { - const user = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomPassword() - } - await createTestUser(user) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: user.id - } - await createTestWorkspace(workspace, user) + it('should not return discoverable workspaces with existing requests for the user', async () => { + const user = await createAndStoreTestUser() + await updateUserEmail({ + query: { + email: user.email + }, + update: { + verified: true + } + }) - await storeWorkspaceDomainFactory({ db })({ + const workspace = await createAndStoreTestWorkspace({ + discoverabilityEnabled: true + }) + await storeWorkspaceDomain({ workspaceDomain: { - id: createRandomPassword(), + id: cryptoRandomString({ length: 6 }), domain: 'example.org', - verified: true, workspaceId: workspace.id, + verified: true, + createdAt: new Date(), + updatedAt: new Date(), + createdByUserId: user.id + } + }) + const workspaceWithExistingRequest = await createAndStoreTestWorkspace({ + discoverabilityEnabled: true + }) + await storeWorkspaceDomain({ + workspaceDomain: { + id: cryptoRandomString({ length: 6 }), + domain: 'example.org', + workspaceId: workspaceWithExistingRequest.id, + verified: true, createdAt: new Date(), updatedAt: new Date(), createdByUserId: user.id } }) - const workspaceWithDomains = await getWorkspaceWithDomainsFactory({ db })({ - id: workspace.id + await db(WorkspaceJoinRequests.name).insert({ + workspaceId: workspaceWithExistingRequest.id, + userId: user.id, + createdAt: new Date(), + status: 'pending' }) - expect(workspaceWithDomains?.domains.length).to.eq(1) + + const workspaces = await getUserDiscoverableWorkspaces({ + domains: ['example.org'], + userId: user.id + }) + + expect(workspaces.length).to.equal(1) }) }) +}) - describe('countWorkspaceRoleWithOptionalProjectRoleFactory returns a function, that', () => { - it('counts workspace roles by userId', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace, admin) +describe('getWorkspaceDomainsFactory creates a function, that', () => { + it('returns a workspace with domains', async () => { + const user = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomPassword() + } + await createTestUser(user) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: user.id + } + await createTestWorkspace(workspace, user) - // just another workspace, for testing if workspaceId filter works - const workspace2 = { + await storeWorkspaceDomainFactory({ db })({ + workspaceDomain: { id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id + domain: 'example.org', + verified: true, + workspaceId: workspace.id, + createdAt: new Date(), + updatedAt: new Date(), + createdByUserId: user.id } - await createTestWorkspace(workspace2, admin) + }) + const workspaceWithDomains = await getWorkspaceWithDomainsFactory({ db })({ + id: workspace.id + }) + expect(workspaceWithDomains?.domains.length).to.eq(1) + }) +}) - const admin2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin2) - await assignToWorkspace(workspace, admin2, Roles.Workspace.Admin) +describe('countWorkspaceRoleWithOptionalProjectRoleFactory returns a function, that', () => { + it('counts workspace roles by userId', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace, admin) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace, member, Roles.Workspace.Member) - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Admin - }) - expect(count).to.equal(2) + // just another workspace, for testing if workspaceId filter works + const workspace2 = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace2, admin) - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Member - }) - expect(count).to.equal(1) - }) - it('counts workspace roles with a project role filter', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } + const admin2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin2) + await assignToWorkspace(workspace, admin2, Roles.Workspace.Admin) - await createTestWorkspace(workspace, admin) + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace, member, Roles.Workspace.Member) + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Admin + }) + expect(count).to.equal(2) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace, member, Roles.Workspace.Member) + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Member + }) + expect(count).to.equal(1) + }) + it('counts workspace roles with a project role filter', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } - const member2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member2) - await assignToWorkspace(workspace, member2, Roles.Workspace.Member) - - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace.id - } - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: member.id, - workspaceId: workspace.id - } + await createTestWorkspace(workspace, admin) - const project3 = { - id: createRandomString(), - name: 'test stream 3', - isPublic: true, - ownerId: member.id, - workspaceId: workspace.id - } - await createTestStream(project1, admin) - await createTestStream(project2, member) - await createTestStream(project3, member2) + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace, member, Roles.Workspace.Member) - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Admin, - projectRole: Roles.Stream.Owner - }) - expect(count).to.equal(1) + const member2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member2) + await assignToWorkspace(workspace, member2, Roles.Workspace.Member) + + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace.id + } + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: member.id, + workspaceId: workspace.id + } - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Member, - projectRole: Roles.Stream.Owner - }) - expect(count).to.equal(2) + const project3 = { + id: createRandomString(), + name: 'test stream 3', + isPublic: true, + ownerId: member.id, + workspaceId: workspace.id + } + await createTestStream(project1, admin) + await createTestStream(project2, member) + await createTestStream(project3, member2) + + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Admin, + projectRole: Roles.Stream.Owner }) - it('does not count project roles, that are not in the workspace', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace, admin) + expect(count).to.equal(1) - const guest = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(guest) - await assignToWorkspace(workspace, guest, Roles.Workspace.Guest) + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Member, + projectRole: Roles.Stream.Owner + }) + expect(count).to.equal(2) + }) + it('does not count project roles, that are not in the workspace', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace, admin) - const guest2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(guest2) - await assignToWorkspace(workspace, guest2, Roles.Workspace.Guest) - - // only project 1 is in the workspace - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace.id - } - // this is not in the workspace, roles here should not count - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: guest.id - } + const guest = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(guest) + await assignToWorkspace(workspace, guest, Roles.Workspace.Guest) - await createTestStream(project1, admin) - await createTestStream(project2, guest) + const guest2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(guest2) + await assignToWorkspace(workspace, guest2, Roles.Workspace.Guest) + + // only project 1 is in the workspace + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace.id + } + // this is not in the workspace, roles here should not count + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: guest.id + } - // adding project roles to guests - await upsertProjectRole({ - role: Roles.Stream.Contributor, - projectId: project1.id, - userId: guest.id - }) + await createTestStream(project1, admin) + await createTestStream(project2, guest) - await upsertProjectRole({ - role: Roles.Stream.Reviewer, - projectId: project1.id, - userId: guest2.id - }) + // adding project roles to guests + await upsertProjectRole({ + role: Roles.Stream.Contributor, + projectId: project1.id, + userId: guest.id + }) - // adding contributor to guest 2 on project 2 - await upsertProjectRole({ - role: Roles.Stream.Contributor, - projectId: project2.id, - userId: guest2.id - }) + await upsertProjectRole({ + role: Roles.Stream.Reviewer, + projectId: project1.id, + userId: guest2.id + }) - const count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor - }) - // checking that the non workspace project doesn't leak into the counts - expect(count).to.equal(1) + // adding contributor to guest 2 on project 2 + await upsertProjectRole({ + role: Roles.Stream.Contributor, + projectId: project2.id, + userId: guest2.id }) - it('does not count roles from other workspaces when filtering by project role too', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace1 = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace1, admin) - const workspace2 = { - id: createRandomPassword(), - name: 'my workspace 2', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace2, admin) + const count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor + }) + // checking that the non workspace project doesn't leak into the counts + expect(count).to.equal(1) + }) + it('does not count roles from other workspaces when filtering by project role too', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace1 = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace1, admin) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace1, member, Roles.Workspace.Member) - // member becomes a guest in the other workspace and it leaks back into the first - await assignToWorkspace(workspace2, member, Roles.Workspace.Guest) - - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace1.id - } - // this is not in the workspace, roles here should not count - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace2.id - } + const workspace2 = { + id: createRandomPassword(), + name: 'my workspace 2', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace2, admin) - await createTestStream(project1, admin) - await createTestStream(project2, admin) + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace1, member, Roles.Workspace.Member) + // member becomes a guest in the other workspace and it leaks back into the first + await assignToWorkspace(workspace2, member, Roles.Workspace.Guest) + + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace1.id + } + // this is not in the workspace, roles here should not count + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace2.id + } - await grantStreamPermissions({ - role: Roles.Stream.Contributor, - streamId: project2.id, - userId: member.id - }) + await createTestStream(project1, admin) + await createTestStream(project2, admin) - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace1.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor - }) + await grantStreamPermissions({ + role: Roles.Stream.Contributor, + streamId: project2.id, + userId: member.id + }) - expect(count).to.equal(0) + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace1.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor + }) - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace2.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor - }) + expect(count).to.equal(0) - expect(count).to.equal(1) + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace2.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor }) + + expect(count).to.equal(1) }) }) From 844133f435c470dab8351bc2b82445b503fd3c1f Mon Sep 17 00:00:00 2001 From: Alessandro Magionami Date: Tue, 7 Jan 2025 17:34:12 +0100 Subject: [PATCH 2/4] feat(workspaces): fix query --- .../workspaces/repositories/workspaces.ts | 18 ++++++++++++------ .../tests/integration/repositories.spec.ts | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/server/modules/workspaces/repositories/workspaces.ts b/packages/server/modules/workspaces/repositories/workspaces.ts index ec33dd4725..6adb2c56c8 100644 --- a/packages/server/modules/workspaces/repositories/workspaces.ts +++ b/packages/server/modules/workspaces/repositories/workspaces.ts @@ -2,6 +2,7 @@ import { Workspace, WorkspaceAcl, WorkspaceDomain, + WorkspaceJoinRequest, WorkspaceWithOptionalRole } from '@/modules/workspacesCore/domain/types' import { @@ -38,7 +39,6 @@ import { WorkspaceInvalidRoleError } from '@/modules/workspaces/errors/workspace import { WorkspaceAcl as DbWorkspaceAcl, WorkspaceDomains, - WorkspaceJoinRequests, Workspaces } from '@/modules/workspaces/helpers/db' import { @@ -68,7 +68,9 @@ const tables = { workspaceDomains: (db: Knex) => db('workspace_domains'), workspacesAcl: (db: Knex) => db('workspace_acl'), workspaceCreationState: (db: Knex) => - db('workspace_creation_state') + db('workspace_creation_state'), + workspaceJoinRequests: (db: Knex) => + db('workspace_join_requests') } export const getUserDiscoverableWorkspacesFactory = @@ -95,11 +97,15 @@ export const getUserDiscoverableWorkspacesFactory = 'workspaces.id' ) .leftJoin( - WorkspaceJoinRequests.name, - WorkspaceJoinRequests.col.workspaceId, - Workspaces.col.id + tables + .workspaceJoinRequests(db) + .select('*') + .where({ userId }) + .as('joinRequest'), + 'joinRequest.workspaceId', + 'workspaces.id' ) - .whereNull(WorkspaceJoinRequests.col.workspaceId) + .whereNull('joinRequest.workspaceId') .whereIn('domain', domains) .where('discoverabilityEnabled', true) .where('verified', true) diff --git a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts index 24e0099dd3..91d1dd38c8 100644 --- a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts @@ -773,7 +773,7 @@ describe('Workspace repositories', () => { expect(workspaces.length).to.equal(1) }) - it('should not return discoverable workspaces with existing requests for the user', async () => { + it.only('should not return discoverable workspaces with existing requests for the user', async () => { const user = await createAndStoreTestUser() await updateUserEmail({ query: { @@ -783,6 +783,15 @@ describe('Workspace repositories', () => { verified: true } }) + const otherUser = await createAndStoreTestUser() + await updateUserEmail({ + query: { + email: otherUser.email + }, + update: { + verified: true + } + }) const workspace = await createAndStoreTestWorkspace({ discoverabilityEnabled: true @@ -798,6 +807,13 @@ describe('Workspace repositories', () => { createdByUserId: user.id } }) + // existing request for other user + await db(WorkspaceJoinRequests.name).insert({ + workspaceId: workspace.id, + userId: otherUser.id, + createdAt: new Date(), + status: 'pending' + }) const workspaceWithExistingRequest = await createAndStoreTestWorkspace({ discoverabilityEnabled: true }) From c25418a1d207c158bd952efec477f6e284682f53 Mon Sep 17 00:00:00 2001 From: Alessandro Magionami Date: Thu, 9 Jan 2025 09:49:39 +0100 Subject: [PATCH 3/4] feat(workspaces): test indentation fix --- .../tests/integration/repositories.spec.ts | 558 +++++++++--------- 1 file changed, 279 insertions(+), 279 deletions(-) diff --git a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts index 91d1dd38c8..1588ef0026 100644 --- a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts @@ -773,7 +773,7 @@ describe('Workspace repositories', () => { expect(workspaces.length).to.equal(1) }) - it.only('should not return discoverable workspaces with existing requests for the user', async () => { + it('should not return discoverable workspaces with existing requests for the user', async () => { const user = await createAndStoreTestUser() await updateUserEmail({ query: { @@ -843,316 +843,316 @@ describe('Workspace repositories', () => { expect(workspaces.length).to.equal(1) }) }) -}) - -describe('getWorkspaceDomainsFactory creates a function, that', () => { - it('returns a workspace with domains', async () => { - const user = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomPassword() - } - await createTestUser(user) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: user.id - } - await createTestWorkspace(workspace, user) - await storeWorkspaceDomainFactory({ db })({ - workspaceDomain: { + describe('getWorkspaceDomainsFactory creates a function, that', () => { + it('returns a workspace with domains', async () => { + const user = { id: createRandomPassword(), - domain: 'example.org', - verified: true, - workspaceId: workspace.id, - createdAt: new Date(), - updatedAt: new Date(), - createdByUserId: user.id + name: createRandomPassword(), + email: createRandomPassword() } + await createTestUser(user) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: user.id + } + await createTestWorkspace(workspace, user) + + await storeWorkspaceDomainFactory({ db })({ + workspaceDomain: { + id: createRandomPassword(), + domain: 'example.org', + verified: true, + workspaceId: workspace.id, + createdAt: new Date(), + updatedAt: new Date(), + createdByUserId: user.id + } + }) + const workspaceWithDomains = await getWorkspaceWithDomainsFactory({ db })({ + id: workspace.id + }) + expect(workspaceWithDomains?.domains.length).to.eq(1) }) - const workspaceWithDomains = await getWorkspaceWithDomainsFactory({ db })({ - id: workspace.id - }) - expect(workspaceWithDomains?.domains.length).to.eq(1) }) -}) -describe('countWorkspaceRoleWithOptionalProjectRoleFactory returns a function, that', () => { - it('counts workspace roles by userId', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace, admin) + describe('countWorkspaceRoleWithOptionalProjectRoleFactory returns a function, that', () => { + it('counts workspace roles by userId', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace, admin) - // just another workspace, for testing if workspaceId filter works - const workspace2 = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace2, admin) + // just another workspace, for testing if workspaceId filter works + const workspace2 = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace2, admin) - const admin2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin2) - await assignToWorkspace(workspace, admin2, Roles.Workspace.Admin) + const admin2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin2) + await assignToWorkspace(workspace, admin2, Roles.Workspace.Admin) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace, member, Roles.Workspace.Member) - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Admin - }) - expect(count).to.equal(2) + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace, member, Roles.Workspace.Member) + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Admin + }) + expect(count).to.equal(2) - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Member + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Member + }) + expect(count).to.equal(1) }) - expect(count).to.equal(1) - }) - it('counts workspace roles with a project role filter', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } + it('counts workspace roles with a project role filter', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } - await createTestWorkspace(workspace, admin) + await createTestWorkspace(workspace, admin) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace, member, Roles.Workspace.Member) + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace, member, Roles.Workspace.Member) - const member2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member2) - await assignToWorkspace(workspace, member2, Roles.Workspace.Member) - - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace.id - } - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: member.id, - workspaceId: workspace.id - } + const member2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member2) + await assignToWorkspace(workspace, member2, Roles.Workspace.Member) + + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace.id + } + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: member.id, + workspaceId: workspace.id + } - const project3 = { - id: createRandomString(), - name: 'test stream 3', - isPublic: true, - ownerId: member.id, - workspaceId: workspace.id - } - await createTestStream(project1, admin) - await createTestStream(project2, member) - await createTestStream(project3, member2) - - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Admin, - projectRole: Roles.Stream.Owner - }) - expect(count).to.equal(1) + const project3 = { + id: createRandomString(), + name: 'test stream 3', + isPublic: true, + ownerId: member.id, + workspaceId: workspace.id + } + await createTestStream(project1, admin) + await createTestStream(project2, member) + await createTestStream(project3, member2) - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Member, - projectRole: Roles.Stream.Owner + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Admin, + projectRole: Roles.Stream.Owner + }) + expect(count).to.equal(1) + + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Member, + projectRole: Roles.Stream.Owner + }) + expect(count).to.equal(2) }) - expect(count).to.equal(2) - }) - it('does not count project roles, that are not in the workspace', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace, admin) + it('does not count project roles, that are not in the workspace', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace, admin) - const guest = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(guest) - await assignToWorkspace(workspace, guest, Roles.Workspace.Guest) + const guest = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(guest) + await assignToWorkspace(workspace, guest, Roles.Workspace.Guest) - const guest2 = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(guest2) - await assignToWorkspace(workspace, guest2, Roles.Workspace.Guest) - - // only project 1 is in the workspace - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace.id - } - // this is not in the workspace, roles here should not count - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: guest.id - } + const guest2 = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(guest2) + await assignToWorkspace(workspace, guest2, Roles.Workspace.Guest) + + // only project 1 is in the workspace + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace.id + } + // this is not in the workspace, roles here should not count + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: guest.id + } - await createTestStream(project1, admin) - await createTestStream(project2, guest) + await createTestStream(project1, admin) + await createTestStream(project2, guest) - // adding project roles to guests - await upsertProjectRole({ - role: Roles.Stream.Contributor, - projectId: project1.id, - userId: guest.id - }) + // adding project roles to guests + await upsertProjectRole({ + role: Roles.Stream.Contributor, + projectId: project1.id, + userId: guest.id + }) - await upsertProjectRole({ - role: Roles.Stream.Reviewer, - projectId: project1.id, - userId: guest2.id - }) + await upsertProjectRole({ + role: Roles.Stream.Reviewer, + projectId: project1.id, + userId: guest2.id + }) - // adding contributor to guest 2 on project 2 - await upsertProjectRole({ - role: Roles.Stream.Contributor, - projectId: project2.id, - userId: guest2.id - }) + // adding contributor to guest 2 on project 2 + await upsertProjectRole({ + role: Roles.Stream.Contributor, + projectId: project2.id, + userId: guest2.id + }) - const count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor + const count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor + }) + // checking that the non workspace project doesn't leak into the counts + expect(count).to.equal(1) }) - // checking that the non workspace project doesn't leak into the counts - expect(count).to.equal(1) - }) - it('does not count roles from other workspaces when filtering by project role too', async () => { - const admin = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(admin) - const workspace1 = { - id: createRandomPassword(), - name: 'my workspace', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace1, admin) + it('does not count roles from other workspaces when filtering by project role too', async () => { + const admin = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(admin) + const workspace1 = { + id: createRandomPassword(), + name: 'my workspace', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace1, admin) - const workspace2 = { - id: createRandomPassword(), - name: 'my workspace 2', - slug: cryptoRandomString({ length: 10 }), - ownerId: admin.id - } - await createTestWorkspace(workspace2, admin) + const workspace2 = { + id: createRandomPassword(), + name: 'my workspace 2', + slug: cryptoRandomString({ length: 10 }), + ownerId: admin.id + } + await createTestWorkspace(workspace2, admin) - const member = { - id: createRandomPassword(), - name: createRandomPassword(), - email: createRandomEmail() - } - await createTestUser(member) - await assignToWorkspace(workspace1, member, Roles.Workspace.Member) - // member becomes a guest in the other workspace and it leaks back into the first - await assignToWorkspace(workspace2, member, Roles.Workspace.Guest) - - const project1 = { - id: createRandomString(), - name: 'test stream', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace1.id - } - // this is not in the workspace, roles here should not count - const project2 = { - id: createRandomString(), - name: 'test stream 2', - isPublic: true, - ownerId: admin.id, - workspaceId: workspace2.id - } + const member = { + id: createRandomPassword(), + name: createRandomPassword(), + email: createRandomEmail() + } + await createTestUser(member) + await assignToWorkspace(workspace1, member, Roles.Workspace.Member) + // member becomes a guest in the other workspace and it leaks back into the first + await assignToWorkspace(workspace2, member, Roles.Workspace.Guest) + + const project1 = { + id: createRandomString(), + name: 'test stream', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace1.id + } + // this is not in the workspace, roles here should not count + const project2 = { + id: createRandomString(), + name: 'test stream 2', + isPublic: true, + ownerId: admin.id, + workspaceId: workspace2.id + } - await createTestStream(project1, admin) - await createTestStream(project2, admin) + await createTestStream(project1, admin) + await createTestStream(project2, admin) - await grantStreamPermissions({ - role: Roles.Stream.Contributor, - streamId: project2.id, - userId: member.id - }) + await grantStreamPermissions({ + role: Roles.Stream.Contributor, + streamId: project2.id, + userId: member.id + }) - let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace1.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor - }) + let count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace1.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor + }) - expect(count).to.equal(0) + expect(count).to.equal(0) - count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ - workspaceId: workspace2.id, - workspaceRole: Roles.Workspace.Guest, - projectRole: Roles.Stream.Contributor - }) + count = await countWorkspaceRoleWithOptionalProjectRoleFactory({ db })({ + workspaceId: workspace2.id, + workspaceRole: Roles.Workspace.Guest, + projectRole: Roles.Stream.Contributor + }) - expect(count).to.equal(1) + expect(count).to.equal(1) + }) }) }) From 9d5402fabbacf2f7206fbfbe737dc1d5537c6631 Mon Sep 17 00:00:00 2001 From: Alessandro Magionami Date: Fri, 10 Jan 2025 14:44:34 +0100 Subject: [PATCH 4/4] feat(workspaces): add assertions to test --- .../workspaces/tests/integration/repositories.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts index 1588ef0026..d6fadbca78 100644 --- a/packages/server/modules/workspaces/tests/integration/repositories.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/repositories.spec.ts @@ -841,6 +841,15 @@ describe('Workspace repositories', () => { }) expect(workspaces.length).to.equal(1) + expect(workspaces[0].id).to.equal(workspace.id) + + const otherUserWorkspaces = await getUserDiscoverableWorkspaces({ + domains: ['example.org'], + userId: otherUser.id + }) + + expect(otherUserWorkspaces.length).to.equal(1) + expect(otherUserWorkspaces[0].id).to.equal(workspaceWithExistingRequest.id) }) })