Files
hoppscotch/packages/hoppscotch-backend/src/team/team.service.spec.ts
Mir Arif Hasan ffc08227dd fix: all unit test cases for backend modules (HBE-171) (#51)
* fix: if-condition for getCollectionOfRequest func

* fix: all test cases for team request module

* fix: user collection test case

* fix: team module test case

* refactor: updated test description for last implemented changes in admin and removed commented code

---------

Co-authored-by: ankitsridhar16 <ankit.sridhar16@gmail.com>
2023-04-06 19:53:04 +05:30

996 lines
28 KiB
TypeScript

import { TeamService } from './team.service';
import { PrismaService } from '../prisma/prisma.service';
import { Team, TeamMember, TeamMemberRole } from './team.model';
import { TeamMember as DbTeamMember } from '@prisma/client';
import {
USER_NOT_FOUND,
TEAM_INVALID_ID,
TEAM_NAME_INVALID,
TEAM_ONLY_ONE_OWNER,
TEAM_INVALID_ID_OR_USER,
} from '../errors';
import { mockDeep, mockReset } from 'jest-mock-extended';
import * as O from 'fp-ts/Option';
const mockPrisma = mockDeep<PrismaService>();
const mockUserService = {
findUserByEmail: jest.fn(),
getUserForUID: jest.fn(),
authenticateWithIDToken: jest.fn(),
};
const mockPubSub = {
publish: jest.fn().mockResolvedValue(null),
};
const teamService = new TeamService(
mockPrisma as any,
mockUserService as any,
mockPubSub as any,
);
beforeEach(async () => {
mockReset(mockPrisma);
});
const team: Team = {
id: 'teamID',
name: 'teamName',
};
const teams: Team[] = [
{
id: 'teamID',
name: 'teamName',
},
{
id: 'teamID2',
name: 'teamName2',
},
];
const dbTeamMember: DbTeamMember = {
id: 'teamMemberID',
role: TeamMemberRole.VIEWER,
userUid: 'userUid',
teamID: team.id,
};
const teamMember: TeamMember = {
membershipID: dbTeamMember.id,
role: TeamMemberRole[dbTeamMember.role],
userUid: dbTeamMember.userUid,
};
describe('getCountOfUsersWithRoleInTeam', () => {
test('resolves to the correct count of owners in a team', async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockPrisma.teamMember.count.mockResolvedValue(2);
await expect(
teamService.getCountOfUsersWithRoleInTeam(
dbTeamMember.teamID,
TeamMemberRole.OWNER,
),
).resolves.toEqual(2);
expect(mockPrisma.teamMember.count).toHaveBeenCalledWith({
where: {
teamID: dbTeamMember.teamID,
role: TeamMemberRole.OWNER,
},
});
});
test('resolves to the correct count of viewers in a team', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
await expect(
teamService.getCountOfUsersWithRoleInTeam(
dbTeamMember.teamID,
TeamMemberRole.VIEWER,
),
).resolves.toEqual(2);
expect(mockPrisma.teamMember.count).toHaveBeenCalledWith({
where: {
teamID: dbTeamMember.teamID,
role: TeamMemberRole.VIEWER,
},
});
});
test('resolves to the correct count of editors in a team', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
await expect(
teamService.getCountOfUsersWithRoleInTeam(
dbTeamMember.teamID,
TeamMemberRole.EDITOR,
),
).resolves.toEqual(2);
expect(mockPrisma.teamMember.count).toHaveBeenCalledWith({
where: {
teamID: dbTeamMember.teamID,
role: TeamMemberRole.EDITOR,
},
});
});
});
describe('addMemberToTeam', () => {
test('resolves when proper team id is given', () => {
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
expect(
teamService.addMemberToTeam(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[dbTeamMember.role],
),
).resolves.toEqual(expect.objectContaining(teamMember));
});
test('makes the update in the database', async () => {
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
await teamService.addMemberToTeam(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[dbTeamMember.role],
);
expect(mockPrisma.teamMember.create).toHaveBeenCalledWith({
data: {
userUid: dbTeamMember.userUid,
team: {
connect: {
id: dbTeamMember.teamID,
},
},
role: TeamMemberRole[dbTeamMember.role],
},
});
});
test('fires "team/<team_id>/member_added" pubsub message with correct payload', async () => {
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
const member = await teamService.addMemberToTeam(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[dbTeamMember.role],
);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team/${dbTeamMember.teamID}/member_added`,
member,
);
});
});
describe('addMemberToTeamWithEmail', () => {
afterEach(() => {
mockUserService.findUserByEmail.mockClear();
mockUserService.authenticateWithIDToken.mockClear();
mockUserService.authenticateWithIDToken.mockClear();
});
test('resolves when user with email exists', () => {
mockUserService.findUserByEmail.mockResolvedValueOnce(
O.some({
uid: dbTeamMember.userUid,
}),
);
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
const result = teamService.addMemberToTeamWithEmail(
dbTeamMember.teamID,
'test@hoppscotch.io',
TeamMemberRole[dbTeamMember.role],
);
return expect(result).resolves.toBeDefined();
});
test("rejects with user with email doesn't exist with USER_NOT_FOUND", () => {
mockUserService.findUserByEmail.mockResolvedValue(O.none);
const result = teamService.addMemberToTeamWithEmail(
dbTeamMember.teamID,
'test@hoppscotch.io',
TeamMemberRole[dbTeamMember.role],
);
return expect(result).resolves.toEqualLeft(USER_NOT_FOUND);
});
test('makes update in the database', async () => {
mockUserService.findUserByEmail.mockResolvedValueOnce(
O.some({
uid: dbTeamMember.userUid,
}),
);
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
await teamService.addMemberToTeamWithEmail(
dbTeamMember.teamID,
'test@hoppscotch.io',
TeamMemberRole[dbTeamMember.role],
);
expect(mockPrisma.teamMember.create).toHaveBeenCalledWith({
data: {
userUid: dbTeamMember.userUid,
team: {
connect: {
id: dbTeamMember.teamID,
},
},
role: TeamMemberRole[dbTeamMember.role],
},
});
});
test('fires "team/<team_id>/member_added" pubsub message with correct payload', async () => {
mockUserService.findUserByEmail.mockResolvedValueOnce(
O.some({
uid: dbTeamMember.userUid,
}),
);
mockPrisma.teamMember.create.mockResolvedValue(dbTeamMember);
await teamService.addMemberToTeamWithEmail(
dbTeamMember.teamID,
'test@hoppscotch.io',
TeamMemberRole[dbTeamMember.role],
);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team/${dbTeamMember.teamID}/member_added`,
teamMember,
);
});
});
describe('deleteTeam', () => {
test('resolves for proper deletion', async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockPrisma.team.findUnique.mockResolvedValue(team);
mockPrisma.teamMember.deleteMany.mockResolvedValue({
count: 10,
});
mockPrisma.team.delete.mockResolvedValue(team);
const result = await teamService.deleteTeam(team.id);
return expect(result).toEqualRight(true);
});
test('performs deletion on database', async () => {
mockPrisma.team.findUnique.mockResolvedValue(team);
mockPrisma.teamMember.deleteMany.mockResolvedValue({
count: 10,
});
mockPrisma.team.delete.mockResolvedValue(team);
await teamService.deleteTeam(team.id);
expect(mockPrisma.team.delete).toHaveBeenCalledWith({
where: {
id: team.id,
},
});
});
test('rejects for invalid team id', async () => {
mockPrisma.team.findUnique.mockResolvedValue(null);
// If invalid team ID, team member deletes nothing (count 0)
mockPrisma.teamMember.deleteMany.mockResolvedValue({
count: 0,
});
// TODO: Confirm RecordNotFound works like this
mockPrisma.team.delete.mockRejectedValue('RecordNotFound');
// Team will not find and reject
const result = await teamService.deleteTeam(team.id);
return expect(result).toEqualLeft(TEAM_INVALID_ID);
});
});
describe('renameTeam', () => {
test('resolves for proper rename', () => {
const newTeamName = 'Rename';
mockPrisma.team.update.mockResolvedValue({
...team,
name: newTeamName,
});
return expect(
teamService.renameTeam(team.id, newTeamName),
).resolves.toBeDefined();
});
test('resolves with team structure', () => {
const newTeamName = 'Rename';
mockPrisma.team.update.mockResolvedValue({
...team,
name: newTeamName,
});
return expect(
teamService.renameTeam(team.id, newTeamName),
).resolves.toEqualRight(
expect.objectContaining({
...team,
name: newTeamName,
}),
);
});
test('performs rename on database', async () => {
const newTeamName = 'Rename';
mockPrisma.team.update.mockResolvedValue({
...team,
name: newTeamName,
});
await teamService.renameTeam(team.id, newTeamName);
expect(mockPrisma.team.update).toHaveBeenCalledWith({
where: {
id: team.id,
},
data: {
name: newTeamName,
},
});
});
test('rejects for invalid team id with TEAM_INVALID_ID', () => {
const newTeamName = 'Rename';
// If invalid team id, update fails with RecordNotFound
mockPrisma.team.update.mockRejectedValue('RecordNotFound');
return expect(
teamService.renameTeam(team.id, newTeamName),
).resolves.toEqualLeft(TEAM_INVALID_ID);
});
test('rejects for new team name length < 6 with TEAM_NAME_INVALID', () => {
const newTeamName = 'smol';
// Prisma doesn't care about the team name length, so it will resolve
mockPrisma.team.update.mockResolvedValue({
...team,
name: newTeamName,
});
return expect(
teamService.renameTeam(team.id, newTeamName),
).resolves.toEqualLeft(TEAM_NAME_INVALID);
});
});
describe('updateTeamMemberRole', () => {
/**
* Test Scenario:
* 3 users (testuid1 thru 3) having each of the roles
* (OWNER, VIEWER, EDITOR)
* in Team with id 3170
*/
test('updates the role', async () => {
const newRole = TeamMemberRole.EDITOR;
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole[dbTeamMember.role],
});
mockPrisma.teamMember.update.mockResolvedValue({
...dbTeamMember,
role: newRole,
});
await teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
newRole,
);
expect(mockPrisma.teamMember.update).toHaveBeenCalledWith({
where: {
teamID_userUid: {
teamID: dbTeamMember.teamID,
userUid: dbTeamMember.userUid,
},
},
data: {
role: newRole,
},
});
});
test('returns the updated details', () => {
const newRole = TeamMemberRole.EDITOR;
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
mockPrisma.teamMember.update.mockResolvedValue({
...dbTeamMember,
role: newRole,
});
return expect(
teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
newRole,
),
).resolves.toEqualRight({ ...teamMember, role: newRole });
});
test('rejects if you change the status of the sole owner to non-owner status with TEAM_ONLY_ONE_OWNER', () => {
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
// Prisma doesn't care if it goes through
mockPrisma.teamMember.update.mockResolvedValue(dbTeamMember);
return expect(
teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[dbTeamMember.role],
),
).resolves.toEqualLeft(TEAM_ONLY_ONE_OWNER);
});
test('resolves if you change the status of the sole owner to owner status (no change)', () => {
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
mockPrisma.teamMember.update.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
return expect(
teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[TeamMemberRole.OWNER],
),
).resolves.toBeDefined();
});
test('resolves if you change the status of an owner but there are other owners', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
mockPrisma.teamMember.update.mockResolvedValue(dbTeamMember);
// Set another user as the owner
await teamService.updateTeamMemberRole(
dbTeamMember.teamID,
'testuid2',
TeamMemberRole.OWNER,
);
await expect(
teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
TeamMemberRole[dbTeamMember.role],
),
).resolves.toBeDefined();
});
test('fires "team/<team_id>/member_updated" pubsub message with correct payload', async () => {
const newRole = TeamMemberRole.EDITOR;
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
mockPrisma.teamMember.update.mockResolvedValue({
...dbTeamMember,
role: newRole,
});
await teamService.updateTeamMemberRole(
dbTeamMember.teamID,
dbTeamMember.userUid,
newRole,
);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team/${dbTeamMember.teamID}/member_updated`,
{
...teamMember,
role: newRole,
},
);
});
});
describe('leaveTeam', () => {
/*
Same scenario as above:
3 users (testuid1 thru 3) with respectively
OWNER, VIEWER and EDITOR roles in team with id 3170
*/
test('removes the user if valid credentials given', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
mockPrisma.teamMember.delete.mockResolvedValue(dbTeamMember);
await teamService.leaveTeam(dbTeamMember.teamID, dbTeamMember.userUid);
expect(mockPrisma.teamMember.delete).toHaveBeenCalledWith({
where: {
teamID_userUid: {
teamID: dbTeamMember.teamID,
userUid: dbTeamMember.userUid,
},
},
});
});
test('rejects if invalid teamId with TEAM_INVALID_ID_OR_USER', () => {
// Invalid team id will return 0 count
mockPrisma.teamMember.count.mockResolvedValue(0);
// getTeamMember returns null if no match
mockPrisma.teamMember.findUnique.mockResolvedValue(null);
// Deletion rejects with RecordNotFound when no match
mockPrisma.teamMember.delete.mockRejectedValue('RecordNotFound');
return expect(
teamService.leaveTeam('31700', dbTeamMember.userUid),
).resolves.toEqualLeft(TEAM_INVALID_ID_OR_USER);
});
test('rejects if invalid userUid with TEAM_INVALID_ID_OR_USER', () => {
// Invalid team id will return proper count
mockPrisma.teamMember.count.mockResolvedValue(1);
// getTeamMember returns null if no match
mockPrisma.teamMember.findUnique.mockResolvedValue(null);
// Deletion rejects with RecordNotFound when no match
mockPrisma.teamMember.delete.mockRejectedValue('RecordNotFound');
return expect(
teamService.leaveTeam(dbTeamMember.teamID, 'testuid3'),
).resolves.toEqualLeft(TEAM_INVALID_ID_OR_USER);
});
test('rejects if the removed user is the sole owner of the team with TEAM_ONLY_ONE_OWNER', () => {
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
// Prisma does not care
mockPrisma.teamMember.delete.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
return expect(
teamService.leaveTeam(dbTeamMember.teamID, dbTeamMember.userUid),
).resolves.toEqualLeft(TEAM_ONLY_ONE_OWNER);
});
test('resolves if the removed user is an owner (but not the sole) of the team', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
mockPrisma.teamMember.delete.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
await expect(
teamService.leaveTeam(dbTeamMember.teamID, dbTeamMember.userUid),
).resolves.toEqualRight(true);
});
test('fires "team/<team_id>/member_removed" pubsub message with correct payload', async () => {
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
mockPrisma.teamMember.delete.mockResolvedValue(dbTeamMember);
await teamService.leaveTeam(dbTeamMember.teamID, dbTeamMember.userUid);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team/${dbTeamMember.teamID}/member_removed`,
dbTeamMember.userUid,
);
});
});
describe('createTeam', () => {
test('adds the new team to the db', async () => {
mockPrisma.team.create.mockResolvedValue(team);
await teamService.createTeam(team.name, dbTeamMember.userUid);
expect(mockPrisma.team.create).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.objectContaining({
name: team.name,
}),
}),
);
});
test('adds the creator to team and set them as OWNER', async () => {
mockPrisma.team.create.mockResolvedValue(team);
await teamService.createTeam(team.name, dbTeamMember.userUid);
expect(mockPrisma.team.create).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.objectContaining({
members: {
create: {
userUid: dbTeamMember.userUid,
role: TeamMemberRole.OWNER,
},
},
}),
}),
);
});
test('resolves with the team info', () => {
mockPrisma.team.create.mockResolvedValue(team);
return expect(
teamService.createTeam(team.name, dbTeamMember.userUid),
).resolves.toEqualRight(expect.objectContaining(team));
});
test('rejects for team name length < 6 with TEAM_NAME_INVALID', () => {
const newName = 'smol';
// Prisma doesn't care
mockPrisma.team.create.mockResolvedValue({
...team,
name: newName,
});
return expect(
teamService.createTeam(newName, dbTeamMember.userUid),
).resolves.toEqualLeft(TEAM_NAME_INVALID);
});
});
describe('getTeamWithID', () => {
test('resolves for a proper team id with the proper details', () => {
mockPrisma.team.findUnique.mockResolvedValue(team);
return expect(teamService.getTeamWithID(team.id)).resolves.toEqual(
expect.objectContaining(team),
);
});
test('resolves for a invalid team id as null', () => {
// Prisma would reject with RecordNotFound
mockPrisma.team.findUnique.mockRejectedValue('RecordNotFound');
return expect(teamService.getTeamWithID('3171')).resolves.toBeNull();
});
});
describe('getTeamMember', () => {
test('resolves for a proper team id and user uid and returns the info', () => {
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
return expect(
teamService.getTeamMember(dbTeamMember.teamID, dbTeamMember.userUid),
).resolves.toEqual(expect.objectContaining(teamMember));
});
test('resolves for a invalid team id and proper uid and returns null', () => {
// If not found, prisma rejects with RecordNotFound
mockPrisma.teamMember.findUnique.mockRejectedValue('RecordNotFound');
return expect(
teamService.getTeamMember(dbTeamMember.teamID, 'testuid'),
).resolves.toBeNull();
});
});
describe('getRoleOfUserInTeam', () => {
test('resolves with the correct role value', () => {
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
return expect(
teamService.getRoleOfUserInTeam(
dbTeamMember.teamID,
dbTeamMember.userUid,
),
).resolves.toEqual(dbTeamMember.role);
});
test('resolves with null if user is not found in team', () => {
mockPrisma.teamMember.findUnique.mockRejectedValue('RecordNotFound');
return expect(
teamService.getRoleOfUserInTeam(dbTeamMember.teamID, 'nottestuid'),
).resolves.toBeNull();
});
test('resolves with null if team does not exist', () => {
mockPrisma.teamMember.findUnique.mockRejectedValue('RecordNotFound');
return expect(
teamService.getRoleOfUserInTeam('invalidteam', dbTeamMember.userUid),
).resolves.toBeNull();
});
});
describe('getMembersOfTeam', () => {
test('resolves for the team id and null cursor with the first page', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([]);
await teamService.getMembersOfTeam(team.id, null);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10,
where: {
teamID: team.id,
},
});
});
test('resolves for the team id and proper cursor with pagination', async () => {
const cursor = 'secondpage';
mockPrisma.teamMember.findMany.mockResolvedValue([]);
await teamService.getMembersOfTeam(team.id, cursor);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10,
skip: 1,
cursor: {
id: cursor,
},
where: {
teamID: team.id,
},
});
});
test('resolves with an empty array for invalid team id and null cursor', () => {
// findMany returns an empty array if no matches are found
mockPrisma.teamMember.findMany.mockResolvedValue([]);
return expect(
teamService.getMembersOfTeam('invalidteamid', null),
).resolves.toHaveLength(0);
});
test('resolves with an empty array for an invalid team id and invalid cursor', () => {
// findMany returns an empty array if no matches are found
mockPrisma.teamMember.findMany.mockResolvedValue([]);
return expect(
teamService.getMembersOfTeam('invalidteamid', 'invalidcursor'),
).resolves.toHaveLength(0);
});
});
describe('getTeamsOfUser', () => {
test('resolves with the first 10 elements when no cursor is given', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([]);
await teamService.getTeamsOfUser(dbTeamMember.userUid, null);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10,
where: {
userUid: dbTeamMember.userUid,
},
include: {
team: true,
},
});
});
test('resolves as expected for paginated requests with cursor', async () => {
const cursor = 'secondpage';
mockPrisma.teamMember.findMany.mockResolvedValue([]);
await teamService.getTeamsOfUser(dbTeamMember.userUid, cursor);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10,
skip: 1,
cursor: {
teamID_userUid: {
teamID: cursor,
userUid: dbTeamMember.userUid,
},
},
where: {
userUid: dbTeamMember.userUid,
},
include: {
team: true,
},
});
});
test('resolves with an empty array for an invalid cursor', () => {
// Invalid cursors return an empty array
mockPrisma.teamMember.findMany.mockResolvedValue([]);
return expect(
teamService.getTeamsOfUser(dbTeamMember.userUid, 'invalidcursor'),
).resolves.toHaveLength(0);
});
test('resolves with an empty array for invalid user id and null cursor', () => {
mockPrisma.teamMember.findMany.mockResolvedValue([]);
return expect(
teamService.getTeamsOfUser('invalidid', null),
).resolves.toHaveLength(0);
});
test('resolves with an empty array for invalid user id and invalid cursor', () => {
mockPrisma.teamMember.findMany.mockResolvedValue([]);
return expect(
teamService.getTeamsOfUser('invalidId', 'invalidCursor'),
).resolves.toHaveLength(0);
});
});
describe('deleteUserFromAllTeams', () => {
test('should return undefined when a valid uid is passed and user is deleted from all teams', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([dbTeamMember]);
mockPrisma.teamMember.count.mockResolvedValue(2);
mockPrisma.teamMember.findUnique.mockResolvedValue(dbTeamMember);
const result = await teamService.deleteUserFromAllTeams(
dbTeamMember.userUid,
)();
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
where: {
userUid: dbTeamMember.userUid,
},
});
expect(result).toBeUndefined();
});
test('should return undefined when user has no data or the uid is invalid', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([]);
const result = await teamService.deleteUserFromAllTeams(
dbTeamMember.userUid,
)();
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
where: {
userUid: dbTeamMember.userUid,
},
});
expect(result).toBeUndefined();
});
test('should reject when user is an OWNER in a team with only 1 member', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([dbTeamMember]);
mockPrisma.teamMember.count.mockResolvedValue(1);
mockPrisma.teamMember.findUnique.mockResolvedValue({
...dbTeamMember,
role: TeamMemberRole.OWNER,
});
const result = teamService.deleteUserFromAllTeams(dbTeamMember.userUid)();
await expect(result).rejects.toThrowError(TEAM_ONLY_ONE_OWNER);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
where: {
userUid: dbTeamMember.userUid,
},
});
});
test('should reject when a valid uid is passed but fetching teamMember details errors out', async () => {
mockPrisma.teamMember.findMany.mockResolvedValue([
{
...dbTeamMember,
role: TeamMemberRole.OWNER,
},
]);
mockPrisma.teamMember.count.mockResolvedValue(2);
// findUnique while getTeamMember() is called errors out
mockPrisma.teamMember.findUnique.mockRejectedValueOnce('NotFoundError');
const result = teamService.deleteUserFromAllTeams(dbTeamMember.userUid);
await expect(result).rejects.toThrowError(TEAM_INVALID_ID_OR_USER);
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
where: {
userUid: dbTeamMember.userUid,
},
});
});
});
describe('fetchAllTeams', () => {
test('should resolve right and return 20 teams when cursor is null', async () => {
mockPrisma.team.findMany.mockResolvedValueOnce(teams);
const result = await teamService.fetchAllTeams(null, 20);
expect(result).toEqual(teams);
});
test('should resolve right and return next 20 teams when cursor is provided', async () => {
mockPrisma.team.findMany.mockResolvedValueOnce(teams);
const result = await teamService.fetchAllTeams('teamID', 20);
expect(result).toEqual(teams);
});
test('should resolve left and return an empty array when users not found', async () => {
mockPrisma.team.findMany.mockResolvedValueOnce([]);
const result = await teamService.fetchAllTeams(null, 20);
expect(result).toEqual([]);
});
});
describe('getCountOfMembersInTeam', () => {
test('should resolve right and return a total team member count ', async () => {
mockPrisma.teamMember.count.mockResolvedValueOnce(2);
const result = await teamService.getCountOfMembersInTeam(team.id);
expect(mockPrisma.teamMember.count).toHaveBeenCalledWith({
where: {
teamID: team.id,
},
});
expect(result).toEqual(2);
});
test('should resolve left and return an error when no team members found', async () => {
mockPrisma.teamMember.count.mockResolvedValueOnce(0);
const result = await teamService.getCountOfMembersInTeam(team.id);
expect(mockPrisma.teamMember.count).toHaveBeenCalledWith({
where: {
teamID: team.id,
},
});
expect(result).toEqual(0);
});
describe('getTeamsCount', () => {
test('should return count of all teams in the organization', async () => {
mockPrisma.team.count.mockResolvedValueOnce(10);
const result = await teamService.getTeamsCount();
expect(result).toEqual(10);
});
});
});