Compare commits
12 Commits
feat-cherr
...
test/backe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c188f865a2 | ||
|
|
a2a675dd86 | ||
|
|
b867ba9139 | ||
|
|
d2ca631492 | ||
|
|
39a4fd8ab2 | ||
|
|
6928eb7992 | ||
|
|
76d52a3b05 | ||
|
|
b83cc38a1c | ||
|
|
db42073d42 | ||
|
|
6c928e72d4 | ||
|
|
ddd0a67da3 | ||
|
|
295304feeb |
@@ -10,11 +10,23 @@ import { TeamInvitationService } from '../team-invitation/team-invitation.servic
|
||||
import { TeamCollectionService } from '../team-collection/team-collection.service';
|
||||
import { MailerService } from '../mailer/mailer.service';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { User as DbUser } from '@prisma/client';
|
||||
import {
|
||||
DUPLICATE_EMAIL,
|
||||
INVALID_EMAIL,
|
||||
ONLY_ONE_ADMIN_ACCOUNT,
|
||||
TEAM_INVITE_ALREADY_MEMBER,
|
||||
TEAM_MEMBER_NOT_FOUND,
|
||||
USER_ALREADY_INVITED,
|
||||
USER_IS_ADMIN,
|
||||
USER_NOT_FOUND,
|
||||
} from '../errors';
|
||||
import { Team, TeamMember, TeamMemberRole } from 'src/team/team.model';
|
||||
import { TeamInvitation } from 'src/team-invitation/team-invitation.model';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import * as O from 'fp-ts/Option';
|
||||
import * as TE from 'fp-ts/TaskEither';
|
||||
import * as utils from 'src/utils';
|
||||
|
||||
const mockPrisma = mockDeep<PrismaService>();
|
||||
const mockPubSub = mockDeep<PubSubService>();
|
||||
@@ -52,7 +64,582 @@ const invitedUsers: InvitedUsers[] = [
|
||||
invitedOn: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
const allUsers: DbUser[] = [
|
||||
{
|
||||
uid: 'uid1',
|
||||
displayName: 'user1',
|
||||
email: 'user1@hoppscotch.io',
|
||||
photoURL: 'https://hoppscotch.io',
|
||||
isAdmin: true,
|
||||
refreshToken: 'refreshToken',
|
||||
currentRESTSession: null,
|
||||
currentGQLSession: null,
|
||||
createdOn: new Date(),
|
||||
},
|
||||
{
|
||||
uid: 'uid2',
|
||||
displayName: 'user2',
|
||||
email: 'user2@hoppscotch.io',
|
||||
photoURL: 'https://hoppscotch.io',
|
||||
isAdmin: false,
|
||||
refreshToken: 'refreshToken',
|
||||
currentRESTSession: null,
|
||||
currentGQLSession: null,
|
||||
createdOn: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
const teamMembers: TeamMember[] = [
|
||||
{
|
||||
membershipID: 'teamMember1',
|
||||
userUid: allUsers[0].uid,
|
||||
role: TeamMemberRole.OWNER,
|
||||
},
|
||||
];
|
||||
|
||||
const teams: Team[] = [
|
||||
{
|
||||
id: 'team1',
|
||||
name: 'team1',
|
||||
},
|
||||
{
|
||||
id: 'team2',
|
||||
name: 'team2',
|
||||
},
|
||||
];
|
||||
|
||||
const teamInvitations: TeamInvitation[] = [
|
||||
{
|
||||
id: 'teamInvitation1',
|
||||
teamID: 'team1',
|
||||
creatorUid: 'uid1',
|
||||
inviteeEmail: '',
|
||||
inviteeRole: TeamMemberRole.OWNER,
|
||||
},
|
||||
];
|
||||
|
||||
describe('AdminService', () => {
|
||||
describe('fetchUsers', () => {
|
||||
test('should resolve right and return an array of users if cursorID is null', async () => {
|
||||
mockUserService.fetchAllUsers.mockResolvedValueOnce(allUsers);
|
||||
|
||||
const result = await adminService.fetchUsers(null, 10);
|
||||
|
||||
expect(result).toEqual(allUsers);
|
||||
expect(mockUserService.fetchAllUsers).toHaveBeenCalledWith(null, 10);
|
||||
});
|
||||
test('should resolve right and return an array of users if cursorID is not null', async () => {
|
||||
mockUserService.fetchAllUsers.mockResolvedValueOnce([allUsers[1]]);
|
||||
|
||||
const cursorID = allUsers[0].uid;
|
||||
const result = await adminService.fetchUsers(cursorID, 10);
|
||||
|
||||
expect(result).toEqual([allUsers[1]]);
|
||||
expect(mockUserService.fetchAllUsers).toHaveBeenCalledWith(cursorID, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchAllTeams', () => {
|
||||
test('should resolve right and return an array of teams if cursorID is null', async () => {
|
||||
mockTeamService.fetchAllTeams.mockResolvedValueOnce(teams);
|
||||
|
||||
const result = await adminService.fetchAllTeams(null, 10);
|
||||
|
||||
expect(result).toEqual(teams);
|
||||
expect(mockTeamService.fetchAllTeams).toHaveBeenCalledWith(null, 10);
|
||||
});
|
||||
test('should resolve right and return an array of teams if cursorID is not null', async () => {
|
||||
mockTeamService.fetchAllTeams.mockResolvedValueOnce([teams[1]]);
|
||||
|
||||
const cursorID = teams[0].id;
|
||||
const result = await adminService.fetchAllTeams(cursorID, 10);
|
||||
|
||||
expect(result).toEqual([teams[1]]);
|
||||
expect(mockTeamService.fetchAllTeams).toHaveBeenCalledWith(cursorID, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('membersCountInTeam', () => {
|
||||
test('should resolve right and return the count of members in a team', async () => {
|
||||
mockTeamService.getCountOfMembersInTeam.mockResolvedValueOnce(10);
|
||||
|
||||
const result = await adminService.membersCountInTeam('team1');
|
||||
|
||||
expect(result).toEqual(10);
|
||||
expect(mockTeamService.getCountOfMembersInTeam).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('collectionCountInTeam', () => {
|
||||
test('should resolve right and return the count of collections in a team', async () => {
|
||||
mockTeamCollectionService.totalCollectionsInTeam.mockResolvedValueOnce(
|
||||
10,
|
||||
);
|
||||
|
||||
const result = await adminService.collectionCountInTeam('team1');
|
||||
|
||||
expect(result).toEqual(10);
|
||||
expect(
|
||||
mockTeamCollectionService.totalCollectionsInTeam,
|
||||
).toHaveBeenCalledWith('team1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('requestCountInTeam', () => {
|
||||
test('should resolve right and return the count of requests in a team', async () => {
|
||||
mockTeamRequestService.totalRequestsInATeam.mockResolvedValueOnce(10);
|
||||
|
||||
const result = await adminService.requestCountInTeam('team1');
|
||||
|
||||
expect(result).toEqual(10);
|
||||
expect(mockTeamRequestService.totalRequestsInATeam).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('environmentCountInTeam', () => {
|
||||
test('should resolve right and return the count of environments in a team', async () => {
|
||||
mockTeamEnvironmentsService.totalEnvsInTeam.mockResolvedValueOnce(10);
|
||||
|
||||
const result = await adminService.environmentCountInTeam('team1');
|
||||
|
||||
expect(result).toEqual(10);
|
||||
expect(mockTeamEnvironmentsService.totalEnvsInTeam).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pendingInvitationCountInTeam', () => {
|
||||
test('should resolve right and return the count of pending invitations in a team', async () => {
|
||||
mockTeamInvitationService.getTeamInvitations.mockResolvedValueOnce(
|
||||
teamInvitations,
|
||||
);
|
||||
|
||||
const result = await adminService.pendingInvitationCountInTeam('team1');
|
||||
|
||||
expect(result).toEqual(teamInvitations);
|
||||
expect(
|
||||
mockTeamInvitationService.getTeamInvitations,
|
||||
).toHaveBeenCalledWith('team1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeRoleOfUserTeam', () => {
|
||||
test('should resolve right and return the count of pending invitations in a team', async () => {
|
||||
const teamMember = teamMembers[0];
|
||||
|
||||
mockTeamService.updateTeamMemberRole.mockResolvedValueOnce(
|
||||
E.right(teamMember),
|
||||
);
|
||||
|
||||
const result = await adminService.changeRoleOfUserTeam(
|
||||
teamMember.userUid,
|
||||
'team1',
|
||||
teamMember.role,
|
||||
);
|
||||
|
||||
expect(result).toEqualRight(teamMember);
|
||||
expect(mockTeamService.updateTeamMemberRole).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
teamMember.userUid,
|
||||
teamMember.role,
|
||||
);
|
||||
});
|
||||
|
||||
test('should resolve left and return the error if any error occurred', async () => {
|
||||
const teamMember = teamMembers[0];
|
||||
const errorMessage = 'Team member not found';
|
||||
|
||||
mockTeamService.updateTeamMemberRole.mockResolvedValueOnce(
|
||||
E.left(errorMessage),
|
||||
);
|
||||
|
||||
const result = await adminService.changeRoleOfUserTeam(
|
||||
teamMember.userUid,
|
||||
'team1',
|
||||
teamMember.role,
|
||||
);
|
||||
|
||||
expect(result).toEqualLeft(errorMessage);
|
||||
expect(mockTeamService.updateTeamMemberRole).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
teamMember.userUid,
|
||||
teamMember.role,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeUserFromTeam', () => {
|
||||
test('should resolve right and remove user from a team', async () => {
|
||||
const teamMember = teamMembers[0];
|
||||
|
||||
mockTeamService.leaveTeam.mockResolvedValueOnce(E.right(true));
|
||||
|
||||
const result = await adminService.removeUserFromTeam(
|
||||
teamMember.userUid,
|
||||
'team1',
|
||||
);
|
||||
|
||||
expect(result).toEqualRight(true);
|
||||
expect(mockTeamService.leaveTeam).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
teamMember.userUid,
|
||||
);
|
||||
});
|
||||
|
||||
test('should resolve left and return the error if any error occurred', async () => {
|
||||
const teamMember = teamMembers[0];
|
||||
const errorMessage = 'Team member not found';
|
||||
|
||||
mockTeamService.leaveTeam.mockResolvedValueOnce(E.left(errorMessage));
|
||||
|
||||
const result = await adminService.removeUserFromTeam(
|
||||
teamMember.userUid,
|
||||
'team1',
|
||||
);
|
||||
|
||||
expect(result).toEqualLeft(errorMessage);
|
||||
expect(mockTeamService.leaveTeam).toHaveBeenCalledWith(
|
||||
'team1',
|
||||
teamMember.userUid,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addUserToTeam', () => {
|
||||
test('should return INVALID_EMAIL when email is invalid', async () => {
|
||||
const teamID = 'team1';
|
||||
const userEmail = 'invalidEmail';
|
||||
const role = TeamMemberRole.EDITOR;
|
||||
|
||||
const mockValidateEmail = jest.spyOn(utils, 'validateEmail');
|
||||
mockValidateEmail.mockReturnValueOnce(false);
|
||||
|
||||
const result = await adminService.addUserToTeam(teamID, userEmail, role);
|
||||
|
||||
expect(result).toEqual(E.left(INVALID_EMAIL));
|
||||
expect(mockValidateEmail).toHaveBeenCalledWith(userEmail);
|
||||
expect(mockUserService.findUserByEmail).not.toHaveBeenCalled();
|
||||
expect(mockTeamService.getTeamMemberTE).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should return USER_NOT_FOUND when user is not found', async () => {
|
||||
const teamID = 'team1';
|
||||
const userEmail = 'u@example.com';
|
||||
const role = TeamMemberRole.EDITOR;
|
||||
|
||||
const mockValidateEmail = jest.spyOn(utils, 'validateEmail');
|
||||
mockValidateEmail.mockReturnValueOnce(true);
|
||||
mockUserService.findUserByEmail.mockResolvedValue(O.none);
|
||||
|
||||
const result = await adminService.addUserToTeam(teamID, userEmail, role);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
expect(mockValidateEmail).toHaveBeenCalledWith(userEmail);
|
||||
});
|
||||
|
||||
test('should return TEAM_INVITE_ALREADY_MEMBER when user is already a member of the team', async () => {
|
||||
const teamID = 'team1';
|
||||
const userEmail = allUsers[0].email;
|
||||
const role = TeamMemberRole.EDITOR;
|
||||
|
||||
const mockValidateEmail = jest.spyOn(utils, 'validateEmail');
|
||||
mockValidateEmail.mockReturnValueOnce(true);
|
||||
mockUserService.findUserByEmail.mockResolvedValueOnce(
|
||||
O.some(allUsers[0]),
|
||||
);
|
||||
mockTeamService.getTeamMemberTE.mockReturnValueOnce(
|
||||
TE.right(teamMembers[0]),
|
||||
);
|
||||
|
||||
const result = await adminService.addUserToTeam(teamID, userEmail, role);
|
||||
|
||||
expect(result).toEqual(E.left(TEAM_INVITE_ALREADY_MEMBER));
|
||||
expect(mockValidateEmail).toHaveBeenCalledWith(userEmail);
|
||||
expect(mockUserService.findUserByEmail).toHaveBeenCalledWith(userEmail);
|
||||
expect(mockTeamService.getTeamMemberTE).toHaveBeenCalledWith(
|
||||
teamID,
|
||||
allUsers[0].uid,
|
||||
);
|
||||
});
|
||||
|
||||
test('should add user to the team and return the result when user is not a member of the team', async () => {
|
||||
const teamID = 'team1';
|
||||
const userEmail = allUsers[0].email;
|
||||
const role = TeamMemberRole.EDITOR;
|
||||
|
||||
const mockValidateEmail = jest.spyOn(utils, 'validateEmail');
|
||||
mockValidateEmail.mockReturnValueOnce(true);
|
||||
mockUserService.findUserByEmail.mockResolvedValueOnce(
|
||||
O.some(allUsers[0]),
|
||||
);
|
||||
mockTeamService.getTeamMemberTE.mockReturnValueOnce(
|
||||
TE.left(TEAM_MEMBER_NOT_FOUND),
|
||||
);
|
||||
mockTeamService.addMemberToTeamWithEmail.mockResolvedValueOnce(
|
||||
E.right(teamMembers[0]),
|
||||
);
|
||||
mockTeamInvitationService.getTeamInviteByEmailAndTeamID.mockResolvedValueOnce(
|
||||
E.right(teamInvitations[0])
|
||||
);
|
||||
|
||||
const result = await adminService.addUserToTeam(teamID, userEmail, role);
|
||||
|
||||
expect(result).toEqual(E.right(teamMembers[0]));
|
||||
expect(mockValidateEmail).toHaveBeenCalledWith(userEmail);
|
||||
expect(mockUserService.findUserByEmail).toHaveBeenCalledWith(userEmail);
|
||||
expect(mockTeamService.getTeamMemberTE).toHaveBeenCalledWith(
|
||||
teamID,
|
||||
allUsers[0].uid,
|
||||
);
|
||||
expect(mockTeamService.addMemberToTeamWithEmail).toHaveBeenCalledWith(
|
||||
teamID,
|
||||
allUsers[0].email,
|
||||
role,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createATeam', () => {
|
||||
test('should return USER_NOT_FOUND when user is not found', async () => {
|
||||
const userUid = allUsers[0].uid;
|
||||
const teamName = 'team1';
|
||||
|
||||
mockUserService.findUserById.mockResolvedValue(O.none);
|
||||
|
||||
const result = await adminService.createATeam(userUid, teamName);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
expect(mockUserService.findUserById).toHaveBeenCalledWith(userUid);
|
||||
expect(mockTeamService.createTeam).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should create a team and return the result when the team is created successfully', async () => {
|
||||
const user = allUsers[0];
|
||||
const team = teams[0];
|
||||
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
mockTeamService.createTeam.mockResolvedValueOnce(E.right(team));
|
||||
|
||||
const result = await adminService.createATeam(user.uid, team.name);
|
||||
|
||||
expect(result).toEqual(E.right(team));
|
||||
expect(mockUserService.findUserById).toHaveBeenCalledWith(user.uid);
|
||||
expect(mockTeamService.createTeam).toHaveBeenCalledWith(
|
||||
team.name,
|
||||
user.uid,
|
||||
);
|
||||
});
|
||||
|
||||
test('should return the error when the team creation fails', async () => {
|
||||
const user = allUsers[0];
|
||||
const team = teams[0];
|
||||
const errorMessage = 'error';
|
||||
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
mockTeamService.createTeam.mockResolvedValueOnce(E.left(errorMessage));
|
||||
|
||||
const result = await adminService.createATeam(user.uid, team.name);
|
||||
|
||||
expect(result).toEqual(E.left(errorMessage));
|
||||
expect(mockUserService.findUserById).toHaveBeenCalledWith(user.uid);
|
||||
expect(mockTeamService.createTeam).toHaveBeenCalledWith(
|
||||
team.name,
|
||||
user.uid,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renameATeam', () => {
|
||||
test('should rename a team and return the result when the team is renamed successfully', async () => {
|
||||
const team = teams[0];
|
||||
const newName = 'new name';
|
||||
|
||||
mockTeamService.renameTeam.mockResolvedValueOnce(E.right(team));
|
||||
|
||||
const result = await adminService.renameATeam(team.id, newName);
|
||||
|
||||
expect(result).toEqual(E.right(team));
|
||||
expect(mockTeamService.renameTeam).toHaveBeenCalledWith(team.id, newName);
|
||||
});
|
||||
|
||||
test('should return the error when the team renaming fails', async () => {
|
||||
const team = teams[0];
|
||||
const newName = 'new name';
|
||||
const errorMessage = 'error';
|
||||
|
||||
mockTeamService.renameTeam.mockResolvedValueOnce(E.left(errorMessage));
|
||||
|
||||
const result = await adminService.renameATeam(team.id, newName);
|
||||
|
||||
expect(result).toEqual(E.left(errorMessage));
|
||||
expect(mockTeamService.renameTeam).toHaveBeenCalledWith(team.id, newName);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteATeam', () => {
|
||||
test('should delete a team and return the result when the team is deleted successfully', async () => {
|
||||
const team = teams[0];
|
||||
|
||||
mockTeamService.deleteTeam.mockResolvedValueOnce(E.right(true));
|
||||
|
||||
const result = await adminService.deleteATeam(team.id);
|
||||
|
||||
expect(result).toEqual(E.right(true));
|
||||
expect(mockTeamService.deleteTeam).toHaveBeenCalledWith(team.id);
|
||||
});
|
||||
|
||||
test('should return the error when the team deletion fails', async () => {
|
||||
const team = teams[0];
|
||||
const errorMessage = 'error';
|
||||
|
||||
mockTeamService.deleteTeam.mockResolvedValueOnce(E.left(errorMessage));
|
||||
|
||||
const result = await adminService.deleteATeam(team.id);
|
||||
|
||||
expect(result).toEqual(E.left(errorMessage));
|
||||
expect(mockTeamService.deleteTeam).toHaveBeenCalledWith(team.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchAdmins', () => {
|
||||
test('should return the list of admin users', async () => {
|
||||
const adminUsers = [];
|
||||
mockUserService.fetchAdminUsers.mockResolvedValueOnce(adminUsers);
|
||||
const result = await adminService.fetchAdmins();
|
||||
|
||||
expect(result).toEqual(adminUsers);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchUserInfo', () => {
|
||||
test('should return the user info when the user is found', async () => {
|
||||
const user = allUsers[0];
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
const result = await adminService.fetchUserInfo(user.uid);
|
||||
|
||||
expect(result).toEqual(E.right(user));
|
||||
});
|
||||
|
||||
test('should return USER_NOT_FOUND when the user is not found', async () => {
|
||||
const user = allUsers[0];
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.none);
|
||||
const result = await adminService.fetchUserInfo(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeUserAccount', () => {
|
||||
test('should return USER_NOT_FOUND when the user is not found', async () => {
|
||||
const user = allUsers[0];
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.none);
|
||||
const result = await adminService.removeUserAccount(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
});
|
||||
|
||||
test('should return USER_IS_ADMIN when the user is an admin', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
const result = await adminService.removeUserAccount(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(USER_IS_ADMIN));
|
||||
});
|
||||
|
||||
test('should remove the user account and return the result when the user is not an admin', async () => {
|
||||
const user = allUsers[1];
|
||||
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
mockUserService.deleteUserByUID.mockReturnValueOnce(TE.right(true));
|
||||
const result = await adminService.removeUserAccount(user.uid);
|
||||
|
||||
expect(result).toEqual(E.right(true));
|
||||
});
|
||||
|
||||
test('should return the error when the user account deletion fails', async () => {
|
||||
const user = allUsers[1];
|
||||
const errorMessage = 'error';
|
||||
|
||||
mockUserService.findUserById.mockResolvedValueOnce(O.some(user));
|
||||
mockUserService.deleteUserByUID.mockReturnValueOnce(
|
||||
TE.left(errorMessage),
|
||||
);
|
||||
const result = await adminService.removeUserAccount(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(errorMessage));
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeUserAdmin', () => {
|
||||
test('should make the user an admin and return true when the operation is successful', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.makeAdmin.mockResolvedValueOnce(E.right(user));
|
||||
const result = await adminService.makeUserAdmin(user.uid);
|
||||
|
||||
expect(result).toEqual(E.right(true));
|
||||
});
|
||||
|
||||
test('should return the error when making the user an admin fails', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.makeAdmin.mockResolvedValueOnce(E.left(USER_NOT_FOUND));
|
||||
const result = await adminService.makeUserAdmin(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeUserAsAdmin', () => {
|
||||
test('should return ONLY_ONE_ADMIN_ACCOUNT when there is only one admin account', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.fetchAdminUsers.mockResolvedValueOnce([user]);
|
||||
const result = await adminService.removeUserAsAdmin(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(ONLY_ONE_ADMIN_ACCOUNT));
|
||||
});
|
||||
|
||||
test('should remove the user as an admin and return true when the operation is successful', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.fetchAdminUsers.mockResolvedValueOnce(allUsers);
|
||||
mockUserService.removeUserAsAdmin.mockResolvedValueOnce(E.right(user));
|
||||
const result = await adminService.removeUserAsAdmin(user.uid);
|
||||
|
||||
expect(result).toEqual(E.right(true));
|
||||
});
|
||||
|
||||
test('should return the error when removing the user as an admin fails', async () => {
|
||||
const user = allUsers[0];
|
||||
|
||||
mockUserService.fetchAdminUsers.mockResolvedValueOnce(allUsers);
|
||||
mockUserService.removeUserAsAdmin.mockResolvedValueOnce(
|
||||
E.left(USER_NOT_FOUND),
|
||||
);
|
||||
const result = await adminService.removeUserAsAdmin(user.uid);
|
||||
|
||||
expect(result).toEqual(E.left(USER_NOT_FOUND));
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTeamInfo', () => {
|
||||
test('should return the team info when the team is found', async () => {
|
||||
const team = teams[0];
|
||||
mockTeamService.getTeamWithIDTE.mockReturnValue(TE.right(team));
|
||||
const result = await adminService.getTeamInfo(team.id);
|
||||
|
||||
expect(result).toEqual(E.right(team));
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchInvitedUsers', () => {
|
||||
test('should resolve right and return an array of invited users', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
|
||||
@@ -240,6 +240,7 @@ export class AdminService {
|
||||
teamID,
|
||||
user.value.uid,
|
||||
)();
|
||||
|
||||
if (E.isLeft(teamMember)) {
|
||||
const addedUser = await this.teamService.addMemberToTeamWithEmail(
|
||||
teamID,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Team, TeamCollection as DBTeamCollection } from '@prisma/client';
|
||||
import { mock, mockDeep, mockReset } from 'jest-mock-extended';
|
||||
import {
|
||||
Team,
|
||||
TeamCollection as DBTeamCollection,
|
||||
TeamRequest as DBTeamRequest,
|
||||
} from '@prisma/client';
|
||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||
import {
|
||||
TEAM_COLL_DEST_SAME,
|
||||
TEAM_COLL_INVALID_JSON,
|
||||
@@ -17,9 +21,8 @@ import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||
import { AuthUser } from 'src/types/AuthUser';
|
||||
import { TeamCollectionService } from './team-collection.service';
|
||||
import { TeamCollection } from './team-collection.model';
|
||||
import { TeamCollectionModule } from './team-collection.module';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import { CollectionFolder } from 'src/types/CollectionFolder';
|
||||
|
||||
const mockPrisma = mockDeep<PrismaService>();
|
||||
const mockPubSub = mockDeep<PubSubService>();
|
||||
@@ -276,11 +279,188 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const teamRequestList: DBTeamRequest[] = [
|
||||
{
|
||||
id: 'req1',
|
||||
collectionID: childTeamCollection.id,
|
||||
teamID: team.id,
|
||||
title: 'request 1',
|
||||
request: {},
|
||||
orderIndex: 1,
|
||||
createdOn: new Date(),
|
||||
updatedOn: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
mockReset(mockPrisma);
|
||||
mockPubSub.publish.mockClear();
|
||||
});
|
||||
|
||||
describe('exportCollectionsToJSON', () => {
|
||||
test('should export collections to JSON string successfully for structure-1', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection
|
||||
|-> childTeamCollection
|
||||
| |-> <no request of child coll>
|
||||
|-> <no request of root coll>
|
||||
|
||||
*/
|
||||
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
rootTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Root Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(rootTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
childTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 2: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Child Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(childTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce([]);
|
||||
// return { name: childTeamCollection.title, folders: [], requests: [], };
|
||||
|
||||
// Back to RCV CALL 1
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
const returnedValue: CollectionFolder = {
|
||||
name: rootTeamCollection.title,
|
||||
folders: [
|
||||
{
|
||||
name: childTeamCollection.title,
|
||||
folders: [],
|
||||
requests: [],
|
||||
},
|
||||
],
|
||||
requests: [],
|
||||
};
|
||||
|
||||
const result = await teamCollectionService.exportCollectionsToJSON(team.id);
|
||||
expect(result).toEqualRight(JSON.stringify([returnedValue]));
|
||||
});
|
||||
|
||||
test('should export collections to JSON string successfully for structure-2', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection
|
||||
|-> childTeamCollection
|
||||
| |-> request1
|
||||
|-> <no request of root coll>
|
||||
|
||||
*/
|
||||
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
rootTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Root Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(rootTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
childTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 2: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Child Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(childTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce(teamRequestList);
|
||||
// return { name: childTeamCollection.title, folders: [], requests: teamRequestList, };
|
||||
|
||||
// Back to RCV CALL 1
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
const returnedValue: CollectionFolder = {
|
||||
name: rootTeamCollection.title,
|
||||
folders: [
|
||||
{
|
||||
name: childTeamCollection.title,
|
||||
folders: [],
|
||||
requests: teamRequestList.map((req) => req.request),
|
||||
},
|
||||
],
|
||||
requests: [],
|
||||
};
|
||||
|
||||
const result = await teamCollectionService.exportCollectionsToJSON(team.id);
|
||||
expect(result).toEqualRight(JSON.stringify([returnedValue]));
|
||||
});
|
||||
|
||||
test('should export collections to JSON string successfully for structure-3', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection
|
||||
|-> childTeamCollection
|
||||
| |-> child-request1
|
||||
|-> root-request1
|
||||
|
||||
*/
|
||||
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
rootTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Root Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(rootTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([
|
||||
childTeamCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 2: Inside exportCollectionsToJSON.exportCollectionToJSONObject for Child Collection
|
||||
jest
|
||||
.spyOn(teamCollectionService, 'getCollection')
|
||||
.mockResolvedValueOnce(E.right(childTeamCollection));
|
||||
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce(teamRequestList);
|
||||
// return { name: childTeamCollection.title, folders: [], requests: teamRequestList, };
|
||||
|
||||
// Back to RCV CALL 1
|
||||
mockPrisma.teamRequest.findMany.mockResolvedValueOnce(teamRequestList);
|
||||
|
||||
const returnedValue: CollectionFolder = {
|
||||
name: rootTeamCollection.title,
|
||||
folders: [
|
||||
{
|
||||
name: childTeamCollection.title,
|
||||
folders: [],
|
||||
requests: teamRequestList.map((req) => req.request),
|
||||
},
|
||||
],
|
||||
requests: teamRequestList.map((req) => req.request),
|
||||
};
|
||||
|
||||
const result = await teamCollectionService.exportCollectionsToJSON(team.id);
|
||||
expect(result).toEqualRight(JSON.stringify([returnedValue]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCollectionCount', () => {
|
||||
test('should return the count of collections successfully', async () => {
|
||||
const count = 10;
|
||||
|
||||
mockPrisma.teamCollection.count.mockResolvedValueOnce(count);
|
||||
const result = await teamCollectionService.getCollectionCount(
|
||||
rootTeamCollection.id,
|
||||
);
|
||||
expect(result).toEqual(count);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTeamOfCollection', () => {
|
||||
test('should return the team of a collection successfully with valid collectionID', async () => {
|
||||
mockPrisma.teamCollection.findUnique.mockResolvedValueOnce({
|
||||
@@ -1460,5 +1640,3 @@ describe('totalCollectionsInTeam', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//ToDo: write test cases for exportCollectionsToJSON
|
||||
|
||||
@@ -306,8 +306,8 @@ describe('TeamEnvironmentsService', () => {
|
||||
);
|
||||
|
||||
mockPrisma.teamEnvironment.create.mockResolvedValueOnce({
|
||||
...teamEnvironment,
|
||||
id: 'newid',
|
||||
...teamEnvironment,
|
||||
});
|
||||
|
||||
const result = await teamEnvironmentsService.createDuplicateEnvironment(
|
||||
@@ -337,8 +337,8 @@ describe('TeamEnvironmentsService', () => {
|
||||
);
|
||||
|
||||
mockPrisma.teamEnvironment.create.mockResolvedValueOnce({
|
||||
...teamEnvironment,
|
||||
id: 'newid',
|
||||
...teamEnvironment,
|
||||
});
|
||||
|
||||
const result = await teamEnvironmentsService.createDuplicateEnvironment(
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
TEAM_REQ_NOT_FOUND,
|
||||
TEAM_REQ_REORDERING_FAILED,
|
||||
TEAM_COLL_NOT_FOUND,
|
||||
JSON_INVALID,
|
||||
} from 'src/errors';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||
@@ -239,7 +240,7 @@ describe('deleteTeamRequest', () => {
|
||||
});
|
||||
|
||||
describe('createTeamRequest', () => {
|
||||
test('rejects for invalid collection id', async () => {
|
||||
test('should rejects for invalid collection id', async () => {
|
||||
mockTeamCollectionService.getTeamOfCollection.mockResolvedValue(
|
||||
E.left(TEAM_INVALID_COLL_ID),
|
||||
);
|
||||
@@ -255,7 +256,42 @@ describe('createTeamRequest', () => {
|
||||
expect(mockPrisma.teamRequest.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('resolves for valid collection id', async () => {
|
||||
test('should rejects for invalid team ID', async () => {
|
||||
mockTeamCollectionService.getTeamOfCollection.mockResolvedValue(
|
||||
E.right(team),
|
||||
);
|
||||
|
||||
const response = await teamRequestService.createTeamRequest(
|
||||
'testcoll',
|
||||
'invalidteamid',
|
||||
'Test Request',
|
||||
'{}',
|
||||
);
|
||||
|
||||
expect(response).toEqualLeft(TEAM_INVALID_ID);
|
||||
expect(mockPrisma.teamRequest.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should reject for invalid request body', async () => {
|
||||
mockTeamCollectionService.getTeamOfCollection.mockResolvedValue(
|
||||
E.right(team),
|
||||
);
|
||||
teamRequestService.getRequestsCountInCollection = jest
|
||||
.fn()
|
||||
.mockResolvedValueOnce(0);
|
||||
|
||||
const response = await teamRequestService.createTeamRequest(
|
||||
'testcoll',
|
||||
team.id,
|
||||
'Test Request',
|
||||
'invalidjson',
|
||||
);
|
||||
|
||||
expect(response).toEqualLeft(JSON_INVALID);
|
||||
expect(mockPrisma.teamRequest.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should resolves and create team request', async () => {
|
||||
const dbRequest = dbTeamRequests[0];
|
||||
const teamRequest = teamRequests[0];
|
||||
|
||||
@@ -536,6 +572,52 @@ describe('findRequestAndNextRequest', () => {
|
||||
|
||||
expect(result).resolves.toEqualLeft(TEAM_REQ_NOT_FOUND);
|
||||
});
|
||||
test('should resolve left if the next request and given destCollId are different', () => {
|
||||
const args: MoveTeamRequestArgs = {
|
||||
srcCollID: teamRequests[0].collectionID,
|
||||
destCollID: 'different_coll_id',
|
||||
requestID: teamRequests[0].id,
|
||||
nextRequestID: teamRequests[4].id,
|
||||
};
|
||||
|
||||
mockPrisma.teamRequest.findFirst
|
||||
.mockResolvedValueOnce(dbTeamRequests[0])
|
||||
.mockResolvedValueOnce(dbTeamRequests[4]);
|
||||
|
||||
const result = teamRequestService.findRequestAndNextRequest(
|
||||
args.srcCollID,
|
||||
args.requestID,
|
||||
args.destCollID,
|
||||
args.nextRequestID,
|
||||
);
|
||||
|
||||
expect(result).resolves.toEqualLeft(TEAM_REQ_INVALID_TARGET_COLL_ID);
|
||||
});
|
||||
test('should resolve left if the request and the next request are from different teams', async () => {
|
||||
const args: MoveTeamRequestArgs = {
|
||||
srcCollID: teamRequests[0].collectionID,
|
||||
destCollID: teamRequests[4].collectionID,
|
||||
requestID: teamRequests[0].id,
|
||||
nextRequestID: teamRequests[4].id,
|
||||
};
|
||||
|
||||
const request = {
|
||||
...dbTeamRequests[0],
|
||||
teamID: 'different_team_id',
|
||||
};
|
||||
mockPrisma.teamRequest.findFirst
|
||||
.mockResolvedValueOnce(request)
|
||||
.mockResolvedValueOnce(dbTeamRequests[4]);
|
||||
|
||||
const result = await teamRequestService.findRequestAndNextRequest(
|
||||
args.srcCollID,
|
||||
args.requestID,
|
||||
args.destCollID,
|
||||
args.nextRequestID,
|
||||
);
|
||||
|
||||
expect(result).toEqualLeft(TEAM_REQ_INVALID_TARGET_COLL_ID);
|
||||
});
|
||||
});
|
||||
|
||||
describe('moveRequest', () => {
|
||||
@@ -725,13 +807,12 @@ describe('totalRequestsInATeam', () => {
|
||||
});
|
||||
expect(result).toEqual(0);
|
||||
});
|
||||
});
|
||||
describe('getTeamRequestsCount', () => {
|
||||
test('should return count of all Team Collections in the organization', async () => {
|
||||
mockPrisma.teamRequest.count.mockResolvedValueOnce(10);
|
||||
|
||||
describe('getTeamRequestsCount', () => {
|
||||
test('should return count of all Team Collections in the organization', async () => {
|
||||
mockPrisma.teamRequest.count.mockResolvedValueOnce(10);
|
||||
|
||||
const result = await teamRequestService.getTeamRequestsCount();
|
||||
expect(result).toEqual(10);
|
||||
});
|
||||
const result = await teamRequestService.getTeamRequestsCount();
|
||||
expect(result).toEqual(10);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UserCollection } from '@prisma/client';
|
||||
import { UserCollection, UserRequest as DbUserRequest } from '@prisma/client';
|
||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||
import {
|
||||
USER_COLL_DEST_SAME,
|
||||
@@ -11,12 +11,17 @@ import {
|
||||
USER_COLL_SHORT_TITLE,
|
||||
USER_COLL_ALREADY_ROOT,
|
||||
USER_NOT_OWNER,
|
||||
USER_NOT_FOUND,
|
||||
USER_COLL_INVALID_JSON,
|
||||
} from 'src/errors';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||
import { AuthUser } from 'src/types/AuthUser';
|
||||
import { ReqType } from 'src/types/RequestTypes';
|
||||
import { UserCollectionService } from './user-collection.service';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import { CollectionFolder } from 'src/types/CollectionFolder';
|
||||
import { UserCollectionExportJSONData } from './user-collections.model';
|
||||
|
||||
const mockPrisma = mockDeep<PrismaService>();
|
||||
const mockPubSub = mockDeep<PubSubService>();
|
||||
@@ -341,11 +346,485 @@ const rootGQLGQLUserCollectionList: UserCollection[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const userRESTRequestList: DbUserRequest[] = [
|
||||
{
|
||||
id: '123',
|
||||
collectionID: rootRESTUserCollection.id,
|
||||
userUid: user.uid,
|
||||
title: 'Request 1',
|
||||
request: {},
|
||||
type: ReqType.REST,
|
||||
orderIndex: 1,
|
||||
createdOn: new Date(),
|
||||
updatedOn: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
mockReset(mockPrisma);
|
||||
mockPubSub.publish.mockClear();
|
||||
});
|
||||
|
||||
describe('importCollectionsFromJSON', () => {
|
||||
test('should resolve left for invalid JSON string', async () => {
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
'invalidJSONString',
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
|
||||
expect(result).toEqual(E.left(USER_COLL_INVALID_JSON));
|
||||
});
|
||||
test('should resolve left if JSON string is not an array', async () => {
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify({}),
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
|
||||
expect(result).toEqual(E.left(USER_COLL_INVALID_JSON));
|
||||
});
|
||||
test('should resolve left if destCollectionID is invalid', async () => {
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.left(USER_COLL_NOT_FOUND));
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([]),
|
||||
user.uid,
|
||||
'invalidID',
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqual(E.left(USER_COLL_NOT_FOUND));
|
||||
});
|
||||
test('should resolve left if destCollectionID is not owned by this user', async () => {
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([]),
|
||||
'anotherUserUid',
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqual(E.left(USER_NOT_OWNER));
|
||||
});
|
||||
test('should resolve left if destCollection type miss match', async () => {
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([]),
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.GQL,
|
||||
);
|
||||
expect(result).toEqual(E.left(USER_COLL_NOT_SAME_TYPE));
|
||||
});
|
||||
test('should resolve right for valid JSON and destCollectionID provided', async () => {
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
|
||||
// private getChildCollectionsCount function call
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
mockPrisma.$transaction.mockResolvedValueOnce([]);
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([]),
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqual(E.right(true));
|
||||
});
|
||||
test('should resolve right for importing in root directory (destCollectionID == null)', async () => {
|
||||
// private getChildCollectionsCount function call
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
mockPrisma.$transaction.mockResolvedValueOnce([]);
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([
|
||||
{
|
||||
name: 'collection-name',
|
||||
folders: [],
|
||||
requests: [{ name: 'request-name' }],
|
||||
},
|
||||
]),
|
||||
user.uid,
|
||||
null,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqual(E.right(true));
|
||||
});
|
||||
test('should resolve right and publish event', async () => {
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
|
||||
// private getChildCollectionsCount function call
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
mockPrisma.$transaction.mockResolvedValueOnce([{}]);
|
||||
|
||||
const result = await userCollectionService.importCollectionsFromJSON(
|
||||
JSON.stringify([
|
||||
{
|
||||
name: 'collection-name',
|
||||
folders: [],
|
||||
requests: [{ name: 'request-name' }],
|
||||
},
|
||||
]),
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqual(E.right(true));
|
||||
expect(mockPubSub.publish).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportUserCollectionsToJSON', () => {
|
||||
test('should return a list of user collections successfully for valid collectionID input and structure - 1', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection (id: 1 [exporting this collection])
|
||||
|-> childTeamCollection
|
||||
| |-> <no request of root coll>
|
||||
|-> <no request of root coll>
|
||||
*/
|
||||
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([
|
||||
childRESTUserCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: exportUserCollectionToJSONObject
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(childRESTUserCollection));
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce([]);
|
||||
const returnFromCallee: CollectionFolder = {
|
||||
id: childRESTUserCollection.id,
|
||||
name: childRESTUserCollection.title,
|
||||
folders: [],
|
||||
requests: [],
|
||||
};
|
||||
|
||||
// Back to exportUserCollectionsToJSON
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
const returnedValue: UserCollectionExportJSONData = {
|
||||
exportedCollection: JSON.stringify({
|
||||
id: rootRESTUserCollection.id,
|
||||
name: rootRESTUserCollection.title,
|
||||
folders: [returnFromCallee],
|
||||
requests: [],
|
||||
}),
|
||||
collectionType: ReqType.REST,
|
||||
};
|
||||
|
||||
const result = await userCollectionService.exportUserCollectionsToJSON(
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqualRight(returnedValue);
|
||||
});
|
||||
|
||||
test('should return a list of user collections successfully for valid collectionID input and structure - 2', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection (id: 1 [exporting this collection])
|
||||
|-> childTeamCollection
|
||||
| |-> request1
|
||||
|-> <no request of root coll>
|
||||
*/
|
||||
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([
|
||||
childRESTUserCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: exportUserCollectionToJSONObject
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(childRESTUserCollection));
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce(userRESTRequestList);
|
||||
const returnFromCallee: CollectionFolder = {
|
||||
id: childRESTUserCollection.id,
|
||||
name: childRESTUserCollection.title,
|
||||
folders: [],
|
||||
requests: userRESTRequestList.map((r) => {
|
||||
return {
|
||||
id: r.id,
|
||||
name: r.title,
|
||||
...(r.request as Record<string, unknown>),
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
// Back to exportUserCollectionsToJSON
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
const returnedValue: UserCollectionExportJSONData = {
|
||||
exportedCollection: JSON.stringify({
|
||||
id: rootRESTUserCollection.id,
|
||||
name: rootRESTUserCollection.title,
|
||||
folders: [returnFromCallee],
|
||||
requests: [],
|
||||
}),
|
||||
collectionType: ReqType.REST,
|
||||
};
|
||||
|
||||
const result = await userCollectionService.exportUserCollectionsToJSON(
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqualRight(returnedValue);
|
||||
});
|
||||
test('should return a list of user collections successfully for valid collectionID input and structure - 3', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection (id: 1 [exporting this collection])
|
||||
|-> childTeamCollection
|
||||
| |-> request1
|
||||
|-> request2
|
||||
*/
|
||||
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([
|
||||
childRESTUserCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: exportUserCollectionToJSONObject
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(childRESTUserCollection));
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce(userRESTRequestList);
|
||||
const returnFromCallee: CollectionFolder = {
|
||||
id: childRESTUserCollection.id,
|
||||
name: childRESTUserCollection.title,
|
||||
folders: [],
|
||||
requests: userRESTRequestList.map((r) => {
|
||||
return {
|
||||
id: r.id,
|
||||
name: r.title,
|
||||
...(r.request as Record<string, unknown>),
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
// Back to exportUserCollectionsToJSON
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(rootRESTUserCollection));
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce(userRESTRequestList);
|
||||
|
||||
const returnedValue: UserCollectionExportJSONData = {
|
||||
exportedCollection: JSON.stringify({
|
||||
id: rootRESTUserCollection.id,
|
||||
name: rootRESTUserCollection.title,
|
||||
folders: [returnFromCallee],
|
||||
requests: userRESTRequestList.map((x) => {
|
||||
return {
|
||||
id: x.id,
|
||||
name: x.title,
|
||||
...(x.request as Record<string, unknown>), // type casting x.request of type Prisma.JSONValue to an object to enable spread
|
||||
};
|
||||
}),
|
||||
}),
|
||||
collectionType: ReqType.REST,
|
||||
};
|
||||
|
||||
const result = await userCollectionService.exportUserCollectionsToJSON(
|
||||
user.uid,
|
||||
rootRESTUserCollection.id,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqualRight(returnedValue);
|
||||
});
|
||||
test('should return a list of user collections successfully for collectionID == null', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection (id: 1 [exporting this collection])
|
||||
|-> childTeamCollection
|
||||
| |-> request1
|
||||
|-> request2
|
||||
*/
|
||||
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([
|
||||
childRESTUserCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: exportUserCollectionToJSONObject
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.right(childRESTUserCollection));
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
mockPrisma.userRequest.findMany.mockResolvedValueOnce(userRESTRequestList);
|
||||
const returnFromCallee: CollectionFolder = {
|
||||
id: childRESTUserCollection.id,
|
||||
name: childRESTUserCollection.title,
|
||||
folders: [],
|
||||
requests: userRESTRequestList.map((r) => {
|
||||
return {
|
||||
id: r.id,
|
||||
name: r.title,
|
||||
...(r.request as Record<string, unknown>),
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
// Back to exportUserCollectionsToJSON
|
||||
|
||||
const returnedValue: UserCollectionExportJSONData = {
|
||||
exportedCollection: JSON.stringify([returnFromCallee]),
|
||||
collectionType: ReqType.REST,
|
||||
};
|
||||
|
||||
const result = await userCollectionService.exportUserCollectionsToJSON(
|
||||
user.uid,
|
||||
null,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqualRight(returnedValue);
|
||||
});
|
||||
test('should return USER_COLL_NOT_FOUND if collectionID or its child not found in DB', async () => {
|
||||
/*
|
||||
Assuming collection and request structure is as follows:
|
||||
|
||||
rootTeamCollection (id: 1 [exporting this collection])
|
||||
|-> childTeamCollection
|
||||
| |-> request1 <NOT FOUND IN DATABASE>
|
||||
|-> request2
|
||||
*/
|
||||
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([
|
||||
childRESTUserCollection,
|
||||
]);
|
||||
|
||||
// RCV CALL 1: exportUserCollectionToJSONObject
|
||||
jest
|
||||
.spyOn(userCollectionService, 'getUserCollection')
|
||||
.mockResolvedValueOnce(E.left(USER_COLL_NOT_FOUND));
|
||||
|
||||
// Back to exportUserCollectionsToJSON
|
||||
|
||||
const result = await userCollectionService.exportUserCollectionsToJSON(
|
||||
user.uid,
|
||||
null,
|
||||
ReqType.REST,
|
||||
);
|
||||
expect(result).toEqualLeft(USER_COLL_NOT_FOUND);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUserOfCollection', () => {
|
||||
test('should return a user successfully with valid collectionID', async () => {
|
||||
mockPrisma.userCollection.findUniqueOrThrow.mockResolvedValueOnce({
|
||||
...rootRESTUserCollection,
|
||||
user: user,
|
||||
} as any);
|
||||
|
||||
const result = await userCollectionService.getUserOfCollection(
|
||||
rootRESTUserCollection.id,
|
||||
);
|
||||
expect(result).toEqualRight(user);
|
||||
});
|
||||
test('should return null with invalid collectionID', async () => {
|
||||
mockPrisma.userCollection.findUniqueOrThrow.mockRejectedValue('error');
|
||||
|
||||
const result = await userCollectionService.getUserOfCollection('invalidId');
|
||||
expect(result).toEqualLeft(USER_NOT_FOUND);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUserChildCollections', () => {
|
||||
test('should return a list of child collections successfully with valid collectionID and userID', async () => {
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce(
|
||||
childRESTUserCollectionList,
|
||||
);
|
||||
|
||||
const result = await userCollectionService.getUserChildCollections(
|
||||
user,
|
||||
rootRESTUserCollection.id,
|
||||
null,
|
||||
10,
|
||||
ReqType.REST,
|
||||
);
|
||||
|
||||
expect(result).toEqual(childRESTUserCollectionList);
|
||||
expect(mockPrisma.userCollection.findMany).toHaveBeenCalledWith({
|
||||
where: {
|
||||
userUid: user.uid,
|
||||
parentID: rootRESTUserCollection.id,
|
||||
type: ReqType.REST,
|
||||
},
|
||||
take: 10,
|
||||
skip: 0,
|
||||
cursor: undefined,
|
||||
});
|
||||
});
|
||||
test('should return an empty list if no child collections found', async () => {
|
||||
mockPrisma.userCollection.findMany.mockResolvedValueOnce([]);
|
||||
|
||||
const result = await userCollectionService.getUserChildCollections(
|
||||
user,
|
||||
rootRESTUserCollection.id,
|
||||
null,
|
||||
10,
|
||||
ReqType.REST,
|
||||
);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
expect(mockPrisma.userCollection.findMany).toHaveBeenCalledWith({
|
||||
where: {
|
||||
userUid: user.uid,
|
||||
parentID: rootRESTUserCollection.id,
|
||||
type: ReqType.REST,
|
||||
},
|
||||
take: 10,
|
||||
skip: 0,
|
||||
cursor: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCollectionCount', () => {
|
||||
test('should return the count of collections', async () => {
|
||||
const collectionID = 'collection123';
|
||||
const count = 5;
|
||||
|
||||
mockPrisma.userCollection.count.mockResolvedValueOnce(count);
|
||||
|
||||
const result = await userCollectionService.getCollectionCount(collectionID);
|
||||
|
||||
expect(result).toEqual(count);
|
||||
expect(mockPrisma.userCollection.count).toHaveBeenCalledTimes(1);
|
||||
expect(mockPrisma.userCollection.count).toHaveBeenCalledWith({
|
||||
where: { parentID: collectionID },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getParentOfUserCollection', () => {
|
||||
test('should return a user-collection successfully with valid collectionID', async () => {
|
||||
mockPrisma.userCollection.findUnique.mockResolvedValueOnce({
|
||||
|
||||
@@ -140,13 +140,15 @@ describe('UserHistoryService', () => {
|
||||
});
|
||||
describe('createUserHistory', () => {
|
||||
test('Should resolve right and create a REST request to users history and return a `UserHistory` object', async () => {
|
||||
const executedOn = new Date();
|
||||
|
||||
mockPrisma.userHistory.create.mockResolvedValueOnce({
|
||||
userUid: 'abc',
|
||||
id: '1',
|
||||
request: [{}],
|
||||
responseMetadata: [{}],
|
||||
reqType: ReqType.REST,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
});
|
||||
|
||||
@@ -156,7 +158,7 @@ describe('UserHistoryService', () => {
|
||||
request: JSON.stringify([{}]),
|
||||
responseMetadata: JSON.stringify([{}]),
|
||||
reqType: ReqType.REST,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
};
|
||||
|
||||
@@ -170,13 +172,15 @@ describe('UserHistoryService', () => {
|
||||
).toEqualRight(userHistory);
|
||||
});
|
||||
test('Should resolve right and create a GQL request to users history and return a `UserHistory` object', async () => {
|
||||
const executedOn = new Date();
|
||||
|
||||
mockPrisma.userHistory.create.mockResolvedValueOnce({
|
||||
userUid: 'abc',
|
||||
id: '1',
|
||||
request: [{}],
|
||||
responseMetadata: [{}],
|
||||
reqType: ReqType.GQL,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
});
|
||||
|
||||
@@ -186,7 +190,7 @@ describe('UserHistoryService', () => {
|
||||
request: JSON.stringify([{}]),
|
||||
responseMetadata: JSON.stringify([{}]),
|
||||
reqType: ReqType.GQL,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
};
|
||||
|
||||
@@ -210,13 +214,15 @@ describe('UserHistoryService', () => {
|
||||
).toEqualLeft(USER_HISTORY_INVALID_REQ_TYPE);
|
||||
});
|
||||
test('Should create a GQL request to users history and publish a created subscription', async () => {
|
||||
const executedOn = new Date();
|
||||
|
||||
mockPrisma.userHistory.create.mockResolvedValueOnce({
|
||||
userUid: 'abc',
|
||||
id: '1',
|
||||
request: [{}],
|
||||
responseMetadata: [{}],
|
||||
reqType: ReqType.GQL,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
});
|
||||
|
||||
@@ -226,7 +232,7 @@ describe('UserHistoryService', () => {
|
||||
request: JSON.stringify([{}]),
|
||||
responseMetadata: JSON.stringify([{}]),
|
||||
reqType: ReqType.GQL,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
};
|
||||
|
||||
@@ -243,13 +249,15 @@ describe('UserHistoryService', () => {
|
||||
);
|
||||
});
|
||||
test('Should create a REST request to users history and publish a created subscription', async () => {
|
||||
const executedOn = new Date();
|
||||
|
||||
mockPrisma.userHistory.create.mockResolvedValueOnce({
|
||||
userUid: 'abc',
|
||||
id: '1',
|
||||
request: [{}],
|
||||
responseMetadata: [{}],
|
||||
reqType: ReqType.REST,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
});
|
||||
|
||||
@@ -259,7 +267,7 @@ describe('UserHistoryService', () => {
|
||||
request: JSON.stringify([{}]),
|
||||
responseMetadata: JSON.stringify([{}]),
|
||||
reqType: ReqType.REST,
|
||||
executedOn: new Date(),
|
||||
executedOn,
|
||||
isStarred: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ import {
|
||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||
import {
|
||||
JSON_INVALID,
|
||||
USER_COLLECTION_NOT_FOUND,
|
||||
USER_COLL_NOT_FOUND,
|
||||
USER_REQUEST_INVALID_TYPE,
|
||||
USER_REQUEST_NOT_FOUND,
|
||||
USER_REQUEST_REORDERING_FAILED,
|
||||
} from 'src/errors';
|
||||
@@ -373,6 +376,101 @@ describe('UserRequestService', () => {
|
||||
|
||||
expect(result).resolves.toEqualLeft(JSON_INVALID);
|
||||
});
|
||||
test('Should resolve left for invalid collection ID', () => {
|
||||
const args: CreateUserRequestArgs = {
|
||||
collectionID: 'invalid-collection-id',
|
||||
title: userRequests[0].title,
|
||||
request: userRequests[0].request,
|
||||
type: userRequests[0].type,
|
||||
};
|
||||
|
||||
mockPrisma.userRequest.count.mockResolvedValue(
|
||||
dbUserRequests[0].orderIndex - 1,
|
||||
);
|
||||
mockUserCollectionService.getUserCollection.mockResolvedValue(
|
||||
E.left(USER_COLL_NOT_FOUND),
|
||||
);
|
||||
|
||||
const result = userRequestService.createRequest(
|
||||
args.collectionID,
|
||||
args.title,
|
||||
args.request,
|
||||
args.type,
|
||||
user,
|
||||
);
|
||||
|
||||
expect(result).resolves.toEqualLeft(USER_COLL_NOT_FOUND);
|
||||
});
|
||||
test('Should resolve left for wrong collection ID (using other users collection ID)', () => {
|
||||
const args: CreateUserRequestArgs = {
|
||||
collectionID: userRequests[0].collectionID,
|
||||
title: userRequests[0].title,
|
||||
request: userRequests[0].request,
|
||||
type: userRequests[0].type,
|
||||
};
|
||||
|
||||
mockPrisma.userRequest.count.mockResolvedValue(
|
||||
dbUserRequests[0].orderIndex - 1,
|
||||
);
|
||||
mockUserCollectionService.getUserCollection.mockResolvedValue(
|
||||
E.right({ type: userRequests[0].type, userUid: 'another-user' } as any),
|
||||
);
|
||||
|
||||
const result = userRequestService.createRequest(
|
||||
args.collectionID,
|
||||
args.title,
|
||||
args.request,
|
||||
args.type,
|
||||
user,
|
||||
);
|
||||
|
||||
expect(result).resolves.toEqualLeft(USER_COLLECTION_NOT_FOUND);
|
||||
});
|
||||
test('Should resolve left for collection type and request type miss match', () => {
|
||||
const args: CreateUserRequestArgs = {
|
||||
collectionID: userRequests[0].collectionID,
|
||||
title: userRequests[0].title,
|
||||
request: userRequests[0].request,
|
||||
type: userRequests[0].type,
|
||||
};
|
||||
|
||||
mockUserCollectionService.getUserCollection.mockResolvedValue(
|
||||
E.right({ type: 'invalid-type', userUid: user.uid } as any),
|
||||
);
|
||||
|
||||
const result = userRequestService.createRequest(
|
||||
args.collectionID,
|
||||
args.title,
|
||||
args.request,
|
||||
args.type,
|
||||
user,
|
||||
);
|
||||
|
||||
expect(result).resolves.toEqualLeft(USER_REQUEST_INVALID_TYPE);
|
||||
});
|
||||
test('Should resolve left if DB request type and parameter type is different', () => {
|
||||
const args: CreateUserRequestArgs = {
|
||||
collectionID: userRequests[0].collectionID,
|
||||
title: userRequests[0].title,
|
||||
request: userRequests[0].request,
|
||||
type: userRequests[0].type,
|
||||
};
|
||||
|
||||
mockPrisma.userRequest.count.mockResolvedValue(
|
||||
dbUserRequests[0].orderIndex - 1,
|
||||
);
|
||||
mockPrisma.userRequest.create.mockResolvedValue(dbUserRequests[0]);
|
||||
|
||||
const result = userRequestService.createRequest(
|
||||
args.collectionID,
|
||||
args.title,
|
||||
args.request,
|
||||
ReqType.GQL,
|
||||
user,
|
||||
);
|
||||
|
||||
expect(result).resolves.toEqualLeft(USER_REQUEST_INVALID_TYPE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateRequest', () => {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"edit": "編輯",
|
||||
"filter": "篩選回應",
|
||||
"go_back": "返回",
|
||||
"go_forward": "Go forward",
|
||||
"go_forward": "向前",
|
||||
"group_by": "分組方式",
|
||||
"label": "標籤",
|
||||
"learn_more": "瞭解更多",
|
||||
@@ -117,37 +117,37 @@
|
||||
"username": "使用者名稱"
|
||||
},
|
||||
"collection": {
|
||||
"created": "組合已建立",
|
||||
"different_parent": "Cannot reorder collection with different parent",
|
||||
"edit": "編輯組合",
|
||||
"invalid_name": "請提供有效的組合名稱",
|
||||
"invalid_root_move": "Collection already in the root",
|
||||
"moved": "Moved Successfully",
|
||||
"my_collections": "我的組合",
|
||||
"name": "我的新組合",
|
||||
"name_length_insufficient": "組合名稱至少要有 3 個字元。",
|
||||
"new": "建立組合",
|
||||
"order_changed": "Collection Order Updated",
|
||||
"renamed": "組合已重新命名",
|
||||
"created": "集合已建立",
|
||||
"different_parent": "無法為父集合不同的集合重新排序",
|
||||
"edit": "編輯集合",
|
||||
"invalid_name": "請提供有效的集合名稱",
|
||||
"invalid_root_move": "集合已在根目錄",
|
||||
"moved": "移動成功",
|
||||
"my_collections": "我的集合",
|
||||
"name": "我的新集合",
|
||||
"name_length_insufficient": "集合名稱至少要有 3 個字元。",
|
||||
"new": "建立集合",
|
||||
"order_changed": "集合順序已更新",
|
||||
"renamed": "集合已重新命名",
|
||||
"request_in_use": "請求正在使用中",
|
||||
"save_as": "另存為",
|
||||
"select": "選擇一個組合",
|
||||
"select": "選擇一個集合",
|
||||
"select_location": "選擇位置",
|
||||
"select_team": "選擇一個團隊",
|
||||
"team_collections": "團隊組合"
|
||||
"team_collections": "團隊集合"
|
||||
},
|
||||
"confirm": {
|
||||
"exit_team": "您確定要離開此團隊嗎?",
|
||||
"logout": "您確定要登出嗎?",
|
||||
"remove_collection": "您確定要永久刪除該組合嗎?",
|
||||
"remove_collection": "您確定要永久刪除該集合嗎?",
|
||||
"remove_environment": "您確定要永久刪除該環境嗎?",
|
||||
"remove_folder": "您確定要永久刪除該資料夾嗎?",
|
||||
"remove_history": "您確定要永久刪除全部歷史記錄嗎?",
|
||||
"remove_request": "您確定要永久刪除該請求嗎?",
|
||||
"remove_team": "您確定要刪除該團隊嗎?",
|
||||
"remove_telemetry": "您確定要退出遙測服務嗎?",
|
||||
"request_change": "您確定要捨棄當前請求嗎?未儲存的變更將遺失。",
|
||||
"save_unsaved_tab": "Do you want to save changes made in this tab?",
|
||||
"request_change": "您確定要捨棄目前的請求嗎?未儲存的變更將遺失。",
|
||||
"save_unsaved_tab": "您要儲存在此分頁做出的改動嗎?",
|
||||
"sync": "您想從雲端恢復您的工作區嗎?這將丟棄您的本地進度。"
|
||||
},
|
||||
"count": {
|
||||
@@ -160,13 +160,13 @@
|
||||
},
|
||||
"documentation": {
|
||||
"generate": "產生文件",
|
||||
"generate_message": "匯入 Hoppscotch 組合以隨時隨地產生 API 文件。"
|
||||
"generate_message": "匯入 Hoppscotch 集合以隨時隨地產生 API 文件。"
|
||||
},
|
||||
"empty": {
|
||||
"authorization": "該請求沒有使用任何授權",
|
||||
"body": "該請求沒有任何請求主體",
|
||||
"collection": "組合為空",
|
||||
"collections": "組合為空",
|
||||
"collection": "集合為空",
|
||||
"collections": "集合為空",
|
||||
"documentation": "連線到 GraphQL 端點以檢視文件",
|
||||
"endpoint": "端點不能留空",
|
||||
"environments": "環境為空",
|
||||
@@ -209,7 +209,7 @@
|
||||
"browser_support_sse": "此瀏覽器似乎不支援 SSE。",
|
||||
"check_console_details": "檢查控制台日誌以獲悉詳情",
|
||||
"curl_invalid_format": "cURL 格式不正確",
|
||||
"danger_zone": "Danger zone",
|
||||
"danger_zone": "危險地帶",
|
||||
"delete_account": "您的帳號目前為這些團隊的擁有者:",
|
||||
"delete_account_description": "您在刪除帳號前必須先將您自己從團隊中移除、轉移擁有權,或是刪除團隊。",
|
||||
"empty_req_name": "空請求名稱",
|
||||
@@ -277,38 +277,38 @@
|
||||
"tests": "編寫測試指令碼以自動除錯。"
|
||||
},
|
||||
"hide": {
|
||||
"collection": "隱藏組合面板",
|
||||
"collection": "隱藏集合面板",
|
||||
"more": "隱藏更多",
|
||||
"preview": "隱藏預覽",
|
||||
"sidebar": "隱藏側邊欄"
|
||||
},
|
||||
"import": {
|
||||
"collections": "匯入組合",
|
||||
"collections": "匯入集合",
|
||||
"curl": "匯入 cURL",
|
||||
"failed": "匯入失敗",
|
||||
"from_gist": "從 Gist 匯入",
|
||||
"from_gist_description": "從 Gist 網址匯入",
|
||||
"from_insomnia": "從 Insomnia 匯入",
|
||||
"from_insomnia_description": "從 Insomnia 組合匯入",
|
||||
"from_insomnia_description": "從 Insomnia 集合匯入",
|
||||
"from_json": "從 Hoppscotch 匯入",
|
||||
"from_json_description": "從 Hoppscotch 組合檔匯入",
|
||||
"from_my_collections": "從我的組合匯入",
|
||||
"from_my_collections_description": "從我的組合檔匯入",
|
||||
"from_json_description": "從 Hoppscotch 集合檔匯入",
|
||||
"from_my_collections": "從我的集合匯入",
|
||||
"from_my_collections_description": "從我的集合檔匯入",
|
||||
"from_openapi": "從 OpenAPI 匯入",
|
||||
"from_openapi_description": "從 OpenAPI 規格檔 (YML/JSON) 匯入",
|
||||
"from_postman": "從 Postman 匯入",
|
||||
"from_postman_description": "從 Postman 組合匯入",
|
||||
"from_postman_description": "從 Postman 集合匯入",
|
||||
"from_url": "從網址匯入",
|
||||
"gist_url": "輸入 Gist 網址",
|
||||
"import_from_url_invalid_fetch": "無法從網址取得資料",
|
||||
"import_from_url_invalid_file_format": "匯入組合時發生錯誤",
|
||||
"import_from_url_invalid_file_format": "匯入集合時發生錯誤",
|
||||
"import_from_url_invalid_type": "不支援此類型。可接受的值為 'hoppscotch'、'openapi'、'postman'、'insomnia'",
|
||||
"import_from_url_success": "已匯入組合",
|
||||
"json_description": "從 Hoppscotch 組合 JSON 檔匯入組合",
|
||||
"import_from_url_success": "已匯入集合",
|
||||
"json_description": "從 Hoppscotch 集合 JSON 檔匯入集合",
|
||||
"title": "匯入"
|
||||
},
|
||||
"layout": {
|
||||
"collapse_collection": "隱藏或顯示組合",
|
||||
"collapse_collection": "隱藏或顯示集合",
|
||||
"collapse_sidebar": "隱藏或顯示側邊欄",
|
||||
"column": "垂直版面",
|
||||
"name": "配置",
|
||||
@@ -316,8 +316,8 @@
|
||||
"zen_mode": "專注模式"
|
||||
},
|
||||
"modal": {
|
||||
"close_unsaved_tab": "You have unsaved changes",
|
||||
"collections": "組合",
|
||||
"close_unsaved_tab": "您有未儲存的改動",
|
||||
"collections": "集合",
|
||||
"confirm": "確認",
|
||||
"edit_request": "編輯請求",
|
||||
"import_export": "匯入/匯出"
|
||||
@@ -374,9 +374,9 @@
|
||||
"email_verification_mail": "已將驗證信寄送至您的電子郵件地址。請點擊信中連結以驗證您的電子郵件地址。",
|
||||
"no_permission": "您沒有權限執行此操作。",
|
||||
"owner": "擁有者",
|
||||
"owner_description": "擁有者可以新增、編輯和刪除請求、組合和團隊成員。",
|
||||
"owner_description": "擁有者可以新增、編輯和刪除請求、集合和團隊成員。",
|
||||
"roles": "角色",
|
||||
"roles_description": "角色用來控制對共用組合的存取權。",
|
||||
"roles_description": "角色用來控制對共用集合的存取權。",
|
||||
"updated": "已更新個人檔案",
|
||||
"viewer": "檢視者",
|
||||
"viewer_description": "檢視者只能檢視和使用請求。"
|
||||
@@ -396,8 +396,8 @@
|
||||
"text": "文字"
|
||||
},
|
||||
"copy_link": "複製連結",
|
||||
"different_collection": "Cannot reorder requests from different collections",
|
||||
"duplicated": "Request duplicated",
|
||||
"different_collection": "無法重新排列來自不同集合的請求",
|
||||
"duplicated": "已複製請求",
|
||||
"duration": "持續時間",
|
||||
"enter_curl": "輸入 cURL",
|
||||
"generate_code": "產生程式碼",
|
||||
@@ -405,10 +405,10 @@
|
||||
"header_list": "請求標頭列表",
|
||||
"invalid_name": "請提供請求名稱",
|
||||
"method": "方法",
|
||||
"moved": "Request moved",
|
||||
"moved": "已移動請求",
|
||||
"name": "請求名稱",
|
||||
"new": "新請求",
|
||||
"order_changed": "Request Order Updated",
|
||||
"order_changed": "已更新請求順序",
|
||||
"override": "覆寫",
|
||||
"override_help": "在標頭設置 <kbd>Content-Type</kbd>",
|
||||
"overriden": "已覆寫",
|
||||
@@ -432,7 +432,7 @@
|
||||
"view_my_links": "檢視我的連結"
|
||||
},
|
||||
"response": {
|
||||
"audio": "Audio",
|
||||
"audio": "音訊",
|
||||
"body": "回應本體",
|
||||
"filter_response_body": "篩選 JSON 回應本體 (使用 JSONPath 語法)",
|
||||
"headers": "回應標頭",
|
||||
@@ -446,7 +446,7 @@
|
||||
"status": "狀態",
|
||||
"time": "時間",
|
||||
"title": "回應",
|
||||
"video": "Video",
|
||||
"video": "視訊",
|
||||
"waiting_for_connection": "等待連線",
|
||||
"xml": "XML"
|
||||
},
|
||||
@@ -494,7 +494,7 @@
|
||||
"short_codes_description": "我們為您打造的快捷碼。",
|
||||
"sidebar_on_left": "左側邊欄",
|
||||
"sync": "同步",
|
||||
"sync_collections": "組合",
|
||||
"sync_collections": "集合",
|
||||
"sync_description": "這些設定會同步到雲端。",
|
||||
"sync_environments": "環境",
|
||||
"sync_history": "歷史",
|
||||
@@ -551,7 +551,7 @@
|
||||
"previous_method": "選擇上一個方法",
|
||||
"put_method": "選擇 PUT 方法",
|
||||
"reset_request": "重置請求",
|
||||
"save_to_collections": "儲存到組合",
|
||||
"save_to_collections": "儲存到集合",
|
||||
"send_request": "傳送請求",
|
||||
"title": "請求"
|
||||
},
|
||||
@@ -570,7 +570,7 @@
|
||||
},
|
||||
"show": {
|
||||
"code": "顯示程式碼",
|
||||
"collection": "顯示組合面板",
|
||||
"collection": "顯示集合面板",
|
||||
"more": "顯示更多",
|
||||
"sidebar": "顯示側邊欄"
|
||||
},
|
||||
@@ -639,9 +639,9 @@
|
||||
"tab": {
|
||||
"authorization": "授權",
|
||||
"body": "請求本體",
|
||||
"collections": "組合",
|
||||
"collections": "集合",
|
||||
"documentation": "幫助文件",
|
||||
"environments": "Environments",
|
||||
"environments": "環境",
|
||||
"headers": "請求標頭",
|
||||
"history": "歷史記錄",
|
||||
"mqtt": "MQTT",
|
||||
@@ -666,7 +666,7 @@
|
||||
"email_do_not_match": "電子信箱與您的帳號資料不一致。請聯絡您的團隊擁有者。",
|
||||
"exit": "退出團隊",
|
||||
"exit_disabled": "團隊擁有者無法退出團隊",
|
||||
"invalid_coll_id": "Invalid collection ID",
|
||||
"invalid_coll_id": "集合 ID 無效",
|
||||
"invalid_email_format": "電子信箱格式無效",
|
||||
"invalid_id": "團隊 ID 無效。請聯絡您的團隊擁有者。",
|
||||
"invalid_invite_link": "邀請連結無效",
|
||||
@@ -690,21 +690,21 @@
|
||||
"member_removed": "使用者已移除",
|
||||
"member_role_updated": "使用者角色已更新",
|
||||
"members": "成員",
|
||||
"more_members": "+{count} more",
|
||||
"more_members": "還有 {count} 位",
|
||||
"name_length_insufficient": "團隊名稱至少為 6 個字元",
|
||||
"name_updated": "團隊名稱已更新",
|
||||
"new": "新團隊",
|
||||
"new_created": "已建立新團隊",
|
||||
"new_name": "我的新團隊",
|
||||
"no_access": "您沒有編輯組合的許可權",
|
||||
"no_access": "您沒有編輯集合的許可權",
|
||||
"no_invite_found": "未找到邀請。請聯絡您的團隊擁有者。",
|
||||
"no_request_found": "Request not found.",
|
||||
"no_request_found": "找不到請求。",
|
||||
"not_found": "找不到團隊。請聯絡您的團隊擁有者。",
|
||||
"not_valid_viewer": "您不是一個有效的檢視者。請聯絡您的團隊擁有者。",
|
||||
"parent_coll_move": "Cannot move collection to a child collection",
|
||||
"parent_coll_move": "無法將集合移動至子集合",
|
||||
"pending_invites": "待定邀請",
|
||||
"permissions": "許可權",
|
||||
"same_target_destination": "Same target and destination",
|
||||
"same_target_destination": "目標和目的地相同",
|
||||
"saved": "團隊已儲存",
|
||||
"select_a_team": "選擇團隊",
|
||||
"title": "團隊",
|
||||
@@ -734,9 +734,9 @@
|
||||
"url": "網址"
|
||||
},
|
||||
"workspace": {
|
||||
"change": "Change workspace",
|
||||
"personal": "My Workspace",
|
||||
"team": "Team Workspace",
|
||||
"title": "Workspaces"
|
||||
"change": "切換工作區",
|
||||
"personal": "我的工作區",
|
||||
"team": "團隊工作區",
|
||||
"title": "工作區"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user