Files
Compass/backend/api/tests/unit/update-me.unit.test.ts
2026-01-15 16:54:29 +01:00

255 lines
11 KiB
TypeScript

jest.mock('common/api/user-types');
jest.mock('common/util/clean-username');
jest.mock('shared/supabase/init');
jest.mock('common/util/object');
jest.mock('lodash');
jest.mock('shared/utils');
jest.mock('shared/supabase/users');
jest.mock('shared/websockets/helpers');
jest.mock('common/envs/constants');
import { updateMe } from "api/update-me";
import { toUserAPIResponse } from "common/api/user-types";
import * as cleanUsernameModules from "common/util/clean-username";
import * as supabaseInit from "shared/supabase/init";
import * as objectUtils from "common/util/object";
import * as lodashModules from "lodash";
import * as sharedUtils from "shared/utils";
import * as supabaseUsers from "shared/supabase/users";
import * as websocketHelperModules from "shared/websockets/helpers";
import { AuthedUser } from "api/helpers/endpoint";
describe('updateMe', () => {
let mockPg = {} as any;
beforeEach(() => {
jest.resetAllMocks();
mockPg = {
oneOrNone: jest.fn(),
none: jest.fn()
};
(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('when given valid input', () => {
it('should update user information', async () => {
const mockProps = {} as any;
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockUpdate = {
name: "mockName",
username: "mockUsername",
avatarUrl: "mockAvatarUrl",
bio: "mockBio",
link: {"mockLink" : "mockLinkValue"},
optOutBetWarnings:true,
website: "mockWebsite",
twitterHandle: "mockTwitterHandle",
discordHandle: "mockDiscordHandle",
};
const mockStripped = {
bio: "mockBio"
};
const mockData = {link: "mockNewLinks"};
const arrySpy = jest.spyOn(Array.prototype, 'includes');
(lodashModules.cloneDeep as jest.Mock).mockReturnValue(mockUpdate);
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
(cleanUsernameModules.cleanDisplayName as jest.Mock).mockReturnValue(mockUpdate.name);
(cleanUsernameModules.cleanUsername as jest.Mock).mockReturnValue(mockUpdate.username);
arrySpy.mockReturnValue(false);
(sharedUtils.getUserByUsername as jest.Mock).mockReturnValue(false);
(supabaseUsers.updateUser as jest.Mock)
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(null);
(lodashModules.mapValues as jest.Mock).mockReturnValue(mockStripped);
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockData);
(mockPg.none as jest.Mock)
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(null);
(objectUtils.removeUndefinedProps as jest.Mock).mockReturnValue("mockRemoveUndefinedProps");
(websocketHelperModules.broadcastUpdatedUser as jest.Mock).mockReturnValue(null);
(toUserAPIResponse as jest.Mock).mockReturnValue(null);
await updateMe(mockProps, mockAuth, mockReq);
expect(lodashModules.cloneDeep).toBeCalledTimes(1);
expect(lodashModules.cloneDeep).toBeCalledWith(mockProps);
expect(sharedUtils.getUser).toBeCalledTimes(1);
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
expect(cleanUsernameModules.cleanDisplayName).toBeCalledTimes(1);
expect(cleanUsernameModules.cleanDisplayName).toBeCalledWith(mockUpdate.name);
expect(cleanUsernameModules.cleanUsername).toBeCalledTimes(1);
expect(cleanUsernameModules.cleanUsername).toBeCalledWith(mockUpdate.username);
expect(arrySpy).toBeCalledTimes(1);
expect(arrySpy).toBeCalledWith(mockUpdate.username);
expect(sharedUtils.getUserByUsername).toBeCalledTimes(1);
expect(sharedUtils.getUserByUsername).toBeCalledWith(mockUpdate.username);
expect(supabaseUsers.updateUser).toBeCalledTimes(2);
expect(supabaseUsers.updateUser).toHaveBeenNthCalledWith(
1,
expect.any(Object),
mockAuth.uid,
'mockRemoveUndefinedProps'
);
expect(supabaseUsers.updateUser).toHaveBeenNthCalledWith(
2,
expect.any(Object),
mockAuth.uid,
{avatarUrl: mockUpdate.avatarUrl}
);
expect(lodashModules.mapValues).toBeCalledTimes(1);
expect(lodashModules.mapValues).toBeCalledWith(
expect.any(Object),
expect.any(Function)
);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('update users'),
{
adds: expect.any(Object),
removes: expect.any(Array),
id: mockAuth.uid
}
);
expect(mockPg.none).toBeCalledTimes(2);
expect(mockPg.none).toHaveBeenNthCalledWith(
1,
expect.stringContaining(`update users set name = $1 where id = $2`),
[mockUpdate.name, mockAuth.uid]
);
expect(mockPg.none).toHaveBeenNthCalledWith(
2,
expect.stringContaining(`update users set username = $1 where id = $2`),
[mockUpdate.username, mockAuth.uid]
);
expect(objectUtils.removeUndefinedProps).toBeCalledTimes(2);
expect(objectUtils.removeUndefinedProps).toHaveBeenNthCalledWith(
2,
{
id: mockAuth.uid,
name: mockUpdate.name,
username: mockUpdate.username,
avatarUrl: mockUpdate.avatarUrl,
link: mockData.link
}
);
expect(websocketHelperModules.broadcastUpdatedUser).toBeCalledTimes(1);
expect(websocketHelperModules.broadcastUpdatedUser).toBeCalledWith('mockRemoveUndefinedProps');
expect(toUserAPIResponse).toBeCalledTimes(1);
});
});
describe('when an error occurs', () => {
it('should throw if no account was found', async () => {
const mockProps = {} as any;
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockUpdate = {
name: "mockName",
username: "mockUsername",
avatarUrl: "mockAvatarUrl",
bio: "mockBio",
link: {"mockLink" : "mockLinkValue"},
optOutBetWarnings:true,
website: "mockWebsite",
twitterHandle: "mockTwitterHandle",
discordHandle: "mockDiscordHandle",
};
(lodashModules.cloneDeep as jest.Mock).mockReturnValue(mockUpdate);
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
expect(updateMe(mockProps, mockAuth, mockReq))
.rejects
.toThrow('Your account was not found');
});
it('should throw if the username is invalid', async () => {
const mockProps = {} as any;
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockUpdate = {
name: "mockName",
username: "mockUsername",
avatarUrl: "mockAvatarUrl",
bio: "mockBio",
link: {"mockLink" : "mockLinkValue"},
optOutBetWarnings:true,
website: "mockWebsite",
twitterHandle: "mockTwitterHandle",
discordHandle: "mockDiscordHandle",
};
(lodashModules.cloneDeep as jest.Mock).mockReturnValue(mockUpdate);
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
(cleanUsernameModules.cleanDisplayName as jest.Mock).mockReturnValue(mockUpdate.name);
(cleanUsernameModules.cleanUsername as jest.Mock).mockReturnValue(false);
expect(updateMe(mockProps, mockAuth, mockReq))
.rejects
.toThrow('Invalid username');
});
it('should throw if the username is reserved', async () => {
const mockProps = {} as any;
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockUpdate = {
name: "mockName",
username: "mockUsername",
avatarUrl: "mockAvatarUrl",
bio: "mockBio",
link: {"mockLink" : "mockLinkValue"},
optOutBetWarnings:true,
website: "mockWebsite",
twitterHandle: "mockTwitterHandle",
discordHandle: "mockDiscordHandle",
};
const arrySpy = jest.spyOn(Array.prototype, 'includes');
(lodashModules.cloneDeep as jest.Mock).mockReturnValue(mockUpdate);
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
(cleanUsernameModules.cleanDisplayName as jest.Mock).mockReturnValue(mockUpdate.name);
(cleanUsernameModules.cleanUsername as jest.Mock).mockReturnValue(mockUpdate.username);
arrySpy.mockReturnValue(true);
expect(updateMe(mockProps, mockAuth, mockReq))
.rejects
.toThrow('This username is reserved');
});
it('should throw if the username is taken', async () => {
const mockProps = {} as any;
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockUpdate = {
name: "mockName",
username: "mockUsername",
avatarUrl: "mockAvatarUrl",
bio: "mockBio",
link: {"mockLink" : "mockLinkValue"},
optOutBetWarnings:true,
website: "mockWebsite",
twitterHandle: "mockTwitterHandle",
discordHandle: "mockDiscordHandle",
};
const arrySpy = jest.spyOn(Array.prototype, 'includes');
(lodashModules.cloneDeep as jest.Mock).mockReturnValue(mockUpdate);
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
(cleanUsernameModules.cleanDisplayName as jest.Mock).mockReturnValue(mockUpdate.name);
(cleanUsernameModules.cleanUsername as jest.Mock).mockReturnValue(mockUpdate.username);
arrySpy.mockReturnValue(false);
(sharedUtils.getUserByUsername as jest.Mock).mockReturnValue(true);
expect(updateMe(mockProps, mockAuth, mockReq))
.rejects
.toThrow('Username already taken');
});
});
});