mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-02 13:58:18 -05:00
Adding/Updating API unit tests (#26)
This commit is contained in:
committed by
GitHub
parent
a3c479ff92
commit
449b32d4bc
@@ -11,8 +11,7 @@ import { throwErrorIfNotMod } from "shared/helpers/auth";
|
||||
import * as constants from "common/envs/constants";
|
||||
import * as supabaseUsers from "shared/supabase/users";
|
||||
import * as sharedAnalytics from "shared/analytics";
|
||||
import { } from "shared/helpers/auth";
|
||||
import { APIError, AuthedUser } from "api/helpers/endpoint"
|
||||
import { AuthedUser } from "api/helpers/endpoint"
|
||||
|
||||
|
||||
describe('banUser', () => {
|
||||
@@ -24,13 +23,13 @@ describe('banUser', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('ban a user successfully', async () => {
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should ban a user successfully', async () => {
|
||||
const mockUser = {
|
||||
userId: '123',
|
||||
unban: false
|
||||
@@ -42,15 +41,25 @@ describe('banUser', () => {
|
||||
|
||||
await banUser(mockUser, mockAuth, mockReq);
|
||||
|
||||
expect(throwErrorIfNotMod).toBeCalledTimes(1);
|
||||
expect(throwErrorIfNotMod).toBeCalledWith(mockAuth.uid);
|
||||
expect(constants.isAdminId).toBeCalledTimes(1);
|
||||
expect(constants.isAdminId).toBeCalledWith(mockUser.userId);
|
||||
expect(sharedAnalytics.trackPublicEvent)
|
||||
.toBeCalledWith(mockAuth.uid, 'ban user', {userId: mockUser.userId});
|
||||
expect(supabaseUsers.updateUser)
|
||||
.toBeCalledWith(mockPg, mockUser.userId, {isBannedFromPosting: true});
|
||||
expect(sharedAnalytics.trackPublicEvent).toBeCalledTimes(1);
|
||||
expect(sharedAnalytics.trackPublicEvent).toBeCalledWith(
|
||||
mockAuth.uid,
|
||||
'ban user',
|
||||
{userId: mockUser.userId}
|
||||
);
|
||||
expect(supabaseUsers.updateUser).toBeCalledTimes(1);
|
||||
expect(supabaseUsers.updateUser).toBeCalledWith(
|
||||
mockPg,
|
||||
mockUser.userId,
|
||||
{isBannedFromPosting: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('unban a user successfully', async () => {
|
||||
it('should unban a user successfully', async () => {
|
||||
const mockUser = {
|
||||
userId: '123',
|
||||
unban: true
|
||||
@@ -64,13 +73,20 @@ describe('banUser', () => {
|
||||
|
||||
expect(throwErrorIfNotMod).toBeCalledWith(mockAuth.uid);
|
||||
expect(constants.isAdminId).toBeCalledWith(mockUser.userId);
|
||||
expect(sharedAnalytics.trackPublicEvent)
|
||||
.toBeCalledWith(mockAuth.uid, 'ban user', {userId: mockUser.userId});
|
||||
expect(supabaseUsers.updateUser)
|
||||
.toBeCalledWith(mockPg, mockUser.userId, {isBannedFromPosting: false});
|
||||
expect(sharedAnalytics.trackPublicEvent).toBeCalledWith(
|
||||
mockAuth.uid,
|
||||
'ban user',
|
||||
{userId: mockUser.userId}
|
||||
);
|
||||
expect(supabaseUsers.updateUser).toBeCalledWith(
|
||||
mockPg,
|
||||
mockUser.userId,
|
||||
{isBannedFromPosting: false}
|
||||
);
|
||||
});
|
||||
|
||||
it('throw and error if the ban requester is not a mod or admin', async () => {
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('throw if the ban requester is not a mod or admin', async () => {
|
||||
const mockUser = {
|
||||
userId: '123',
|
||||
unban: false
|
||||
@@ -79,21 +95,16 @@ describe('banUser', () => {
|
||||
const mockReq = {} as any;
|
||||
|
||||
(throwErrorIfNotMod as jest.Mock).mockRejectedValue(
|
||||
new APIError(
|
||||
403,
|
||||
`User ${mockAuth.uid} must be an admin or trusted to perform this action.`
|
||||
)
|
||||
new Error(`User ${mockAuth.uid} must be an admin or trusted to perform this action.`)
|
||||
);
|
||||
|
||||
await expect(banUser(mockUser, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`User ${mockAuth.uid} must be an admin or trusted to perform this action.`);
|
||||
expect(throwErrorIfNotMod).toBeCalledWith(mockAuth.uid);
|
||||
expect(sharedAnalytics.trackPublicEvent).toBeCalledTimes(0);
|
||||
expect(supabaseUsers.updateUser).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
it('throw an error if the ban target is an admin', async () => {
|
||||
it('throw if the ban target is an admin', async () => {
|
||||
const mockUser = {
|
||||
userId: '123',
|
||||
unban: false
|
||||
@@ -108,8 +119,6 @@ describe('banUser', () => {
|
||||
.toThrowError('Cannot ban admin');
|
||||
expect(throwErrorIfNotMod).toBeCalledWith(mockAuth.uid);
|
||||
expect(constants.isAdminId).toBeCalledWith(mockUser.userId);
|
||||
expect(sharedAnalytics.trackPublicEvent).toBeCalledTimes(0);
|
||||
expect(supabaseUsers.updateUser).toBeCalledTimes(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -23,37 +23,35 @@ describe('blockUser', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
describe('when given valid input', () => {
|
||||
it('block the user successfully', async () => {
|
||||
const mockParams = { id: '123' }
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(supabaseUsers.updatePrivateUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await blockUserModule.blockUser(mockParams, mockAuth, mockReq)
|
||||
|
||||
expect(mockPg.tx).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(supabaseUsers.updatePrivateUser)
|
||||
.toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockParams.id)}
|
||||
);
|
||||
expect(supabaseUsers.updatePrivateUser)
|
||||
.toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
mockParams.id,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockAuth.uid)}
|
||||
);
|
||||
expect(mockPg.tx).toHaveBeenCalledTimes(1);
|
||||
expect(supabaseUsers.updatePrivateUser).toBeCalledTimes(2);
|
||||
expect(supabaseUsers.updatePrivateUser).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockParams.id)}
|
||||
);
|
||||
expect(supabaseUsers.updatePrivateUser).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.any(Object),
|
||||
mockParams.id,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockAuth.uid)}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('throw an error if the user tries to block themselves', async () => {
|
||||
const mockParams = { id: '123' }
|
||||
const mockAuth = {uid: '123'} as AuthedUser;
|
||||
@@ -61,12 +59,9 @@ describe('blockUser', () => {
|
||||
|
||||
expect(blockUserModule.blockUser(mockParams, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('You cannot block yourself')
|
||||
|
||||
expect(mockPg.tx).toHaveBeenCalledTimes(0)
|
||||
.toThrowError('You cannot block yourself');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('unblockUser', () => {
|
||||
@@ -84,35 +79,32 @@ describe('unblockUser', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('block the user successfully', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should block the user successfully', async () => {
|
||||
const mockParams = { id: '123' }
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(supabaseUsers.updatePrivateUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await blockUserModule.unblockUser(mockParams, mockAuth, mockReq)
|
||||
|
||||
expect(mockPg.tx).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(supabaseUsers.updatePrivateUser)
|
||||
.toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockParams.id)}
|
||||
);
|
||||
expect(supabaseUsers.updatePrivateUser)
|
||||
.toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
mockParams.id,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockAuth.uid)}
|
||||
);
|
||||
expect(mockPg.tx).toHaveBeenCalledTimes(1);
|
||||
expect(supabaseUsers.updatePrivateUser).toBeCalledTimes(2);
|
||||
expect(supabaseUsers.updatePrivateUser).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockParams.id)}
|
||||
);
|
||||
expect(supabaseUsers.updatePrivateUser).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.any(Object),
|
||||
mockParams.id,
|
||||
{ blockedByUserIds: supabaseUtils.FieldVal.arrayConcat(mockAuth.uid)}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,32 +1,41 @@
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import {getCompatibleProfiles} from "api/compatible-profiles";
|
||||
jest.mock('shared/supabase/init');
|
||||
|
||||
import {getCompatibleProfiles} from "api/compatible-profiles";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
|
||||
jest.mock('shared/supabase/init')
|
||||
|
||||
describe('getCompatibleProfiles', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
const mockPg = {
|
||||
none: jest.fn().mockResolvedValue(null),
|
||||
one: jest.fn().mockResolvedValue(null),
|
||||
oneOrNone: jest.fn().mockResolvedValue(null),
|
||||
any: jest.fn().mockResolvedValue([]),
|
||||
map: jest.fn().mockResolvedValue([["abc", {score: 0.69}]]),
|
||||
} as any;
|
||||
mockPg = {
|
||||
map: jest.fn().mockResolvedValue([]),
|
||||
};
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully get compatible profiles when supplied with a valid user Id', async () => {
|
||||
const results = await getCompatibleProfiles("123");
|
||||
expect(results.status).toEqual('success');
|
||||
expect(results.profileCompatibilityScores).toEqual({"abc": {score: 0.69}});
|
||||
});
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully get compatible profiles', async () => {
|
||||
const mockProps = '123';
|
||||
const mockScores = ["abc", { score: 0.69 }];
|
||||
const mockScoresFromEntries = {"abc": { score: 0.69 }};
|
||||
|
||||
(mockPg.map as jest.Mock).mockResolvedValue([mockScores]);
|
||||
|
||||
const results = await getCompatibleProfiles(mockProps);
|
||||
const [sql, param, fn] = mockPg.map.mock.calls[0];
|
||||
|
||||
expect(results.status).toEqual('success');
|
||||
expect(results.profileCompatibilityScores).toEqual(mockScoresFromEntries);
|
||||
expect(mockPg.map).toBeCalledTimes(1);
|
||||
expect(sql).toContain('select *');
|
||||
expect(sql).toContain('from compatibility_scores');
|
||||
expect(param).toStrictEqual([mockProps]);
|
||||
expect(fn).toEqual(expect.any(Function));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,6 @@ describe('contact', () => {
|
||||
let mockPg: any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn(),
|
||||
};
|
||||
@@ -22,13 +21,12 @@ describe('contact', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('send a discord message to the user', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should send a discord message to the user', async () => {
|
||||
const mockProps = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
@@ -52,29 +50,42 @@ describe('contact', () => {
|
||||
const mockReturnData = {} as any;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({ data: mockReturnData, error: null });
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockDbUser);
|
||||
(sendDiscordMessage as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
|
||||
const results = await contact(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(results.success).toBe(true);
|
||||
expect(results.result).toStrictEqual({});
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1)
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
mockPg,
|
||||
expect.any(Object),
|
||||
'contact',
|
||||
{
|
||||
user_id: mockProps.userId,
|
||||
content: JSON.stringify(mockProps.content)
|
||||
}
|
||||
);
|
||||
expect(results.success).toBe(true);
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockDbUser);
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select name from users where id = $1'),
|
||||
[mockProps.userId]
|
||||
);
|
||||
expect(sendDiscordMessage).toBeCalledTimes(1);
|
||||
expect(sendDiscordMessage).toBeCalledWith(
|
||||
expect.stringContaining(`New message from ${mockDbUser.name}`),
|
||||
'contact'
|
||||
)
|
||||
expect(sendDiscordMessage).toBeCalledTimes(1);
|
||||
);
|
||||
});
|
||||
|
||||
it('throw an error if the inser function fails', async () => {
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the insert function fails', async () => {
|
||||
const mockProps = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
@@ -100,15 +111,59 @@ describe('contact', () => {
|
||||
expect(contact(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Failed to submit contact message');
|
||||
});
|
||||
|
||||
it('should throw if unable to send discord message', async () => {
|
||||
const mockProps = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Error test message'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockDbUser = { name: 'Humphrey Mocker' };
|
||||
const mockReturnData = {} as any;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({ data: mockReturnData, error: null });
|
||||
|
||||
const results = await contact(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(results.success).toBe(true);
|
||||
expect(results.result).toStrictEqual({});
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1)
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
mockPg,
|
||||
expect.any(Object),
|
||||
'contact',
|
||||
{
|
||||
user_id: mockProps.userId,
|
||||
content: JSON.stringify(mockProps.content)
|
||||
}
|
||||
);
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockDbUser);
|
||||
(sendDiscordMessage as jest.Mock).mockRejectedValue(new Error('Unable to send message'));
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledTimes(1);
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
expect.stringContaining('Failed to send discord contact'),
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,6 @@ describe('createBookmarkedSearch', () => {
|
||||
let mockPg: any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockPg = {
|
||||
one: jest.fn(),
|
||||
};
|
||||
@@ -16,13 +15,12 @@ describe('createBookmarkedSearch', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('insert a bookmarked search into the database', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should insert a bookmarked search into the database', async () => {
|
||||
const mockProps = {
|
||||
search_filters: 'mock_search_filters',
|
||||
location: 'mock_location',
|
||||
@@ -30,9 +28,14 @@ describe('createBookmarkedSearch', () => {
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockInserted = "mockInsertedReturn";
|
||||
|
||||
await createBookmarkedSearch(mockProps, mockAuth, mockReq)
|
||||
expect(mockPg.one).toBeCalledTimes(1)
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockInserted);
|
||||
|
||||
const result = await createBookmarkedSearch(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result).toBe(mockInserted);
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toHaveBeenCalledWith(
|
||||
expect.stringContaining('INSERT INTO bookmarked_searches'),
|
||||
[
|
||||
|
||||
@@ -15,32 +15,26 @@ import * as supabaseNotifications from "shared/supabase/notifications";
|
||||
import * as emailHelpers from "email/functions/helpers";
|
||||
import * as websocketHelpers from "shared/websockets/helpers";
|
||||
import { convertComment } from "common/supabase/comment";
|
||||
import { richTextToString } from "common/util/parse";
|
||||
|
||||
describe('createComment', () => {
|
||||
let mockPg: any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockPg = {
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
(supabaseNotifications.insertNotificationToSupabase as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
(emailHelpers.sendNewEndorsementEmail as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
(convertComment as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a comment with information provided', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully create a comment', async () => {
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
@@ -74,12 +68,17 @@ describe('createComment', () => {
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockComment = {id: 12};
|
||||
const mockNotificationDestination = {} as any;
|
||||
const mockNotificationDestination = {
|
||||
sendToBrowser: true,
|
||||
sendToMobile: false,
|
||||
sendToEmail: true
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
const mockConvertCommentReturn = 'mockConverComment';
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator)
|
||||
@@ -90,24 +89,51 @@ describe('createComment', () => {
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockComment);
|
||||
(notificationPrefs.getNotificationDestinationsForUser as jest.Mock)
|
||||
.mockReturnValue(mockNotificationDestination);
|
||||
(convertComment as jest.Mock).mockReturnValue(mockConvertCommentReturn);
|
||||
|
||||
const results = await createComment(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(results.status).toBe('success');
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(2);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockUserId.userId);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(sharedUtils.getUser).toHaveBeenNthCalledWith(1, mockAuth.uid);
|
||||
expect(sharedUtils.getUser).toHaveBeenNthCalledWith(2, mockUserId.userId);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledTimes(2);
|
||||
expect(sharedUtils.getPrivateUser).toHaveBeenNthCalledWith(1, mockProps.userId);
|
||||
expect(sharedUtils.getPrivateUser).toHaveBeenNthCalledWith(2, mockOnUser.id);
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
expect.stringContaining('insert into profile_comments'),
|
||||
expect.arrayContaining([mockCreator.id])
|
||||
[
|
||||
mockCreator.id,
|
||||
mockCreator.name,
|
||||
mockCreator.username,
|
||||
mockCreator.avatarUrl,
|
||||
mockProps.userId,
|
||||
mockProps.content,
|
||||
mockProps.replyToCommentId
|
||||
]
|
||||
);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledTimes(1)
|
||||
|
||||
expect(notificationPrefs.getNotificationDestinationsForUser).toBeCalledTimes(1);
|
||||
expect(notificationPrefs.getNotificationDestinationsForUser).toBeCalledWith(mockOnUser, 'new_endorsement');
|
||||
expect(supabaseNotifications.insertNotificationToSupabase).toBeCalledTimes(1);
|
||||
expect(supabaseNotifications.insertNotificationToSupabase).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
expect.any(Object)
|
||||
);
|
||||
expect(emailHelpers.sendNewEndorsementEmail).toBeCalledTimes(1);
|
||||
expect(emailHelpers.sendNewEndorsementEmail).toBeCalledWith(
|
||||
mockOnUser,
|
||||
mockCreator,
|
||||
mockOnUser,
|
||||
richTextToString(mockProps.content)
|
||||
);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledTimes(1);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledWith(mockConvertCommentReturn);
|
||||
});
|
||||
});
|
||||
|
||||
it('throw an error if there is no user matching the userId', async () => {
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if there is no user matching the userId', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -147,14 +173,16 @@ describe('createComment', () => {
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator)
|
||||
.mockResolvedValueOnce(null);
|
||||
.mockResolvedValueOnce(false);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserId);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('User not found');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('User not found');
|
||||
});
|
||||
|
||||
it('throw an error if there is no account associated with the authId', async () => {
|
||||
it('throw if there is no account associated with the authId', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -188,10 +216,12 @@ describe('createComment', () => {
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(null);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('Your account was not found');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found');
|
||||
});
|
||||
|
||||
it('throw an error if the account is banned from posting', async () => {
|
||||
it('throw if the account is banned from posting', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -232,10 +262,12 @@ describe('createComment', () => {
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('You are banned');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('You are banned');
|
||||
});
|
||||
|
||||
it('throw an error if the other user is not found', async () => {
|
||||
it('throw if the other user is not found', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -278,10 +310,12 @@ describe('createComment', () => {
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('Other user not found');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('Other user not found');
|
||||
});
|
||||
|
||||
it('throw an error if the user has blocked you', async () => {
|
||||
it('throw if the user has blocked you', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -324,10 +358,12 @@ describe('createComment', () => {
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserId);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('User has blocked you');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('User has blocked you');
|
||||
});
|
||||
|
||||
it('throw an error if the comment is too long', async () => {
|
||||
it('throw if the comment is too long', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
@@ -369,9 +405,10 @@ describe('createComment', () => {
|
||||
.mockResolvedValueOnce(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserId);
|
||||
console.log(JSON.stringify(mockContent.content).length);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('Comment is too long');
|
||||
expect(createComment( mockProps, mockAuth, mockReq ))
|
||||
.rejects
|
||||
.toThrowError('Comment is too long');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,12 +18,12 @@ describe('createCompatibilityQuestion', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
describe('should', () => {
|
||||
it('successfully create compatibility questions', async () => {
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully create compatibility questions', async () => {
|
||||
const mockQuestion = {} as any;
|
||||
const mockOptions = {} as any;
|
||||
const mockProps = {options:mockOptions, question:mockQuestion};
|
||||
@@ -41,31 +41,45 @@ describe('createCompatibilityQuestion', () => {
|
||||
multiple_choice_options: {"first_choice":"first_answer"},
|
||||
question: "mockQuestion"
|
||||
};
|
||||
|
||||
(shareUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(mockData);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data:mockData, error: null});
|
||||
|
||||
const results = await createCompatibilityQuestion(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(results.question).toEqual(mockData);
|
||||
|
||||
expect(shareUtils.getUser).toBeCalledTimes(1);
|
||||
expect(shareUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
'compatibility_prompts',
|
||||
{
|
||||
creator_id: mockCreator.id,
|
||||
question: mockQuestion,
|
||||
answer_type: 'compatibility_multiple_choice',
|
||||
multiple_choice_options: mockOptions
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error if the account does not exist', async () => {
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('throws if the account does not exist', async () => {
|
||||
const mockQuestion = {} as any;
|
||||
const mockOptions = {} as any;
|
||||
const mockProps = {options:mockOptions, question:mockQuestion};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
(shareUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
(shareUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(createCompatibilityQuestion(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found')
|
||||
.toThrowError('Your account was not found');
|
||||
|
||||
});
|
||||
|
||||
it('throws an error if unable to create the question', async () => {
|
||||
it('throws if unable to create the question', async () => {
|
||||
const mockQuestion = {} as any;
|
||||
const mockOptions = {} as any;
|
||||
const mockProps = {options:mockOptions, question:mockQuestion};
|
||||
@@ -74,23 +88,13 @@ describe('createCompatibilityQuestion', () => {
|
||||
const mockCreator = {
|
||||
id: '123',
|
||||
};
|
||||
const mockData = {
|
||||
answer_type: "mockAnswerType",
|
||||
category: "mockCategory",
|
||||
created_time: "mockCreatedTime",
|
||||
id: 1,
|
||||
importance_score: 1,
|
||||
multiple_choice_options: {"first_choice":"first_answer"},
|
||||
question: "mockQuestion"
|
||||
};
|
||||
|
||||
(shareUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(mockData);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data:null, error: Error});
|
||||
|
||||
expect(createCompatibilityQuestion(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Error creating question')
|
||||
|
||||
.toThrowError('Error creating question');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,25 +8,23 @@ import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseNotifications from "shared/supabase/notifications";
|
||||
import { Notification } from "common/notifications";
|
||||
|
||||
type MockNotificationUser = Pick<Notification, 'userId'>;
|
||||
|
||||
describe('createNotifications', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
const mockPg = {
|
||||
mockPg = {
|
||||
many: jest.fn().mockReturnValue(null)
|
||||
} as any;
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('sucessfully create a notification', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should sucessfully create a notification', async () => {
|
||||
const mockUsers = [
|
||||
{
|
||||
created_time: "mockCreatedTime",
|
||||
@@ -39,60 +37,89 @@ describe('createNotifications', () => {
|
||||
];
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
} as Notification;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockUsers, error:null});
|
||||
(supabaseNotifications.insertNotificationToSupabase as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
jest.spyOn(createNotificationModules, 'createNotification');
|
||||
|
||||
const results = await createNotificationModules.createNotifications(mockNotification);
|
||||
|
||||
const results = await createNotificationModules.createNotifications(mockNotification as Notification);
|
||||
expect(results?.success).toBeTruthy;
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(mockPg.many).toBeCalledTimes(1);
|
||||
expect(mockPg.many).toBeCalledWith('select * from users');
|
||||
expect(createNotificationModules.createNotification).toBeCalledTimes(1);
|
||||
expect(createNotificationModules.createNotification).toBeCalledWith(
|
||||
mockUsers[0],
|
||||
mockNotification,
|
||||
expect.any(Object)
|
||||
);
|
||||
expect(supabaseNotifications.insertNotificationToSupabase).toBeCalledTimes(1);
|
||||
expect(supabaseNotifications.insertNotificationToSupabase).toBeCalledWith(
|
||||
mockNotification,
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error if its unable to fetch users', async () => {
|
||||
const mockUsers = [
|
||||
{
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData": "mockDataJson"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_user_vector: "mockNUV",
|
||||
username: "mockUsername"
|
||||
},
|
||||
];
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if its unable to fetch users', async () => {
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
} as Notification;
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockUsers, error:Error});
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: null, error:Error});
|
||||
|
||||
await createNotificationModules.createNotifications(mockNotification as Notification)
|
||||
expect(errorSpy).toHaveBeenCalledWith('Error fetching users', expect.objectContaining({name: 'Error'}))
|
||||
await createNotificationModules.createNotifications(mockNotification);
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
'Error fetching users',
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error if there are no users', async () => {
|
||||
const mockUsers = [
|
||||
{
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData": "mockDataJson"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_user_vector: "mockNUV",
|
||||
username: "mockUsername"
|
||||
},
|
||||
];
|
||||
it('should throw if there are no users', async () => {
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
} as Notification;
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: null, error:null});
|
||||
|
||||
await createNotificationModules.createNotifications(mockNotification as Notification)
|
||||
expect(errorSpy).toHaveBeenCalledWith('No users found')
|
||||
await createNotificationModules.createNotifications(mockNotification);
|
||||
expect(errorSpy).toBeCalledWith('No users found');
|
||||
});
|
||||
|
||||
it('should throw if unable to create notification', async () => {
|
||||
const mockUsers = [
|
||||
{
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData": "mockDataJson"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_user_vector: "mockNUV",
|
||||
username: "mockUsername"
|
||||
},
|
||||
];
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as Notification;
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockUsers, error:null});
|
||||
jest.spyOn(createNotificationModules, 'createNotification').mockRejectedValue(new Error('Creation failure'));
|
||||
|
||||
await createNotificationModules.createNotifications(mockNotification);
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
'Failed to create notification',
|
||||
expect.objectContaining({name: 'Error'}),
|
||||
mockUsers[0]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -23,13 +23,12 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a private user message channel (currentChannel)', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully create a private user message channel (currentChannel)', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
@@ -55,29 +54,27 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockResolvedValue(mockCurrentChannel);
|
||||
(privateMessageModules.addUsersToPrivateMessageChannel as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(utilArrayModules.filterDefined as jest.Mock).mockReturnValue(mockPrivateUsers);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockCurrentChannel);
|
||||
|
||||
const results = await createPrivateUserMessageChannel(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.status).toBe('success');
|
||||
expect(results.channelId).toBe(444);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledTimes(2);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[0]);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[1]);
|
||||
expect(results.status).toBe('success');
|
||||
expect(results.channelId).toBe(444)
|
||||
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select channel_id from private_user_message_channel_members'),
|
||||
[mockUserIds]
|
||||
);
|
||||
});
|
||||
|
||||
it('successfully create a private user message channel (channel)', async () => {
|
||||
it('should successfully create a private user message channel (channel)', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
@@ -103,45 +100,54 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
(mockPg.one as jest.Mock)
|
||||
.mockResolvedValue(mockChannel);
|
||||
(privateMessageModules.addUsersToPrivateMessageChannel as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(utilArrayModules.filterDefined as jest.Mock).mockReturnValue(mockPrivateUsers);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockChannel);
|
||||
|
||||
const results = await createPrivateUserMessageChannel(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.status).toBe('success');
|
||||
expect(results.channelId).toBe(333);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledTimes(2);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[0]);
|
||||
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[1]);
|
||||
expect(results.status).toBe('success');
|
||||
expect(results.channelId).toBe(333)
|
||||
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
expect.stringContaining('insert into private_user_message_channels default values returning id')
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('insert into private_user_message_channel_members (channel_id, user_id, role, status)'),
|
||||
[mockChannel.id, mockAuth.uid]
|
||||
);
|
||||
expect(privateMessageModules.addUsersToPrivateMessageChannel).toBeCalledTimes(1);
|
||||
expect(privateMessageModules.addUsersToPrivateMessageChannel).toBeCalledWith(
|
||||
[mockUserIds[0]],
|
||||
mockChannel.id,
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
|
||||
it('throw an error if the user account doesnt exist', async () => {
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the user account doesnt exist', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(createPrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found');
|
||||
});
|
||||
|
||||
it('throw an error if the authId is banned from posting', async () => {
|
||||
it('should throw if the authId is banned from posting', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
@@ -151,21 +157,17 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
isBannedFromPosting: true
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
|
||||
expect(createPrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('You are banned');
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
});
|
||||
|
||||
it('throw an error if the array lengths dont match (privateUsers, userIds)', async () => {
|
||||
it('should throw if the array lengths dont match (privateUsers, userIds)', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['123'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
@@ -181,8 +183,6 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
|
||||
@@ -191,11 +191,10 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
.toThrowError(`Private user ${mockAuth.uid} not found`);
|
||||
});
|
||||
|
||||
it('throw an error if there is a blocked user in the userId list', async () => {
|
||||
it('should throw if there is a blocked user in the userId list', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['321'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
@@ -216,8 +215,6 @@ describe('createPrivateUserMessageChannel', () => {
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('createPrivateUserMessage', () => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
describe('when given valid input', () => {
|
||||
it('successfully create a private user message', async () => {
|
||||
const mockBody = {
|
||||
content: {"": "x".repeat((MAX_COMMENT_JSON_LENGTH-8))},
|
||||
@@ -36,10 +36,12 @@ describe('createPrivateUserMessage', () => {
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(helpersPrivateMessagesModules.createPrivateUserMessageMain as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
await createPrivateUserMessage(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(helpersPrivateMessagesModules.createPrivateUserMessageMain).toBeCalledTimes(1);
|
||||
expect(helpersPrivateMessagesModules.createPrivateUserMessageMain).toBeCalledWith(
|
||||
mockCreator,
|
||||
mockBody.channelId,
|
||||
@@ -48,8 +50,9 @@ describe('createPrivateUserMessage', () => {
|
||||
'private'
|
||||
);
|
||||
});
|
||||
|
||||
it('throw an error if the content is too long', async () => {
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the content is too long', async () => {
|
||||
const mockBody = {
|
||||
content: {"": "x".repeat((MAX_COMMENT_JSON_LENGTH))},
|
||||
channelId: 123
|
||||
@@ -62,7 +65,7 @@ describe('createPrivateUserMessage', () => {
|
||||
.toThrowError(`Message JSON should be less than ${MAX_COMMENT_JSON_LENGTH}`);
|
||||
});
|
||||
|
||||
it('throw an error if the user does not exist', async () => {
|
||||
it('should throw if the user does not exist', async () => {
|
||||
const mockBody = {
|
||||
content: {"mockJson": "mockJsonContent"},
|
||||
channelId: 123
|
||||
@@ -70,14 +73,14 @@ describe('createPrivateUserMessage', () => {
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(createPrivateUserMessage(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`Your account was not found`);
|
||||
});
|
||||
|
||||
it('throw an error if the user does not exist', async () => {
|
||||
it('should throw if the user does not exist', async () => {
|
||||
const mockBody = {
|
||||
content: {"mockJson": "mockJsonContent"},
|
||||
channelId: 123
|
||||
|
||||
@@ -6,10 +6,7 @@ jest.mock('shared/supabase/utils');
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/analytics');
|
||||
jest.mock('common/discord/core');
|
||||
jest.mock('common/util/time', () => {
|
||||
const actual = jest.requireActual('common/util/time');
|
||||
return{ ...actual, sleep: () => Promise.resolve()}
|
||||
});
|
||||
jest.mock('common/util/time');
|
||||
|
||||
import { createProfile } from "api/create-profile";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
@@ -24,25 +21,22 @@ import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('createProfile', () => {
|
||||
let mockPg = {} as any;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn().mockReturnValue(null),
|
||||
oneOrNone: jest.fn(),
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a profile', async () => {
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully create a profile', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
@@ -62,29 +56,41 @@ describe('createProfile', () => {
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
createdTime: Date.now(),
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: false, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1)
|
||||
expect(tryCatch).toBeCalledTimes(2);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select id from profiles where user_id = $1'),
|
||||
[mockAuth.uid]
|
||||
);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockBody);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(supabaseUsers.updateUser).toBeCalledTimes(1);
|
||||
expect(supabaseUsers.updateUser).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{avatarUrl: mockBody.pinned_url}
|
||||
);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
'profiles',
|
||||
expect.objectContaining({user_id: mockAuth.uid})
|
||||
);
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockResolvedValue(null);
|
||||
(sendDiscordMessage as jest.Mock)
|
||||
.mockResolvedValueOnce(null)
|
||||
.mockResolvedValueOnce(null);
|
||||
(mockPg.one as jest.Mock).mockReturnValue(mockNProfiles);
|
||||
|
||||
await results.continue();
|
||||
@@ -102,7 +108,146 @@ describe('createProfile', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('successfully create milestone profile', async () => {
|
||||
it('should successfully create milestone profile', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockNProfiles = 15
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: false, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
|
||||
(mockPg.one as jest.Mock).mockReturnValue(mockNProfiles);
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
expect.stringContaining('SELECT count(*) FROM profiles'),
|
||||
[],
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(sendDiscordMessage).toBeCalledTimes(2);
|
||||
expect(sendDiscordMessage).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining(String(mockNProfiles)),
|
||||
'general'
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if it failed to track create profile', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: false, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockRejectedValue(new Error('Track error'));
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
'Failed to track create profile',
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if it failed to send discord new profile', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sendDiscordMessage as jest.Mock).mockRejectedValue(new Error('Sending error'));
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
'Failed to send discord new profile',
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if it failed to send discord user milestone', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
@@ -129,47 +274,34 @@ describe('createProfile', () => {
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1)
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockBody);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockResolvedValue(null);
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sendDiscordMessage as jest.Mock)
|
||||
.mockResolvedValueOnce(null)
|
||||
.mockResolvedValueOnce(null);
|
||||
.mockRejectedValueOnce(new Error('Discord error'));
|
||||
(mockPg.one as jest.Mock).mockReturnValue(mockNProfiles);
|
||||
|
||||
await results.continue();
|
||||
|
||||
expect(sharedAnalytics.track).toBeCalledTimes(1);
|
||||
expect(sharedAnalytics.track).toBeCalledWith(
|
||||
mockAuth.uid,
|
||||
'create profile',
|
||||
{username: mockUser.username}
|
||||
);
|
||||
expect(sendDiscordMessage).toBeCalledTimes(2);
|
||||
expect(sendDiscordMessage).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining(mockUser.name && mockUser.username),
|
||||
'members'
|
||||
);
|
||||
expect(sendDiscordMessage).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining(String(mockNProfiles)),
|
||||
'general'
|
||||
);
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
'Failed to send discord user milestone',
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error if it failed to track create profile', async () => {
|
||||
it('should throw if the user already exists', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
@@ -183,183 +315,15 @@ describe('createProfile', () => {
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1)
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockBody);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockRejectedValue(null);
|
||||
|
||||
await results.continue();
|
||||
expect(errorSpy).toBeCalledWith('Failed to track create profile', null)
|
||||
});
|
||||
|
||||
it('throws an error if it failed to send discord new profile', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1)
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockBody);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockResolvedValue(null);
|
||||
(sendDiscordMessage as jest.Mock).mockRejectedValue(null);
|
||||
|
||||
await results.continue();
|
||||
expect(sharedAnalytics.track).toBeCalledTimes(1);
|
||||
expect(sharedAnalytics.track).toBeCalledWith(
|
||||
mockAuth.uid,
|
||||
'create profile',
|
||||
{username: mockUser.username}
|
||||
);
|
||||
expect(errorSpy).toBeCalledWith('Failed to send discord new profile', null);
|
||||
});
|
||||
|
||||
it('throws an error if it failed to send discord user milestone', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockNProfiles = 15
|
||||
const mockData = {
|
||||
age: 30,
|
||||
city: "mockCity"
|
||||
};
|
||||
const mockUser = {
|
||||
createdTime: Date.now() - 2 * 60 * 60 * 1000, //2 hours ago
|
||||
name: "mockName",
|
||||
username: "mockUserName"
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.result).toEqual(mockData);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1)
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockBody);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
|
||||
const errorSpy = jest.spyOn(console , 'error').mockImplementation(() => {});
|
||||
|
||||
(sharedAnalytics.track as jest.Mock).mockResolvedValue(null);
|
||||
(sendDiscordMessage as jest.Mock)
|
||||
.mockResolvedValueOnce(null)
|
||||
.mockRejectedValueOnce(null);
|
||||
(mockPg.one as jest.Mock).mockReturnValue(mockNProfiles);
|
||||
|
||||
await results.continue();
|
||||
expect(sharedAnalytics.track).toBeCalledTimes(1);
|
||||
expect(sharedAnalytics.track).toBeCalledWith(
|
||||
mockAuth.uid,
|
||||
'create profile',
|
||||
{username: mockUser.username}
|
||||
);
|
||||
expect(sendDiscordMessage).toBeCalledTimes(2);
|
||||
expect(sendDiscordMessage).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining(mockUser.name && mockUser.username),
|
||||
'members'
|
||||
);
|
||||
expect(sendDiscordMessage).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining(String(mockNProfiles)),
|
||||
'general'
|
||||
);
|
||||
expect(errorSpy).toBeCalledWith('Failed to send discord user milestone', null);
|
||||
});
|
||||
|
||||
it('throws an error if the profile already exists', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
looking_for_matches: true,
|
||||
photo_urls: ["mockPhotoUrl1"],
|
||||
pinned_url: "mockPinnedUrl",
|
||||
pref_gender: ["mockPrefGender"],
|
||||
pref_relation_styles: ["mockPrefRelationStyles"],
|
||||
visibility: 'public' as "public" | "member",
|
||||
wants_kids_strength: 2,
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExistingUser = {id: "mockExistingUserId"};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: mockExistingUser, error: null});
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: true, error: null});
|
||||
|
||||
await expect(createProfile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('User already exists');
|
||||
});
|
||||
|
||||
it('throws an error if the user already exists', async () => {
|
||||
it('should throw if unable to find the account', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
@@ -375,16 +339,14 @@ describe('createProfile', () => {
|
||||
const mockReq = {} as any;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
await expect(createProfile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found');
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
});
|
||||
|
||||
it('throw an error if anything unexpected happens when creating the user', async () => {
|
||||
it('should throw if anything unexpected happens when creating the user', async () => {
|
||||
const mockBody = {
|
||||
city: "mockCity",
|
||||
gender: "mockGender",
|
||||
@@ -406,15 +368,11 @@ describe('createProfile', () => {
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(supabaseUsers.updateUser as jest.Mock).mockReturnValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: Error});
|
||||
|
||||
await expect(createProfile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Error creating user');
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -507,7 +507,7 @@ describe('createUser', () => {
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw an error if the user already exists', async () => {
|
||||
it('should throw if the user already exists', async () => {
|
||||
const mockProps = {
|
||||
deviceToken: "mockDeviceToken",
|
||||
adminToken: "mockAdminToken"
|
||||
@@ -556,7 +556,7 @@ describe('createUser', () => {
|
||||
.toThrowError('User already exists');
|
||||
});
|
||||
|
||||
it('should throw an error if the username is already taken', async () => {
|
||||
it('should throw if the username is already taken', async () => {
|
||||
const mockProps = {
|
||||
deviceToken: "mockDeviceToken",
|
||||
adminToken: "mockAdminToken"
|
||||
@@ -606,7 +606,7 @@ describe('createUser', () => {
|
||||
.toThrowError('Username already taken');
|
||||
});
|
||||
|
||||
it('should throw an error if failed to track create profile', async () => {
|
||||
it('should throw if failed to track create profile', async () => {
|
||||
const mockProps = {
|
||||
deviceToken: "mockDeviceToken",
|
||||
adminToken: "mockAdminToken"
|
||||
@@ -679,7 +679,7 @@ describe('createUser', () => {
|
||||
expect(errorSpy).toHaveBeenCalledWith('Failed to track create profile', expect.any(Error));
|
||||
});
|
||||
|
||||
it('should throw an error if failed to send a welcome email', async () => {
|
||||
it('should throw if failed to send a welcome email', async () => {
|
||||
Object.defineProperty(hostingConstants, 'IS_LOCAL', {
|
||||
value: false,
|
||||
writable: true
|
||||
@@ -757,7 +757,7 @@ describe('createUser', () => {
|
||||
expect(errorSpy).toBeCalledWith('Failed to sendWelcomeEmail', expect.any(Error));
|
||||
});
|
||||
|
||||
it('should throw an error if failed to set last time online', async () => {
|
||||
it('should throw if failed to set last time online', async () => {
|
||||
const mockProps = {
|
||||
deviceToken: "mockDeviceToken",
|
||||
adminToken: "mockAdminToken"
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('createVote', () => {
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('successfully creates a vote', async () => {
|
||||
it('should successfully creates a vote', async () => {
|
||||
const mockProps = {
|
||||
title: 'mockTitle',
|
||||
description: {'mockDescription': 'mockDescriptionValue'},
|
||||
@@ -61,7 +61,7 @@ describe('createVote', () => {
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw an error if the account was not found', async () => {
|
||||
it('should throw if the account was not found', async () => {
|
||||
const mockProps = {
|
||||
title: 'mockTitle',
|
||||
description: {'mockDescription': 'mockDescriptionValue'},
|
||||
@@ -77,7 +77,7 @@ describe('createVote', () => {
|
||||
.toThrow('Your account was not found');
|
||||
});
|
||||
|
||||
it('should throw an error if unable to create a question', async () => {
|
||||
it('should throw if unable to create a question', async () => {
|
||||
const mockProps = {
|
||||
title: 'mockTitle',
|
||||
description: {'mockDescription': 'mockDescriptionValue'},
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('deleteBookmarkedSearch', () => {
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('successfully deletes a bookmarked search', async () => {
|
||||
it('should successfully deletes a bookmarked search', async () => {
|
||||
const mockProps = {
|
||||
id: 123
|
||||
};
|
||||
@@ -28,6 +28,7 @@ describe('deleteBookmarkedSearch', () => {
|
||||
const mockReq = {} as any;
|
||||
|
||||
const result = await deleteBookmarkedSearch(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result).toStrictEqual({});
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('deleteCompatibilityAnswers', () => {
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw an error if the user is not the answers author', async () => {
|
||||
it('should throw if the user is not the answers author', async () => {
|
||||
const mockProps = {
|
||||
id: 123
|
||||
};
|
||||
|
||||
@@ -22,10 +22,10 @@ describe('deleteMe', () => {
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should delete the user account from supabase and firebase', async () => {
|
||||
const mockUser = {
|
||||
@@ -72,13 +72,11 @@ describe('deleteMe', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockRef = {} as any;
|
||||
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
expect(deleteMe(mockRef, mockAuth, mockRef))
|
||||
.rejects
|
||||
.toThrow('Your account was not found');
|
||||
|
||||
});
|
||||
|
||||
it('should throw an error if there is no userId', async () => {
|
||||
@@ -88,14 +86,11 @@ describe('deleteMe', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockRef = {} as any;
|
||||
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
|
||||
|
||||
expect(deleteMe(mockRef, mockAuth, mockRef))
|
||||
.rejects
|
||||
.toThrow('Invalid user ID');
|
||||
|
||||
});
|
||||
|
||||
it('should throw if unable to remove user from firebase auth', async () => {
|
||||
|
||||
@@ -21,6 +21,7 @@ describe('deleteMessage', () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should delete a message', async () => {
|
||||
const mockMessageId = {
|
||||
|
||||
@@ -72,6 +72,7 @@ describe('editMessage', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if there is an issue with the message', async () => {
|
||||
const mockProps = {
|
||||
|
||||
@@ -16,6 +16,7 @@ describe('getCompatibilityQuestions', () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should get compatibility questions', async () => {
|
||||
const mockProps = {} as any;
|
||||
|
||||
@@ -41,6 +41,7 @@ describe('getCurrentPrivateUser', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if unable to get users private data', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
|
||||
@@ -43,6 +43,7 @@ describe('getOptions', () => {
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the table is invalid', async () => {
|
||||
const mockTable = "causes";
|
||||
@@ -60,9 +61,6 @@ describe('getOptions', () => {
|
||||
const mockTable = "causes";
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = [
|
||||
{ name: "mockName" },
|
||||
];
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(true);
|
||||
(mockPg.manyOrNone as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
@@ -186,6 +186,7 @@ describe('getChannelMessagesEndpoint', () => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if unable to get messages', async () => {
|
||||
const mockProps = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as profilesModule from "api/get-profiles";
|
||||
import { Profile } from "common/profiles/profile";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as sqlBuilder from "shared/supabase/sql-builder";
|
||||
|
||||
describe('getProfiles', () => {
|
||||
beforeEach(() => {
|
||||
@@ -11,8 +12,8 @@ describe('getProfiles', () => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should fetch the user profiles', () => {
|
||||
it('successfully', async ()=> {
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully return profile information and count', async ()=> {
|
||||
const mockProfiles = [
|
||||
{
|
||||
diet: ['Jonathon Hammon'],
|
||||
@@ -27,19 +28,15 @@ describe('getProfiles', () => {
|
||||
has_kids: 2,
|
||||
}
|
||||
] as Profile [];
|
||||
|
||||
jest.spyOn(profilesModule, 'loadProfiles').mockResolvedValue({profiles: mockProfiles, count: 3});
|
||||
|
||||
const props = {
|
||||
limit: 2,
|
||||
orderBy: "last_online_time" as const,
|
||||
};
|
||||
const mockReq = {} as any;
|
||||
const results = await profilesModule.getProfiles(props, mockReq, mockReq);
|
||||
|
||||
if('continue' in results) {
|
||||
throw new Error('Expected direct response')
|
||||
};
|
||||
jest.spyOn(profilesModule, 'loadProfiles').mockResolvedValue({profiles: mockProfiles, count: 3});
|
||||
|
||||
const results: any = await profilesModule.getProfiles(props, mockReq, mockReq);
|
||||
|
||||
expect(results.status).toEqual('success');
|
||||
expect(results.profiles).toEqual(mockProfiles);
|
||||
@@ -47,8 +44,10 @@ describe('getProfiles', () => {
|
||||
expect(profilesModule.loadProfiles).toHaveBeenCalledWith(props);
|
||||
expect(profilesModule.loadProfiles).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('unsuccessfully', async () => {
|
||||
describe('when an error occurs', () => {
|
||||
it('should not return profile information', async () => {
|
||||
jest.spyOn(profilesModule, 'loadProfiles').mockRejectedValue(null);
|
||||
|
||||
const props = {
|
||||
@@ -56,278 +55,274 @@ describe('getProfiles', () => {
|
||||
orderBy: "last_online_time" as const,
|
||||
};
|
||||
const mockReq = {} as any;
|
||||
const results = await profilesModule.getProfiles(props, mockReq, mockReq);
|
||||
|
||||
if('continue' in results) {
|
||||
throw new Error('Expected direct response')
|
||||
};
|
||||
const results: any = await profilesModule.getProfiles(props, mockReq, mockReq);
|
||||
|
||||
expect(results.status).toEqual('fail');
|
||||
expect(results.profiles).toEqual([]);
|
||||
expect(profilesModule.loadProfiles).toHaveBeenCalledWith(props);
|
||||
expect(profilesModule.loadProfiles).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadProfiles', () => {
|
||||
let mockPg: any;
|
||||
|
||||
describe('should call pg.map with an SQL query', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockPg = {
|
||||
map: jest.fn().mockResolvedValue([]),
|
||||
one: jest.fn().mockResolvedValue(1),
|
||||
};
|
||||
|
||||
jest.spyOn(supabaseInit, 'createSupabaseDirectClient')
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('successfully', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
limit: 10,
|
||||
name: 'John',
|
||||
is_smoker: true,
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain('select');
|
||||
expect(query).toContain('from profiles');
|
||||
expect(query).toContain('where');
|
||||
expect(query).toContain('limit 10');
|
||||
expect(query).toContain(`John`);
|
||||
expect(query).toContain(`is_smoker`);
|
||||
expect(query).not.toContain(`gender`);
|
||||
expect(query).not.toContain(`education_level`);
|
||||
expect(query).not.toContain(`pref_gender`);
|
||||
expect(query).not.toContain(`age`);
|
||||
expect(query).not.toContain(`drinks_per_month`);
|
||||
expect(query).not.toContain(`pref_relation_styles`);
|
||||
expect(query).not.toContain(`pref_romantic_styles`);
|
||||
expect(query).not.toContain(`diet`);
|
||||
expect(query).not.toContain(`political_beliefs`);
|
||||
expect(query).not.toContain(`religion`);
|
||||
expect(query).not.toContain(`has_kids`);
|
||||
});
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockPg = {
|
||||
map: jest.fn(),
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
it('that contains a gender filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
genders: ['Electrical_gender'],
|
||||
jest.spyOn(supabaseInit, 'createSupabaseDirectClient')
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
describe('should call pg.map with an SQL query', () => {
|
||||
it('successfully', async () => {
|
||||
const mockProps = {
|
||||
limit: 10,
|
||||
name: 'John',
|
||||
is_smoker: true,
|
||||
};
|
||||
|
||||
(mockPg.map as jest.Mock).mockResolvedValue([]);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(1);
|
||||
jest.spyOn(sqlBuilder, 'renderSql');
|
||||
jest.spyOn(sqlBuilder, 'select');
|
||||
jest.spyOn(sqlBuilder, 'from');
|
||||
jest.spyOn(sqlBuilder, 'where');
|
||||
jest.spyOn(sqlBuilder, 'join');
|
||||
|
||||
await profilesModule.loadProfiles(mockProps);
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0];
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain('select');
|
||||
expect(query).toContain('from profiles');
|
||||
expect(query).toContain('where');
|
||||
expect(query).toContain('limit 10');
|
||||
expect(query).toContain(`John`);
|
||||
expect(query).toContain(`is_smoker`);
|
||||
expect(query).not.toContain(`gender`);
|
||||
expect(query).not.toContain(`education_level`);
|
||||
expect(query).not.toContain(`pref_gender`);
|
||||
expect(query).not.toContain(`age`);
|
||||
expect(query).not.toContain(`drinks_per_month`);
|
||||
expect(query).not.toContain(`pref_relation_styles`);
|
||||
expect(query).not.toContain(`pref_romantic_styles`);
|
||||
expect(query).not.toContain(`diet`);
|
||||
expect(query).not.toContain(`political_beliefs`);
|
||||
expect(query).not.toContain(`religion`);
|
||||
expect(query).not.toContain(`has_kids`);
|
||||
expect(sqlBuilder.renderSql).toBeCalledTimes(3);
|
||||
expect(sqlBuilder.select).toBeCalledTimes(3);
|
||||
expect(sqlBuilder.from).toBeCalledTimes(2);
|
||||
expect(sqlBuilder.where).toBeCalledTimes(8);
|
||||
expect(sqlBuilder.join).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('that contains a gender filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
genders: ['Electrical_gender'],
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`gender`);
|
||||
expect(query).toContain(`Electrical_gender`);
|
||||
});
|
||||
|
||||
it('that contains a education level filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
education_levels: ['High School'],
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`education_level`);
|
||||
expect(query).toContain(`High School`);
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`gender`);
|
||||
expect(query).toContain(`Electrical_gender`);
|
||||
});
|
||||
|
||||
it('that contains a education level filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
education_levels: ['High School'],
|
||||
it('that contains a prefer gender filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_gender: ['female'],
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
console.log(query);
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_gender`);
|
||||
expect(query).toContain(`female`);
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`education_level`);
|
||||
expect(query).toContain(`High School`);
|
||||
});
|
||||
|
||||
it('that contains a prefer gender filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_gender: ['female'],
|
||||
it('that contains a minimum age filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_age_min: 20,
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`age`);
|
||||
expect(query).toContain(`>= 20`);
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
console.log(query);
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_gender`);
|
||||
expect(query).toContain(`female`);
|
||||
});
|
||||
it('that contains a maximum age filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_age_max: 40,
|
||||
});
|
||||
|
||||
it('that contains a minimum age filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_age_min: 20,
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`age`);
|
||||
expect(query).toContain(`<= 40`);
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`age`);
|
||||
expect(query).toContain(`>= 20`);
|
||||
});
|
||||
it('that contains a minimum drinks per month filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
drinks_min: 4,
|
||||
});
|
||||
|
||||
it('that contains a maximum age filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_age_max: 40,
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`drinks_per_month`);
|
||||
expect(query).toContain('4');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`age`);
|
||||
expect(query).toContain(`<= 40`);
|
||||
});
|
||||
it('that contains a maximum drinks per month filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
drinks_max: 20,
|
||||
});
|
||||
|
||||
it('that contains a minimum drinks per month filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
drinks_min: 4,
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`drinks_per_month`);
|
||||
expect(query).toContain('20');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`drinks_per_month`);
|
||||
expect(query).toContain('4');
|
||||
});
|
||||
it('that contains a relationship style filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_relation_styles: ['Chill and relaxing'],
|
||||
});
|
||||
|
||||
it('that contains a maximum drinks per month filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
drinks_max: 20,
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_relation_styles`);
|
||||
expect(query).toContain('Chill and relaxing');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`drinks_per_month`);
|
||||
expect(query).toContain('20');
|
||||
});
|
||||
it('that contains a romantic style filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_romantic_styles: ['Sexy'],
|
||||
});
|
||||
|
||||
it('that contains a relationship style filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_relation_styles: ['Chill and relaxing'],
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_romantic_styles`);
|
||||
expect(query).toContain('Sexy');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_relation_styles`);
|
||||
expect(query).toContain('Chill and relaxing');
|
||||
});
|
||||
it('that contains a diet filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
diet: ['Glutton'],
|
||||
});
|
||||
|
||||
it('that contains a romantic style filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
pref_romantic_styles: ['Sexy'],
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`diet`);
|
||||
expect(query).toContain('Glutton');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`pref_romantic_styles`);
|
||||
expect(query).toContain('Sexy');
|
||||
});
|
||||
it('that contains a political beliefs filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
political_beliefs: ['For the people'],
|
||||
});
|
||||
|
||||
it('that contains a diet filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
diet: ['Glutton'],
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`political_beliefs`);
|
||||
expect(query).toContain('For the people');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`diet`);
|
||||
expect(query).toContain('Glutton');
|
||||
});
|
||||
it('that contains a religion filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
religion: ['The blood god'],
|
||||
});
|
||||
|
||||
it('that contains a political beliefs filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
political_beliefs: ['For the people'],
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`religion`);
|
||||
expect(query).toContain('The blood god');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`political_beliefs`);
|
||||
expect(query).toContain('For the people');
|
||||
});
|
||||
it('that contains a has kids filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
has_kids: 3,
|
||||
});
|
||||
|
||||
it('that contains a religion filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
religion: ['The blood god'],
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`has_kids`);
|
||||
expect(query).toContain('> 0');
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`religion`);
|
||||
expect(query).toContain('The blood god');
|
||||
});
|
||||
it('should return profiles from the database', async () => {
|
||||
const mockProfiles = [
|
||||
{
|
||||
diet: ['Jonathon Hammon'],
|
||||
is_smoker: true,
|
||||
has_kids: 0
|
||||
},
|
||||
{
|
||||
diet: ['Joseph Hammon'],
|
||||
is_smoker: false,
|
||||
has_kids: 1
|
||||
},
|
||||
{
|
||||
diet: ['Jolene Hammon'],
|
||||
is_smoker: true,
|
||||
has_kids: 2,
|
||||
}
|
||||
] as Profile [];
|
||||
const props = {} as any;
|
||||
|
||||
it('that contains a has kids filter', async () => {
|
||||
await profilesModule.loadProfiles({
|
||||
has_kids: 3,
|
||||
(mockPg.map as jest.Mock).mockResolvedValue(mockProfiles);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(1);
|
||||
|
||||
const results = await profilesModule.loadProfiles(props);
|
||||
|
||||
expect(results).toEqual({profiles: mockProfiles, count: 1});
|
||||
});
|
||||
|
||||
const [query, values, cb] = mockPg.map.mock.calls[0]
|
||||
|
||||
expect(mockPg.map.mock.calls).toHaveLength(1)
|
||||
expect(query).toContain(`has_kids`);
|
||||
expect(query).toContain('> 0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockPg = {
|
||||
map: jest.fn(),
|
||||
one: jest.fn().mockResolvedValue(1),
|
||||
};
|
||||
|
||||
jest.spyOn(supabaseInit, 'createSupabaseDirectClient')
|
||||
.mockReturnValue(mockPg)
|
||||
|
||||
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('return profiles from the database', async () => {
|
||||
const mockProfiles = [
|
||||
{
|
||||
diet: ['Jonathon Hammon'],
|
||||
is_smoker: true,
|
||||
has_kids: 0
|
||||
},
|
||||
{
|
||||
diet: ['Joseph Hammon'],
|
||||
is_smoker: false,
|
||||
has_kids: 1
|
||||
},
|
||||
{
|
||||
diet: ['Jolene Hammon'],
|
||||
is_smoker: true,
|
||||
has_kids: 2,
|
||||
}
|
||||
] as Profile [];
|
||||
|
||||
mockPg.map.mockResolvedValue(mockProfiles);
|
||||
const props = {} as any;
|
||||
const results = await profilesModule.loadProfiles(props);
|
||||
|
||||
expect(results).toEqual({profiles: mockProfiles, count: 1});
|
||||
});
|
||||
|
||||
it('throw an error if there is no compatability', async () => {
|
||||
describe('when an error occurs', () => {
|
||||
it('throw if there is no compatability', async () => {
|
||||
const props = {
|
||||
orderBy: 'compatibility_score'
|
||||
}
|
||||
|
||||
expect(profilesModule.loadProfiles(props))
|
||||
.rejects
|
||||
.toThrowError('Incompatible with user ID')
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -1,163 +1,90 @@
|
||||
jest.mock("shared/supabase/init");
|
||||
jest.mock("common/supabase/users");
|
||||
jest.mock("common/api/user-types");
|
||||
|
||||
import { getUser } from "api/get-user";
|
||||
import { createSupabaseDirectClient } from "shared/supabase/init";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import { toUserAPIResponse } from "common/api/user-types";
|
||||
import { convertUser } from "common/supabase/users";
|
||||
import { APIError } from "common/api/utils";
|
||||
|
||||
|
||||
jest.spyOn(require("common/supabase/users"), 'convertUser')
|
||||
jest.spyOn(require("common/api/user-types"), 'toUserAPIResponse')
|
||||
|
||||
describe('getUser', () =>{
|
||||
let mockPg: any;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn(),
|
||||
};
|
||||
(createSupabaseDirectClient as jest.Mock).mockReturnValue(mockPg);
|
||||
|
||||
jest.clearAllMocks();
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when fetching by id', () => {
|
||||
it('should fetch user successfully by id', async () => {
|
||||
const mockDbUser = {
|
||||
created_time: '2025-11-11T16:42:05.188Z',
|
||||
data: { link: {}, avatarUrl: "", isBannedFromPosting: false },
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
name_username_vector: "'buckridg':2,4 'franklin':1,3",
|
||||
username: 'Franky_Buck'
|
||||
};
|
||||
const mockConvertedUser = {
|
||||
created_time: new Date(),
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
name_username_vector: "'buckridg':2,4 'franklin':1,3",
|
||||
username: 'Franky_Buck'
|
||||
|
||||
};
|
||||
const mockApiResponse = {
|
||||
created_time: '2025-11-11T16:42:05.188Z',
|
||||
data: { link: {}, avatarUrl: "", isBannedFromPosting: false },
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
username: 'Franky_Buck'
|
||||
};
|
||||
|
||||
mockPg.oneOrNone.mockImplementation((query: string, values: any[], cb: (value: any) => any) => {
|
||||
const result = cb(mockDbUser);
|
||||
return Promise.resolve(result);
|
||||
});
|
||||
|
||||
(convertUser as jest.Mock).mockReturnValue(mockConvertedUser);
|
||||
( toUserAPIResponse as jest.Mock).mockReturnValue(mockApiResponse);
|
||||
|
||||
const result = await getUser({id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP'})
|
||||
|
||||
expect(mockPg.oneOrNone).toHaveBeenCalledWith(
|
||||
expect.stringContaining('where id = $1'),
|
||||
['feUaIfcxVmJZHJOVVfawLTTPgZiP'],
|
||||
expect.any(Function)
|
||||
);
|
||||
|
||||
expect(convertUser).toHaveBeenCalledWith(mockDbUser);
|
||||
expect(toUserAPIResponse).toHaveBeenCalledWith(mockConvertedUser);
|
||||
|
||||
expect(result).toEqual(mockApiResponse);
|
||||
|
||||
});
|
||||
describe('when given valid input', () => {
|
||||
describe('and fetching by id', () => {
|
||||
it('should fetch user successfully by id', async () => {
|
||||
const mockProps = {id: "mockId"};
|
||||
const mockUser = {} as any;
|
||||
|
||||
it('should throw 404 when user is not found by id', async () => {
|
||||
mockPg.oneOrNone.mockImplementation((query: string, values: any[], cb: (value: any) => any) => {
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
|
||||
(convertUser as jest.Mock).mockReturnValue(null)
|
||||
|
||||
try {
|
||||
await getUser({id: '3333'});
|
||||
fail('Should have thrown');
|
||||
} catch (error) {
|
||||
const apiError = error as APIError;
|
||||
expect(apiError.code).toBe(404)
|
||||
expect(apiError.message).toBe('User not found')
|
||||
expect(apiError.details).toBeUndefined()
|
||||
expect(apiError.name).toBe('APIError')
|
||||
}
|
||||
})
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockUser);
|
||||
(toUserAPIResponse as jest.Mock).mockReturnValue('mockApiResponse');
|
||||
|
||||
})
|
||||
const result = await getUser(mockProps);
|
||||
|
||||
describe('when fetching by username', () => {
|
||||
it('should fetch user successfully by username', async () => {
|
||||
const mockDbUser = {
|
||||
created_time: '2025-11-11T16:42:05.188Z',
|
||||
data: { link: {}, avatarUrl: "", isBannedFromPosting: false },
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
name_username_vector: "'buckridg':2,4 'franklin':1,3",
|
||||
username: 'Franky_Buck'
|
||||
};
|
||||
const mockConvertedUser = {
|
||||
created_time: new Date(),
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
name_username_vector: "'buckridg':2,4 'franklin':1,3",
|
||||
username: 'Franky_Buck'
|
||||
|
||||
};
|
||||
const mockApiResponse = {
|
||||
created_time: '2025-11-11T16:42:05.188Z',
|
||||
data: { link: {}, avatarUrl: "", isBannedFromPosting: false },
|
||||
id: 'feUaIfcxVmJZHJOVVfawLTTPgZiP',
|
||||
name: 'Franklin Buckridge',
|
||||
username: 'Franky_Buck'
|
||||
};
|
||||
|
||||
mockPg.oneOrNone.mockImplementation((query: string, values: any[], cb: (value: any) => any) => {
|
||||
const result = cb(mockDbUser);
|
||||
return Promise.resolve(result);
|
||||
expect(result).toBe('mockApiResponse');
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select * from users'),
|
||||
[mockProps.id],
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(toUserAPIResponse).toBeCalledTimes(1);
|
||||
expect(toUserAPIResponse).toBeCalledWith(mockUser);
|
||||
});
|
||||
|
||||
(convertUser as jest.Mock).mockReturnValue(mockConvertedUser);
|
||||
(toUserAPIResponse as jest.Mock).mockReturnValue(mockApiResponse);
|
||||
|
||||
const result = await getUser({username: 'Franky_Buck'})
|
||||
|
||||
expect(mockPg.oneOrNone).toHaveBeenCalledWith(
|
||||
expect.stringContaining('where username = $1'),
|
||||
['Franky_Buck'],
|
||||
expect.any(Function)
|
||||
);
|
||||
|
||||
expect(convertUser).toHaveBeenCalledWith(mockDbUser);
|
||||
expect(toUserAPIResponse).toHaveBeenCalledWith(mockConvertedUser);
|
||||
|
||||
expect(result).toEqual(mockApiResponse);
|
||||
|
||||
});
|
||||
|
||||
it('should throw 404 when user is not found by id', async () => {
|
||||
mockPg.oneOrNone.mockImplementation((query: string, values: any[], cb: (value: any) => any) => {
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
describe('when fetching by username', () => {
|
||||
it('should fetch user successfully by username', async () => {
|
||||
const mockProps = {username: "mockUsername"};
|
||||
const mockUser = {} as any;
|
||||
|
||||
(convertUser as jest.Mock).mockReturnValue(null)
|
||||
|
||||
try {
|
||||
await getUser({username: '3333'});
|
||||
fail('Should have thrown');
|
||||
} catch (error) {
|
||||
const apiError = error as APIError;
|
||||
expect(apiError.code).toBe(404)
|
||||
expect(apiError.message).toBe('User not found')
|
||||
expect(apiError.details).toBeUndefined()
|
||||
expect(apiError.name).toBe('APIError')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockUser);
|
||||
|
||||
await getUser(mockProps)
|
||||
|
||||
expect(mockPg.oneOrNone).toHaveBeenCalledWith(
|
||||
expect.stringContaining('where username = $1'),
|
||||
[mockProps.username],
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs', () => {
|
||||
describe('and fetching by id', () => {
|
||||
it('should throw when user is not found by id', async () => {
|
||||
const mockProps = {id: "mockId"};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(getUser(mockProps))
|
||||
.rejects
|
||||
.toThrow('User not found');
|
||||
});
|
||||
});
|
||||
describe('when fetching by username', () => {
|
||||
it('should throw when user is not found by id', async () => {
|
||||
const mockProps = {username: "mockUsername"};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(getUser(mockProps))
|
||||
.rejects
|
||||
.toThrow('User not found');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -45,12 +45,11 @@ describe('hideComment', () => {
|
||||
user_name: "mockUserName",
|
||||
user_username: "mockUserUsername",
|
||||
};
|
||||
const mockConvertedComment = "mockConvertedCommentValue";
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockComment);
|
||||
jest.spyOn(envConsts, 'isAdminId').mockReturnValue(true);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(convertComment as jest.Mock).mockReturnValue(null);
|
||||
(websocketHelpers.broadcastUpdatedComment as jest.Mock).mockReturnValue(null);
|
||||
(convertComment as jest.Mock).mockReturnValue(mockConvertedComment);
|
||||
|
||||
await hideComment(mockProps, mockAuth, mockReq);
|
||||
|
||||
@@ -64,7 +63,7 @@ describe('hideComment', () => {
|
||||
expect(convertComment).toBeCalledTimes(1);
|
||||
expect(convertComment).toBeCalledWith(mockComment);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledTimes(1);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledWith(null);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledWith(mockConvertedComment);
|
||||
});
|
||||
|
||||
it('should successfully hide the comment if the user is the one who made the comment', async () => {
|
||||
@@ -89,9 +88,6 @@ describe('hideComment', () => {
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockComment);
|
||||
jest.spyOn(envConsts, 'isAdminId').mockReturnValue(false);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(convertComment as jest.Mock).mockReturnValue(null);
|
||||
(websocketHelpers.broadcastUpdatedComment as jest.Mock).mockReturnValue(null);
|
||||
|
||||
await hideComment(mockProps, mockAuth, mockReq);
|
||||
});
|
||||
@@ -118,9 +114,6 @@ describe('hideComment', () => {
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockComment);
|
||||
jest.spyOn(envConsts, 'isAdminId').mockReturnValue(false);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(convertComment as jest.Mock).mockReturnValue(null);
|
||||
(websocketHelpers.broadcastUpdatedComment as jest.Mock).mockReturnValue(null);
|
||||
|
||||
await hideComment(mockProps, mockAuth, mockReq);
|
||||
});
|
||||
@@ -134,7 +127,7 @@ describe('hideComment', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(hideComment(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
@@ -163,9 +156,6 @@ describe('hideComment', () => {
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockComment);
|
||||
jest.spyOn(envConsts, 'isAdminId').mockReturnValue(false);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(convertComment as jest.Mock).mockReturnValue(null);
|
||||
(websocketHelpers.broadcastUpdatedComment as jest.Mock).mockReturnValue(null);
|
||||
|
||||
expect(hideComment(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
|
||||
@@ -29,12 +29,11 @@ describe('leavePrivateUserMessageChannel', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockUser = { name: "mockName" };
|
||||
const mockLeaveChatContent = "mockLeaveChatContentValue";
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(true);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(messageHelpers.leaveChatContent as jest.Mock).mockReturnValue(null);
|
||||
(messageHelpers.insertPrivateMessage as jest.Mock).mockResolvedValue(null);
|
||||
(messageHelpers.leaveChatContent as jest.Mock).mockReturnValue(mockLeaveChatContent);
|
||||
|
||||
const results = await leavePrivateUserMessageChannel(mockProps, mockAuth, mockReq);
|
||||
|
||||
@@ -56,7 +55,7 @@ describe('leavePrivateUserMessageChannel', () => {
|
||||
expect(messageHelpers.leaveChatContent).toBeCalledWith(mockUser.name);
|
||||
expect(messageHelpers.insertPrivateMessage).toBeCalledTimes(1);
|
||||
expect(messageHelpers.insertPrivateMessage).toBeCalledWith(
|
||||
null,
|
||||
mockLeaveChatContent,
|
||||
mockProps.channelId,
|
||||
mockAuth.uid,
|
||||
'system_status',
|
||||
@@ -70,7 +69,7 @@ describe('leavePrivateUserMessageChannel', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(leavePrivateUserMessageChannel(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
|
||||
@@ -41,12 +41,10 @@ describe('likeProfile', () => {
|
||||
target_id: "mockTargetId"
|
||||
};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: false})
|
||||
.mockResolvedValueOnce({data: mockData, error: null});
|
||||
(likeModules.getHasFreeLike as jest.Mock).mockResolvedValue(true);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result: any = await likeProfile(mockProps, mockAuth, mockReq);
|
||||
|
||||
@@ -79,7 +77,6 @@ describe('likeProfile', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: true});
|
||||
|
||||
const result: any = await likeProfile(mockProps, mockAuth, mockReq);
|
||||
@@ -101,7 +98,6 @@ describe('likeProfile', () => {
|
||||
target_id: "mockTargetId"
|
||||
};
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockData, error: null});
|
||||
|
||||
const result: any = await likeProfile(mockProps, mockAuth, mockReq);
|
||||
@@ -130,7 +126,6 @@ describe('likeProfile', () => {
|
||||
target_id: "mockTargetId"
|
||||
};
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: mockData, error: Error});
|
||||
|
||||
@@ -153,7 +148,6 @@ describe('likeProfile', () => {
|
||||
target_id: "mockTargetId"
|
||||
};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: false})
|
||||
.mockResolvedValueOnce({data: mockData, error: null});
|
||||
@@ -179,7 +173,6 @@ describe('likeProfile', () => {
|
||||
target_id: "mockTargetId"
|
||||
};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: false})
|
||||
.mockResolvedValueOnce({data: mockData, error: Error});
|
||||
|
||||
@@ -25,8 +25,6 @@ describe('markAllNotifsRead', () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await markAllNotifsRead(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
|
||||
139
backend/api/tests/unit/react-to-message.unit.test.ts
Normal file
139
backend/api/tests/unit/react-to-message.unit.test.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('api/helpers/private-messages');
|
||||
|
||||
import { reactToMessage } from "api/react-to-message";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as messageHelpers from "api/helpers/private-messages";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('reactToMessage', () => {
|
||||
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 return success', async () => {
|
||||
const mockProps = {
|
||||
messageId: 123,
|
||||
reaction: "mockReaction",
|
||||
toDelete: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockMessage = { channel_id: "mockChannelId"};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockMessage);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(messageHelpers.broadcastPrivateMessages as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await reactToMessage(mockProps, mockAuth, mockReq);
|
||||
const [sql, params] = mockPg.oneOrNone.mock.calls[0]
|
||||
const [sql1, params1] = mockPg.none.mock.calls[0]
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(params).toEqual([mockAuth.uid, mockProps.messageId])
|
||||
expect(sql).toEqual(
|
||||
expect.stringContaining('SELECT *')
|
||||
);
|
||||
expect(sql).toEqual(
|
||||
expect.stringContaining('FROM private_user_message_channel_members m')
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(params1).toEqual([mockProps.reaction, mockAuth.uid, mockProps.messageId])
|
||||
expect(sql1).toEqual(
|
||||
expect.stringContaining('UPDATE private_user_messages')
|
||||
);
|
||||
expect(sql1).toEqual(
|
||||
expect.stringContaining('SET reactions =')
|
||||
);
|
||||
expect(messageHelpers.broadcastPrivateMessages).toBeCalledTimes(1);
|
||||
expect(messageHelpers.broadcastPrivateMessages).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
mockMessage.channel_id,
|
||||
mockAuth.uid
|
||||
);
|
||||
});
|
||||
|
||||
it('should return success when removing a reaction', async () => {
|
||||
const mockProps = {
|
||||
messageId: 123,
|
||||
reaction: "mockReaction",
|
||||
toDelete: true
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockMessage = { channel_id: "mockChannelId"};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockMessage);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(messageHelpers.broadcastPrivateMessages as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await reactToMessage(mockProps, mockAuth, mockReq);
|
||||
const [sql, params] = mockPg.oneOrNone.mock.calls[0]
|
||||
const [sql1, params1] = mockPg.none.mock.calls[0]
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(params1).toEqual([mockProps.reaction, mockProps.messageId, mockAuth.uid])
|
||||
expect(sql1).toEqual(
|
||||
expect.stringContaining('UPDATE private_user_messages')
|
||||
);
|
||||
expect(sql1).toEqual(
|
||||
expect.stringContaining('SET reactions = reactions - $1')
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if user does not have the authorization to react', async () => {
|
||||
const mockProps = {
|
||||
messageId: 123,
|
||||
reaction: "mockReaction",
|
||||
toDelete: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(reactToMessage(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Not authorized to react to this message');
|
||||
});
|
||||
|
||||
it('should return success', async () => {
|
||||
const mockProps = {
|
||||
messageId: 123,
|
||||
reaction: "mockReaction",
|
||||
toDelete: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockMessage = { channel_id: "mockChannelId"};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockMessage);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(messageHelpers.broadcastPrivateMessages as jest.Mock).mockRejectedValue(new Error('Broadcast error'));
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await reactToMessage(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
expect.stringContaining('broadcastPrivateMessages failed'),
|
||||
expect.any(Error)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
75
backend/api/tests/unit/remove-pinned-photo.unit.test.ts
Normal file
75
backend/api/tests/unit/remove-pinned-photo.unit.test.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('common/envs/constants');
|
||||
jest.mock('common/util/try-catch');
|
||||
|
||||
import { removePinnedPhoto } from "api/remove-pinned-photo";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as envConstants from "common/envs/constants";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('removePinnedPhoto', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
none: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return success', async () => {
|
||||
const mockBody = { userId: "mockUserId"};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(envConstants, 'isAdminId').mockReturnValue(true);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({error: null});
|
||||
|
||||
const result: any = await removePinnedPhoto(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(envConstants.isAdminId).toBeCalledTimes(1);
|
||||
expect(envConstants.isAdminId).toBeCalledWith(mockAuth.uid);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('update profiles set pinned_url = null where user_id = $1'),
|
||||
[mockBody.userId]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if user auth is not an admin', async () => {
|
||||
const mockBody = { userId: "mockUserId"};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(envConstants, 'isAdminId').mockReturnValue(false);
|
||||
|
||||
expect(removePinnedPhoto(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Only admins can remove pinned photo');
|
||||
});
|
||||
|
||||
it('should throw if failed to remove the pinned photo', async () => {
|
||||
const mockBody = { userId: "mockUserId"};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(envConstants, 'isAdminId').mockReturnValue(true);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({error: Error});
|
||||
|
||||
expect(removePinnedPhoto(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to remove pinned photo');
|
||||
});
|
||||
});
|
||||
});
|
||||
225
backend/api/tests/unit/report.unit.test.ts
Normal file
225
backend/api/tests/unit/report.unit.test.ts
Normal file
@@ -0,0 +1,225 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/supabase/utils');
|
||||
jest.mock('common/discord/core');
|
||||
|
||||
import { report } from "api/report";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseUtils from "shared/supabase/utils";
|
||||
import { sendDiscordMessage } from "common/discord/core";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('report', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should successfully file a report', async () => {
|
||||
const mockBody = {
|
||||
contentOwnerId: "mockContentOwnerId",
|
||||
contentType: "user" as "user" | "comment" | "contract",
|
||||
contentId: "mockContentId",
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReporter = {
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
};
|
||||
const mockReported = {
|
||||
created_time: "mockCreatedTimeReported",
|
||||
data: {"mockDataReported" : "mockDataValueReported"},
|
||||
id: "mockIdReported",
|
||||
name: "mockNameReported",
|
||||
name_username_vector: "mockNameUsernameVectorReported",
|
||||
username: "mockUsernameReported",
|
||||
};
|
||||
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockBody, error: null});
|
||||
|
||||
const result = await report(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(result.result).toStrictEqual({});
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockReturnValueOnce(null)
|
||||
.mockReturnValueOnce(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: mockReporter, error: null})
|
||||
.mockResolvedValueOnce({data: mockReported, error: null});
|
||||
(sendDiscordMessage as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(2);
|
||||
expect(mockPg.oneOrNone).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining('select * from users where id = $1'),
|
||||
[mockAuth.uid]
|
||||
);
|
||||
expect(mockPg.oneOrNone).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining('select * from users where id = $1'),
|
||||
[mockBody.contentOwnerId]
|
||||
);
|
||||
expect(sendDiscordMessage).toBeCalledTimes(1);
|
||||
expect(sendDiscordMessage).toBeCalledWith(
|
||||
expect.stringContaining('**New Report**'),
|
||||
'reports'
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if failed to create the report', async () => {
|
||||
const mockBody = {
|
||||
contentOwnerId: "mockContentOwnerId",
|
||||
contentType: "user" as "user" | "comment" | "contract",
|
||||
contentId: "mockContentId",
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: null, error: Error});
|
||||
|
||||
expect(report(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to create report: ');
|
||||
});
|
||||
|
||||
it('should throw if unable to get information about the user', async () => {
|
||||
const mockBody = {
|
||||
contentOwnerId: "mockContentOwnerId",
|
||||
contentType: "user" as "user" | "comment" | "contract",
|
||||
contentId: "mockContentId",
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockBody, error: null});
|
||||
|
||||
const result = await report(mockBody, mockAuth, mockReq);
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockReturnValueOnce(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: null, error: Error});
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
expect.stringContaining('Failed to get user for report'),
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if unable to get information about the user being reported', async () => {
|
||||
const mockBody = {
|
||||
contentOwnerId: "mockContentOwnerId",
|
||||
contentType: "user" as "user" | "comment" | "contract",
|
||||
contentId: "mockContentId",
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReporter = {
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
};
|
||||
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockBody, error: null});
|
||||
|
||||
const result = await report(mockBody, mockAuth, mockReq);
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockReturnValueOnce(null)
|
||||
.mockReturnValueOnce(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: mockReporter, error: null})
|
||||
.mockResolvedValueOnce({data: null, error: Error});
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
expect.stringContaining('Failed to get reported user for report'),
|
||||
expect.objectContaining({name: 'Error'})
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if failed to send discord report', async () => {
|
||||
const mockBody = {
|
||||
contentOwnerId: "mockContentOwnerId",
|
||||
contentType: "user" as "user" | "comment" | "contract",
|
||||
contentId: "mockContentId",
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReporter = {
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
};
|
||||
const mockReported = {
|
||||
created_time: "mockCreatedTimeReported",
|
||||
data: {"mockDataReported" : "mockDataValueReported"},
|
||||
id: "mockIdReported",
|
||||
name: "mockNameReported",
|
||||
name_username_vector: "mockNameUsernameVectorReported",
|
||||
username: "mockUsernameReported",
|
||||
};
|
||||
|
||||
(supabaseUtils.insert as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockBody, error: null});
|
||||
|
||||
const result = await report(mockBody, mockAuth, mockReq);
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock)
|
||||
.mockReturnValueOnce(null)
|
||||
.mockReturnValueOnce(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: mockReporter, error: null})
|
||||
.mockResolvedValueOnce({data: mockReported, error: null});
|
||||
(sendDiscordMessage as jest.Mock).mockRejectedValue(new Error('Discord error'));
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
expect.stringContaining('Failed to send discord reports'),
|
||||
expect.any(Error)
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
70
backend/api/tests/unit/save-subscription-mobile.unit.test.ts
Normal file
70
backend/api/tests/unit/save-subscription-mobile.unit.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { saveSubscriptionMobile } from "api/save-subscription-mobile";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
|
||||
describe('saveSubscriptionMobile', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
none: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return success after saving the subscription', async () => {
|
||||
const mockBody = { token: "mockToken" };
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await saveSubscriptionMobile(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('insert into push_subscriptions_mobile(token, platform, user_id)'),
|
||||
[mockBody.token, 'android', mockAuth.uid]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if token is invalid', async () => {
|
||||
const mockBody = {} as any;
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
expect(saveSubscriptionMobile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Invalid subscription object');
|
||||
|
||||
});
|
||||
|
||||
it('should throw if unable to save subscription', async () => {
|
||||
const mockBody = { token: "mockToken" };
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockRejectedValue(new Error('Saving error'));
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
expect(saveSubscriptionMobile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to save subscription');
|
||||
// expect(errorSpy).toBeCalledTimes(1);
|
||||
// expect(errorSpy).toBeCalledWith(
|
||||
// expect.stringContaining('Error saving subscription'),
|
||||
// expect.any(Error)
|
||||
// );
|
||||
});
|
||||
});
|
||||
});
|
||||
118
backend/api/tests/unit/save-subscription.unit.test.ts
Normal file
118
backend/api/tests/unit/save-subscription.unit.test.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { saveSubscription } from "api/save-subscription";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
|
||||
describe('saveSubscription', () => {
|
||||
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 save user subscription', async () => {
|
||||
const mockBody = {
|
||||
subscription: {
|
||||
endpoint: "mockEndpoint",
|
||||
keys: "mockKeys",
|
||||
}
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExists = { id: "mockId" };
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockExists);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await saveSubscription(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select id from push_subscriptions where endpoint = $1'),
|
||||
[mockBody.subscription.endpoint]
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('update push_subscriptions set keys = $1, user_id = $2 where id = $3'),
|
||||
[mockBody.subscription.keys, mockAuth.uid, mockExists.id]
|
||||
);
|
||||
});
|
||||
|
||||
it('should save user subscription even if this is their first one', async () => {
|
||||
const mockBody = {
|
||||
subscription: {
|
||||
endpoint: "mockEndpoint",
|
||||
keys: "mockKeys",
|
||||
}
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await saveSubscription(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result.success).toBeTruthy();
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select id from push_subscriptions where endpoint = $1'),
|
||||
[mockBody.subscription.endpoint]
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('insert into push_subscriptions(endpoint, keys, user_id) values($1, $2, $3)'),
|
||||
[mockBody.subscription.endpoint, mockBody.subscription.keys, mockAuth.uid]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the subscription object is invalid', async () => {
|
||||
const mockBody = {} as any;
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
expect(saveSubscription(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Invalid subscription object');
|
||||
});
|
||||
|
||||
it('should throw if unable to save subscription', async () => {
|
||||
const mockBody = {
|
||||
subscription: {
|
||||
endpoint: "mockEndpoint",
|
||||
keys: "mockKeys",
|
||||
}
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExists = { id: "mockId" };
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockExists);
|
||||
(mockPg.none as jest.Mock).mockRejectedValue(new Error('Saving error'));
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
expect(saveSubscription(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to save subscription');
|
||||
|
||||
// expect(errorSpy).toBeCalledTimes(1);
|
||||
// expect(errorSpy).toBeCalledWith(
|
||||
// expect.stringContaining('Error saving subscription'),
|
||||
// expect.any(Error)
|
||||
// );
|
||||
});
|
||||
});
|
||||
});
|
||||
36
backend/api/tests/unit/search-location.unit.test.ts
Normal file
36
backend/api/tests/unit/search-location.unit.test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
jest.mock('common/geodb');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { searchLocation } from "api/search-location";
|
||||
import * as geodbModules from "common/geodb";
|
||||
|
||||
describe('searchLocation', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return search location', async () => {
|
||||
const mockBody = {
|
||||
term: "mockTerm",
|
||||
limit: 15
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReturn = "Pass";
|
||||
|
||||
(geodbModules.geodbFetch as jest.Mock).mockResolvedValue(mockReturn);
|
||||
|
||||
const result = await searchLocation(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result).toBe(mockReturn);
|
||||
expect(geodbModules.geodbFetch).toBeCalledTimes(1);
|
||||
expect(geodbModules.geodbFetch).toBeCalledWith(
|
||||
expect.stringContaining(`/cities?namePrefix=${mockBody.term}&limit=${mockBody.limit}&offset=0&sort=-population`)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
72
backend/api/tests/unit/search-near-city.unit.test.ts
Normal file
72
backend/api/tests/unit/search-near-city.unit.test.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
jest.mock('common/geodb');
|
||||
|
||||
import * as citySearchModules from "api/search-near-city";
|
||||
import * as geoDbModules from "common/geodb";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('searchNearCity', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return locations near a city', async () => {
|
||||
const mockBody = {
|
||||
radius: 123,
|
||||
cityId: "mockCityId"
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReturn = "Pass";
|
||||
|
||||
(geoDbModules.geodbFetch as jest.Mock).mockResolvedValue(mockReturn);
|
||||
|
||||
const result = await citySearchModules.searchNearCity(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(result).toBe(mockReturn);
|
||||
expect(geoDbModules.geodbFetch).toBeCalledTimes(1);
|
||||
expect(geoDbModules.geodbFetch).toBeCalledWith(
|
||||
expect.stringContaining(`/cities/${mockBody.cityId}/nearbyCities?radius=${mockBody.radius}&offset=0&sort=-population&limit=100`)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getNearCity', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return locations near a city', async () => {
|
||||
const mockBody = {
|
||||
radius: 123,
|
||||
cityId: "mockCityId"
|
||||
};
|
||||
const mockReturn = {
|
||||
status: "mockStatus",
|
||||
data: {
|
||||
data: [
|
||||
{ id: "mockId" }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
(geoDbModules.geodbFetch as jest.Mock).mockResolvedValue(mockReturn);
|
||||
|
||||
const result = await citySearchModules.getNearbyCities(mockBody.cityId, mockBody.radius);
|
||||
|
||||
expect(result).toStrictEqual([mockReturn.data.data[0].id]);
|
||||
expect(geoDbModules.geodbFetch).toBeCalledTimes(1);
|
||||
expect(geoDbModules.geodbFetch).toBeCalledWith(
|
||||
expect.stringContaining(`/cities/${mockBody.cityId}/nearbyCities?radius=${mockBody.radius}&offset=0&sort=-population&limit=100`)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
154
backend/api/tests/unit/search-users.unit.test.ts
Normal file
154
backend/api/tests/unit/search-users.unit.test.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/helpers/search');
|
||||
jest.mock('shared/supabase/sql-builder');
|
||||
jest.mock('common/supabase/users');
|
||||
jest.mock('common/api/user-types');
|
||||
|
||||
import { searchUsers } from "api/search-users";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as searchHelpers from "shared/helpers/search";
|
||||
import * as sqlBuilderModules from "shared/supabase/sql-builder";
|
||||
import * as supabaseUsers from "common/supabase/users";
|
||||
import { toUserAPIResponse } from "common/api/user-types";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('searchUsers', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
map: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return an array of uniq users', async () => {
|
||||
const mockProps = {
|
||||
term: "mockTerm",
|
||||
limit: 10,
|
||||
page: 1
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockSearchAllSql = "mockSQL";
|
||||
const mockAllUser = [
|
||||
{id: "mockId 1"},
|
||||
{id: "mockId 2"},
|
||||
{id: "mockId 3"},
|
||||
];
|
||||
|
||||
(sqlBuilderModules.renderSql as jest.Mock).mockReturnValue(mockSearchAllSql);
|
||||
(sqlBuilderModules.select as jest.Mock).mockReturnValue('Select');
|
||||
(sqlBuilderModules.from as jest.Mock).mockReturnValue('From');
|
||||
(sqlBuilderModules.where as jest.Mock).mockReturnValue('Where');
|
||||
(searchHelpers.constructPrefixTsQuery as jest.Mock).mockReturnValue('ConstructPrefix');
|
||||
(sqlBuilderModules.orderBy as jest.Mock).mockReturnValue('OrderBy');
|
||||
(sqlBuilderModules.limit as jest.Mock).mockReturnValue('Limit');
|
||||
(supabaseUsers.convertUser as jest.Mock).mockResolvedValue(null);
|
||||
(mockPg.map as jest.Mock).mockResolvedValue(mockAllUser);
|
||||
(toUserAPIResponse as jest.Mock)
|
||||
.mockReturnValueOnce(mockAllUser[0].id)
|
||||
.mockReturnValueOnce(mockAllUser[1].id)
|
||||
.mockReturnValueOnce(mockAllUser[2].id);
|
||||
|
||||
const result: any = await searchUsers(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result[0]).toContain(mockAllUser[0].id);
|
||||
expect(result[1]).toContain(mockAllUser[1].id);
|
||||
expect(result[2]).toContain(mockAllUser[2].id);
|
||||
|
||||
expect(sqlBuilderModules.renderSql).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.renderSql).toBeCalledWith(
|
||||
['Select', 'From'],
|
||||
['Where', 'OrderBy'],
|
||||
'Limit'
|
||||
);
|
||||
|
||||
expect(sqlBuilderModules.select).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.select).toBeCalledWith('*');
|
||||
expect(sqlBuilderModules.from).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.from).toBeCalledWith('users');
|
||||
expect(sqlBuilderModules.where).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.where).toBeCalledWith(
|
||||
expect.stringContaining("name_username_vector @@ websearch_to_tsquery('english', $1)"),
|
||||
[mockProps.term, 'ConstructPrefix']
|
||||
);
|
||||
expect(sqlBuilderModules.orderBy).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.orderBy).toBeCalledWith(
|
||||
expect.stringContaining("ts_rank(name_username_vector, websearch_to_tsquery($1)) desc,"),
|
||||
[mockProps.term]
|
||||
);
|
||||
expect(sqlBuilderModules.limit).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.limit).toBeCalledWith(mockProps.limit, mockProps.page * mockProps.limit);
|
||||
expect(mockPg.map).toBeCalledTimes(1);
|
||||
expect(mockPg.map).toBeCalledWith(
|
||||
mockSearchAllSql,
|
||||
null,
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it('should return an array of uniq users if no term is supplied', async () => {
|
||||
const mockProps = {
|
||||
limit: 10,
|
||||
page: 1
|
||||
} as any;
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockSearchAllSql = "mockSQL";
|
||||
const mockAllUser = [
|
||||
{id: "mockId 1"},
|
||||
{id: "mockId 2"},
|
||||
{id: "mockId 3"},
|
||||
];
|
||||
|
||||
(sqlBuilderModules.renderSql as jest.Mock).mockReturnValue(mockSearchAllSql);
|
||||
(sqlBuilderModules.select as jest.Mock).mockReturnValue('Select');
|
||||
(sqlBuilderModules.from as jest.Mock).mockReturnValue('From');
|
||||
(sqlBuilderModules.orderBy as jest.Mock).mockReturnValue('OrderBy');
|
||||
(sqlBuilderModules.limit as jest.Mock).mockReturnValue('Limit');
|
||||
(supabaseUsers.convertUser as jest.Mock).mockResolvedValue(null);
|
||||
(mockPg.map as jest.Mock).mockResolvedValue(mockAllUser);
|
||||
(toUserAPIResponse as jest.Mock)
|
||||
.mockReturnValueOnce(mockAllUser[0].id)
|
||||
.mockReturnValueOnce(mockAllUser[1].id)
|
||||
.mockReturnValueOnce(mockAllUser[2].id);
|
||||
|
||||
const result: any = await searchUsers(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result[0]).toContain(mockAllUser[0].id);
|
||||
expect(result[1]).toContain(mockAllUser[1].id);
|
||||
expect(result[2]).toContain(mockAllUser[2].id);
|
||||
|
||||
expect(sqlBuilderModules.renderSql).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.renderSql).toBeCalledWith(
|
||||
['Select', 'From'],
|
||||
'OrderBy',
|
||||
'Limit'
|
||||
);
|
||||
|
||||
expect(sqlBuilderModules.select).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.select).toBeCalledWith('*');
|
||||
expect(sqlBuilderModules.from).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.from).toBeCalledWith('users');
|
||||
expect(sqlBuilderModules.orderBy).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.orderBy).toBeCalledWith(
|
||||
expect.stringMatching(`data->'creatorTraders'->'allTime' desc nulls last`)
|
||||
);
|
||||
expect(sqlBuilderModules.limit).toBeCalledTimes(1);
|
||||
expect(sqlBuilderModules.limit).toBeCalledWith(mockProps.limit, mockProps.page * mockProps.limit);
|
||||
expect(mockPg.map).toBeCalledTimes(1);
|
||||
expect(mockPg.map).toBeCalledWith(
|
||||
mockSearchAllSql,
|
||||
null,
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
314
backend/api/tests/unit/send-search-notifications.unit.test.ts
Normal file
314
backend/api/tests/unit/send-search-notifications.unit.test.ts
Normal file
@@ -0,0 +1,314 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/supabase/sql-builder');
|
||||
jest.mock('api/get-profiles');
|
||||
jest.mock('email/functions/helpers');
|
||||
jest.mock('lodash');
|
||||
|
||||
import * as searchNotificationModules from "api/send-search-notifications";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as sqlBuilderModules from "shared/supabase/sql-builder";
|
||||
import * as profileModules from "api/get-profiles";
|
||||
import * as helperModules from "email/functions/helpers";
|
||||
import * as lodashModules from "lodash";
|
||||
|
||||
describe('sendSearchNotification', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
map: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should send search notification emails', async () => {
|
||||
const mockSearchQuery = "mockSqlQuery";
|
||||
const mockSearches = [
|
||||
{
|
||||
created_time: "mockSearchCreatedTime",
|
||||
creator_id: "mockCreatorId",
|
||||
id: 123,
|
||||
last_notified_at: null,
|
||||
location: {"mockLocation" : "mockLocationValue"},
|
||||
search_filters: null,
|
||||
search_name: null,
|
||||
},
|
||||
{
|
||||
created_time: "mockCreatedTime1",
|
||||
creator_id: "mockCreatorId1",
|
||||
id: 1234,
|
||||
last_notified_at: null,
|
||||
location: {"mockLocation1" : "mockLocationValue1"},
|
||||
search_filters: null,
|
||||
search_name: null,
|
||||
},
|
||||
];
|
||||
const _mockUsers = [
|
||||
{
|
||||
created_time: "mockUserCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
},
|
||||
{
|
||||
created_time: "mockUserCreatedTime1",
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1",
|
||||
name: "mockName1",
|
||||
name_username_vector: "mockNameUsernameVector1",
|
||||
username: "mockUsername1",
|
||||
},
|
||||
];
|
||||
const mockUsers = {
|
||||
"user1": {
|
||||
created_time: "mockUserCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
},
|
||||
"user2": {
|
||||
created_time: "mockUserCreatedTime1",
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1",
|
||||
name: "mockName1",
|
||||
name_username_vector: "mockNameUsernameVector1",
|
||||
username: "mockUsername1",
|
||||
},
|
||||
};
|
||||
const _mockPrivateUsers = [
|
||||
{
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId"
|
||||
},
|
||||
{
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1"
|
||||
},
|
||||
];
|
||||
const mockPrivateUsers = {
|
||||
"privateUser1": {
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId"
|
||||
},
|
||||
"privateUser2": {
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1"
|
||||
},
|
||||
};
|
||||
const mockProfiles = [
|
||||
{
|
||||
name: "mockProfileName",
|
||||
username: "mockProfileUsername"
|
||||
},
|
||||
{
|
||||
name: "mockProfileName1",
|
||||
username: "mockProfileUsername1"
|
||||
},
|
||||
];
|
||||
const mockProps = [
|
||||
{
|
||||
skipId: "mockCreatorId",
|
||||
lastModificationWithin: '24 hours',
|
||||
shortBio: true,
|
||||
},
|
||||
{
|
||||
skipId: "mockCreatorId1",
|
||||
lastModificationWithin: '24 hours',
|
||||
shortBio: true,
|
||||
},
|
||||
];
|
||||
(sqlBuilderModules.renderSql as jest.Mock)
|
||||
.mockReturnValueOnce(mockSearchQuery)
|
||||
.mockReturnValueOnce('usersRenderSql')
|
||||
.mockReturnValueOnce('privateUsersRenderSql');
|
||||
(sqlBuilderModules.select as jest.Mock).mockReturnValue('Select');
|
||||
(sqlBuilderModules.from as jest.Mock).mockReturnValue('From');
|
||||
(mockPg.map as jest.Mock)
|
||||
.mockResolvedValueOnce(mockSearches)
|
||||
.mockResolvedValueOnce(_mockUsers)
|
||||
.mockResolvedValueOnce(_mockPrivateUsers);
|
||||
(lodashModules.keyBy as jest.Mock)
|
||||
.mockReturnValueOnce(mockUsers)
|
||||
.mockReturnValueOnce(mockPrivateUsers);
|
||||
(profileModules.loadProfiles as jest.Mock)
|
||||
.mockResolvedValueOnce({profiles: mockProfiles})
|
||||
.mockResolvedValueOnce({profiles: mockProfiles});
|
||||
jest.spyOn(searchNotificationModules, 'notifyBookmarkedSearch');
|
||||
(helperModules.sendSearchAlertsEmail as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result = await searchNotificationModules.sendSearchNotifications();
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(sqlBuilderModules.renderSql).toBeCalledTimes(3);
|
||||
expect(sqlBuilderModules.renderSql).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'Select',
|
||||
'From'
|
||||
);
|
||||
expect(sqlBuilderModules.renderSql).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'Select',
|
||||
'From'
|
||||
);
|
||||
expect(sqlBuilderModules.renderSql).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
'Select',
|
||||
'From'
|
||||
);
|
||||
expect(mockPg.map).toBeCalledTimes(3);
|
||||
expect(mockPg.map).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
mockSearchQuery,
|
||||
[],
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(mockPg.map).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'usersRenderSql',
|
||||
[],
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(mockPg.map).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
'privateUsersRenderSql',
|
||||
[],
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(profileModules.loadProfiles).toBeCalledTimes(2);
|
||||
expect(profileModules.loadProfiles).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
mockProps[0]
|
||||
);
|
||||
expect(profileModules.loadProfiles).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
mockProps[1]
|
||||
);
|
||||
expect(searchNotificationModules.notifyBookmarkedSearch).toBeCalledTimes(1);
|
||||
expect(searchNotificationModules.notifyBookmarkedSearch).toBeCalledWith({});
|
||||
});
|
||||
|
||||
it('should send search notification emails when there is a matching creator_id entry in private users', async () => {
|
||||
const mockSearchQuery = "mockSqlQuery";
|
||||
const mockSearches = [
|
||||
{
|
||||
created_time: "mockSearchCreatedTime",
|
||||
creator_id: "mockCreatorId",
|
||||
id: 123,
|
||||
last_notified_at: null,
|
||||
location: {"mockLocation" : "mockLocationValue"},
|
||||
search_filters: null,
|
||||
search_name: null,
|
||||
},
|
||||
{
|
||||
created_time: "mockCreatedTime1",
|
||||
creator_id: "mockCreatorId1",
|
||||
id: 1234,
|
||||
last_notified_at: null,
|
||||
location: {"mockLocation1" : "mockLocationValue1"},
|
||||
search_filters: null,
|
||||
search_name: null,
|
||||
},
|
||||
];
|
||||
const _mockUsers = [
|
||||
{
|
||||
created_time: "mockUserCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
},
|
||||
{
|
||||
created_time: "mockUserCreatedTime1",
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1",
|
||||
name: "mockName1",
|
||||
name_username_vector: "mockNameUsernameVector1",
|
||||
username: "mockUsername1",
|
||||
},
|
||||
];
|
||||
const mockUsers = {
|
||||
"user1": {
|
||||
created_time: "mockUserCreatedTime",
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_username_vector: "mockNameUsernameVector",
|
||||
username: "mockUsername",
|
||||
},
|
||||
"user2": {
|
||||
created_time: "mockUserCreatedTime1",
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1",
|
||||
name: "mockName1",
|
||||
name_username_vector: "mockNameUsernameVector1",
|
||||
username: "mockUsername1",
|
||||
},
|
||||
};
|
||||
const _mockPrivateUsers = [
|
||||
{
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId"
|
||||
},
|
||||
{
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1"
|
||||
},
|
||||
];
|
||||
const mockPrivateUsers = {
|
||||
"mockCreatorId": {
|
||||
data: {"mockData" : "mockDataValue"},
|
||||
id: "mockId"
|
||||
},
|
||||
"mockCreatorId1": {
|
||||
data: {"mockData1" : "mockDataValue1"},
|
||||
id: "mockId1"
|
||||
},
|
||||
};
|
||||
const mockProfiles = [
|
||||
{
|
||||
name: "mockProfileName",
|
||||
username: "mockProfileUsername"
|
||||
},
|
||||
{
|
||||
name: "mockProfileName1",
|
||||
username: "mockProfileUsername1"
|
||||
},
|
||||
];
|
||||
(sqlBuilderModules.renderSql as jest.Mock)
|
||||
.mockReturnValueOnce(mockSearchQuery)
|
||||
.mockReturnValueOnce('usersRenderSql')
|
||||
.mockReturnValueOnce('privateUsersRenderSql');
|
||||
(sqlBuilderModules.select as jest.Mock).mockReturnValue('Select');
|
||||
(sqlBuilderModules.from as jest.Mock).mockReturnValue('From');
|
||||
(mockPg.map as jest.Mock)
|
||||
.mockResolvedValueOnce(mockSearches)
|
||||
.mockResolvedValueOnce(_mockUsers)
|
||||
.mockResolvedValueOnce(_mockPrivateUsers);
|
||||
(lodashModules.keyBy as jest.Mock)
|
||||
.mockReturnValueOnce(mockUsers)
|
||||
.mockReturnValueOnce(mockPrivateUsers);
|
||||
(profileModules.loadProfiles as jest.Mock)
|
||||
.mockResolvedValueOnce({profiles: mockProfiles})
|
||||
.mockResolvedValueOnce({profiles: mockProfiles});
|
||||
jest.spyOn(searchNotificationModules, 'notifyBookmarkedSearch');
|
||||
(helperModules.sendSearchAlertsEmail as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await searchNotificationModules.sendSearchNotifications();
|
||||
|
||||
expect(searchNotificationModules.notifyBookmarkedSearch).toBeCalledTimes(1);
|
||||
expect(searchNotificationModules.notifyBookmarkedSearch).not.toBeCalledWith({});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/compatibility/compute-scores');
|
||||
|
||||
import { setCompatibilityAnswer } from "api/set-compatibility-answer";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import { recomputeCompatibilityScoresForUser } from "shared/compatibility/compute-scores";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('setCompatibilityAnswer', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should set compatibility answers', async () => {
|
||||
const mockProps = {
|
||||
questionId: 1,
|
||||
multipleChoice: 2,
|
||||
prefChoices: [1,2,3,4,5],
|
||||
importance: 1,
|
||||
explanation: "mockExplanation"
|
||||
};
|
||||
const mockResult = {
|
||||
created_time: "mockCreatedTime",
|
||||
creator_id: "mockCreatorId",
|
||||
explanation: "mockExplanation",
|
||||
id: 123,
|
||||
importance: 1,
|
||||
multipleChoice: 2,
|
||||
prefChoices: [1,2,3,4,5],
|
||||
questionId: 1,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockResult);
|
||||
(recomputeCompatibilityScoresForUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result: any = await setCompatibilityAnswer(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.result).toBe(mockResult);
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
{
|
||||
text: expect.stringContaining('INSERT INTO compatibility_answers'),
|
||||
values: [
|
||||
mockAuth.uid,
|
||||
mockProps.questionId,
|
||||
mockProps.multipleChoice,
|
||||
mockProps.prefChoices,
|
||||
mockProps.importance,
|
||||
mockProps.explanation,
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(recomputeCompatibilityScoresForUser).toBeCalledTimes(1);
|
||||
expect(recomputeCompatibilityScoresForUser).toBeCalledWith(mockAuth.uid, expect.any(Object));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,34 +1,56 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import * as setLastTimeOnlineModule from "api/set-last-online-time";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
|
||||
describe('Should', () => {
|
||||
describe('setLastOnlineTimeUser', () => {
|
||||
let mockPg: any;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
none: jest.fn(),
|
||||
};
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
|
||||
jest.clearAllMocks();
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('change the users last online time', async () => {
|
||||
const mockProfile = {user_id: 'Jonathon'};
|
||||
|
||||
await setLastTimeOnlineModule.setLastOnlineTimeUser(mockProfile.user_id);
|
||||
describe('when given valid input', () => {
|
||||
it('should change the users last online time', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockProps = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
jest.spyOn(setLastTimeOnlineModule, 'setLastOnlineTimeUser');
|
||||
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
await setLastTimeOnlineModule.setLastOnlineTime(mockProps, mockAuth, mockReq);
|
||||
const [query, userId] = mockPg.none.mock.calls[0];
|
||||
|
||||
expect(setLastTimeOnlineModule.setLastOnlineTimeUser).toBeCalledTimes(1);
|
||||
expect(setLastTimeOnlineModule.setLastOnlineTimeUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(userId).toContain(mockAuth.uid);
|
||||
expect(query).toContain("VALUES ($1, now())");
|
||||
expect(query).toContain("ON CONFLICT (user_id)");
|
||||
expect(query).toContain("DO UPDATE");
|
||||
expect(query).toContain("user_activity.last_online_time < now() - interval '1 minute'");
|
||||
});
|
||||
|
||||
const [query, userId] = mockPg.none.mock.calls[0];
|
||||
|
||||
expect(userId).toContain(mockProfile.user_id);
|
||||
expect(query).toContain("VALUES ($1, now())")
|
||||
expect(query).toContain("ON CONFLICT (user_id)")
|
||||
expect(query).toContain("DO UPDATE")
|
||||
expect(query).toContain("user_activity.last_online_time < now() - interval '1 minute'")
|
||||
it('should return if there is no auth', async () => {
|
||||
const mockAuth = { } as any;
|
||||
const mockReq = {} as any;
|
||||
const mockProps = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
jest.spyOn(setLastTimeOnlineModule, 'setLastOnlineTimeUser');
|
||||
|
||||
await setLastTimeOnlineModule.setLastOnlineTime(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(setLastTimeOnlineModule.setLastOnlineTimeUser).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
227
backend/api/tests/unit/ship-profiles.unit.test.ts
Normal file
227
backend/api/tests/unit/ship-profiles.unit.test.ts
Normal file
@@ -0,0 +1,227 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/supabase/utils');
|
||||
jest.mock('shared/create-profile-notification');
|
||||
|
||||
import { shipProfiles } from "api/ship-profiles";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseUtils from "shared/supabase/utils";
|
||||
import * as profileNotificationModules from "shared/create-profile-notification";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('shipProfiles', () => {
|
||||
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 return success if the profile ship already exists', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: false,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: { ship_id : "mockShipId" },
|
||||
error: null
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue(mockExisting);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result: any = await shipProfiles(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select ship_id from profile_ships'),
|
||||
[mockAuth.uid, mockProps.targetUserId1, mockProps.targetUserId2]
|
||||
);
|
||||
});
|
||||
|
||||
it('should return success if trying to remove a profile ship that already exists', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: true,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: { ship_id : "mockShipId" },
|
||||
error: null
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce(mockExisting)
|
||||
.mockResolvedValueOnce({error: null});
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const result: any = await shipProfiles(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(2);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select ship_id from profile_ships'),
|
||||
[mockAuth.uid, mockProps.targetUserId1, mockProps.targetUserId2]
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('delete from profile_ships where ship_id = $1'),
|
||||
[mockExisting.data.ship_id]
|
||||
);
|
||||
});
|
||||
|
||||
it('should return success when creating a new profile ship', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: false,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: null,
|
||||
error: null
|
||||
};
|
||||
const mockData = {
|
||||
created_time: "mockCreatedTime",
|
||||
creator_id: "mockCreatorId",
|
||||
ship_id: "mockShipId",
|
||||
target1_id: "mockTarget1Id",
|
||||
target2_id: "mockTarget2Id",
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce(mockExisting)
|
||||
.mockResolvedValueOnce({data: mockData, error: null});
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
|
||||
const result: any = await shipProfiles(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(2);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select ship_id from profile_ships'),
|
||||
[mockAuth.uid, mockProps.targetUserId1, mockProps.targetUserId2]
|
||||
);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
'profile_ships',
|
||||
{
|
||||
creator_id: mockAuth.uid,
|
||||
target1_id: mockProps.targetUserId1,
|
||||
target2_id: mockProps.targetUserId2,
|
||||
}
|
||||
);
|
||||
|
||||
(profileNotificationModules.createProfileShipNotification as jest.Mock).mockReturnValue(null);
|
||||
|
||||
await result.continue();
|
||||
|
||||
expect(profileNotificationModules.createProfileShipNotification).toBeCalledTimes(2);
|
||||
expect(profileNotificationModules.createProfileShipNotification).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
mockData,
|
||||
mockData.target1_id
|
||||
);
|
||||
expect(profileNotificationModules.createProfileShipNotification).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
mockData,
|
||||
mockData.target2_id
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if unable to check ship', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: false,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: null,
|
||||
error: Error
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue(mockExisting);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
expect(shipProfiles(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Error when checking ship: ');
|
||||
|
||||
});
|
||||
|
||||
it('should throw if unable to remove a profile ship that already exists', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: true,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: { ship_id : "mockShipId" },
|
||||
error: null
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce(mockExisting)
|
||||
.mockResolvedValueOnce({error: Error});
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
expect(shipProfiles(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to remove ship: ');
|
||||
});
|
||||
|
||||
it('should return success when creating a new profile ship', async () => {
|
||||
const mockProps = {
|
||||
targetUserId1: "mockTargetUserId1",
|
||||
targetUserId2: "mockTargetUserId2",
|
||||
remove: false,
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
data: null,
|
||||
error: null
|
||||
};
|
||||
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce(mockExisting)
|
||||
.mockResolvedValueOnce({data: null, error: Error});
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
|
||||
expect(shipProfiles(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to create ship: ');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
146
backend/api/tests/unit/star-profile.unit.test.ts
Normal file
146
backend/api/tests/unit/star-profile.unit.test.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/supabase/utils');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { starProfile } from "api/star-profile";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as supabaseUtils from "shared/supabase/utils";
|
||||
|
||||
describe('startProfile', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
none: jest.fn(),
|
||||
oneOrNone: jest.fn(),
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should return success when trying to star a profile for the first time', async () => {
|
||||
const mockProps = {
|
||||
targetUserId: "mockTargetUserId",
|
||||
remove: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: null})
|
||||
.mockResolvedValueOnce({error: null});
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
|
||||
const result: any = await starProfile(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(2);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select * from profile_stars where creator_id = $1 and target_id = $2'),
|
||||
[mockAuth.uid, mockProps.targetUserId]
|
||||
);
|
||||
expect(supabaseUtils.insert).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
'profile_stars',
|
||||
{
|
||||
creator_id: mockAuth.uid,
|
||||
target_id: mockProps.targetUserId
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should return success if the profile already has a star', async () => {
|
||||
const mockProps = {
|
||||
targetUserId: "mockTargetUserId",
|
||||
remove: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockExisting = {
|
||||
created_time: "mockCreatedTime",
|
||||
creator_id: "mockCreatorId",
|
||||
star_id: "mockStarId",
|
||||
target_id: "mockTarget",
|
||||
};
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockExisting});
|
||||
|
||||
const result: any = await starProfile(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.insert).not.toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should return success when trying to remove a star', async () => {
|
||||
const mockProps = {
|
||||
targetUserId: "mockTargetUserId",
|
||||
remove: true
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({error: null});
|
||||
|
||||
const result: any = await starProfile(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.status).toBe('success');
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('delete from profile_stars where creator_id = $1 and target_id = $2'),
|
||||
[mockAuth.uid, mockProps.targetUserId]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if unable to remove star', async () => {
|
||||
const mockProps = {
|
||||
targetUserId: "mockTargetUserId",
|
||||
remove: true
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({error: Error});
|
||||
|
||||
expect(starProfile(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to remove star');
|
||||
});
|
||||
|
||||
it('should throw if unable to add a star', async () => {
|
||||
const mockProps = {
|
||||
targetUserId: "mockTargetUserId",
|
||||
remove: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(null);
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: null})
|
||||
.mockResolvedValueOnce({error: Error});
|
||||
(supabaseUtils.insert as jest.Mock).mockReturnValue(null);
|
||||
|
||||
expect(starProfile(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Failed to add star');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
255
backend/api/tests/unit/update-me.unit.test.ts
Normal file
255
backend/api/tests/unit/update-me.unit.test.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
71
backend/api/tests/unit/update-notif-setting.unit.test.ts
Normal file
71
backend/api/tests/unit/update-notif-setting.unit.test.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/supabase/users');
|
||||
jest.mock('shared/websockets/helpers');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { updateNotifSettings } from "api/update-notif-setting";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as supabaseUsers from "shared/supabase/users";
|
||||
import * as websocketHelpers from "shared/websockets/helpers";
|
||||
|
||||
describe('updateNotifSettings', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
none: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should update notification settings', async () => {
|
||||
const mockProps = {
|
||||
type: "new_match" as const,
|
||||
medium: "email" as const,
|
||||
enabled: false
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(mockPg.none as jest.Mock).mockResolvedValue(null);
|
||||
(websocketHelpers.broadcastUpdatedPrivateUser as jest.Mock).mockReturnValue(null);
|
||||
|
||||
await updateNotifSettings(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('update private_users'),
|
||||
[mockProps.type, mockProps.medium, mockAuth.uid]
|
||||
);
|
||||
expect(websocketHelpers.broadcastUpdatedPrivateUser).toBeCalledTimes(1);
|
||||
expect(websocketHelpers.broadcastUpdatedPrivateUser).toBeCalledWith(mockAuth.uid);
|
||||
});
|
||||
|
||||
it('should turn off notifications', async () => {
|
||||
const mockProps = {
|
||||
type: "opt_out_all" as const,
|
||||
medium: "mobile" as const,
|
||||
enabled: true
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(supabaseUsers.updatePrivateUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
await updateNotifSettings(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(supabaseUsers.updatePrivateUser).toBeCalledTimes(1);
|
||||
expect(supabaseUsers.updatePrivateUser).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{interestedInPushNotifications: !mockProps.enabled}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
170
backend/api/tests/unit/update-options.unit.test.ts
Normal file
170
backend/api/tests/unit/update-options.unit.test.ts
Normal file
@@ -0,0 +1,170 @@
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/supabase/init');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { updateOptions } from "api/update-options";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
|
||||
describe('updateOptions', () => {
|
||||
let mockPg = {} as any;
|
||||
let mockTx = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockTx = {
|
||||
one: jest.fn(),
|
||||
none: jest.fn()
|
||||
};
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn(),
|
||||
tx: jest.fn(async (cb) => await cb(mockTx))
|
||||
};
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when given valid input', () => {
|
||||
it('should update user', async () => {
|
||||
const mockProps = {
|
||||
table: 'causes' as const,
|
||||
names: ["mockNamesOne", "mockNamesTwo"]
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockProfileIdResult = {id: 123};
|
||||
const mockRow1 = {
|
||||
id: 1234,
|
||||
};
|
||||
const mockRow2 = {
|
||||
id: 12345,
|
||||
};
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(true);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockProfileIdResult);
|
||||
(tryCatch as jest.Mock).mockImplementation(async (fn: any) => {
|
||||
try {
|
||||
const data = await fn;
|
||||
return {data, error: null};
|
||||
} catch (error) {
|
||||
return {data:null, error};
|
||||
}
|
||||
});
|
||||
(mockTx.one as jest.Mock)
|
||||
.mockResolvedValueOnce(mockRow1)
|
||||
.mockResolvedValueOnce(mockRow2);
|
||||
|
||||
const result: any = await updateOptions(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.updatedIds).toStrictEqual([mockRow1.id, mockRow2.id]);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('SELECT id FROM profiles WHERE user_id = $1'),
|
||||
[mockAuth.uid]
|
||||
);
|
||||
expect(tryCatch).toBeCalledTimes(1);
|
||||
expect(mockTx.one).toBeCalledTimes(2);
|
||||
expect(mockTx.one).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining(`INSERT INTO ${mockProps.table} (name, creator_id)`),
|
||||
[mockProps.names[0], mockAuth.uid]
|
||||
);
|
||||
expect(mockTx.one).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining(`INSERT INTO ${mockProps.table} (name, creator_id)`),
|
||||
[mockProps.names[1], mockAuth.uid]
|
||||
);
|
||||
expect(mockTx.none).toBeCalledTimes(2);
|
||||
expect(mockTx.none).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
expect.stringContaining(`DELETE FROM profile_${mockProps.table} WHERE profile_id = $1`),
|
||||
[mockProfileIdResult.id]
|
||||
);
|
||||
expect(mockTx.none).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.stringContaining(`INSERT INTO profile_${mockProps.table} (profile_id, option_id) VALUES`),
|
||||
[mockProfileIdResult.id, mockRow1.id, mockRow2.id]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the table param is invalid', async () => {
|
||||
const mockProps = {
|
||||
table: 'causes' as const,
|
||||
names: ["mockNamesOne", "mockNamesTwo"]
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(false);
|
||||
|
||||
expect(updateOptions(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Invalid table');
|
||||
});
|
||||
|
||||
it('should throw if the names param is not provided', async () => {
|
||||
const mockProps = {
|
||||
table: 'causes' as const,
|
||||
names: []
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(true);
|
||||
|
||||
expect(updateOptions(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('No names provided');
|
||||
});
|
||||
|
||||
it('should throw if unable to find profile', async () => {
|
||||
const mockProps = {
|
||||
table: 'causes' as const,
|
||||
names: ["mockNamesOne", "mockNamesTwo"]
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(true);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(updateOptions(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Profile not found');
|
||||
});
|
||||
|
||||
it('should update user', async () => {
|
||||
const mockProps = {
|
||||
table: 'causes' as const,
|
||||
names: ["mockNamesOne", "mockNamesTwo"]
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockProfileIdResult = {id: 123};
|
||||
const mockRow1 = {
|
||||
id: 1234,
|
||||
};
|
||||
const mockRow2 = {
|
||||
id: 12345,
|
||||
};
|
||||
|
||||
jest.spyOn(Array.prototype, 'includes').mockReturnValue(true);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockProfileIdResult);
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: null, error: Error});
|
||||
(mockPg.tx as jest.Mock).mockResolvedValue(null);
|
||||
(mockTx.one as jest.Mock)
|
||||
.mockResolvedValueOnce(mockRow1)
|
||||
.mockResolvedValueOnce(mockRow2);
|
||||
(mockTx.none as jest.Mock)
|
||||
.mockResolvedValueOnce(null)
|
||||
.mockResolvedValueOnce(null);
|
||||
|
||||
expect(updateOptions(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Error updating profile options');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/utils');
|
||||
jest.mock('common/supabase/utils');
|
||||
|
||||
import {updatePrivateUserMessageChannel} from "api/update-private-user-message-channel";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as sharedUtils from "shared/utils";
|
||||
import * as supabaseUtils from "common/supabase/utils";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('updatePrivateUserMessageChannel', () => {
|
||||
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 return success after updating the users private message channel', async () => {
|
||||
const mockBody = {
|
||||
channelId: 123,
|
||||
notifyAfterTime: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(true);
|
||||
(supabaseUtils.millisToTs as jest.Mock).mockReturnValue('mockMillisToTs');
|
||||
|
||||
const results = await updatePrivateUserMessageChannel(mockBody, mockAuth, mockReq);
|
||||
|
||||
expect(results.status).toBe('success');
|
||||
expect(results.channelId).toBe(mockBody.channelId);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select status from private_user_message_channel_members'),
|
||||
[mockBody.channelId, mockAuth.uid]
|
||||
);
|
||||
expect(mockPg.none).toBeCalledTimes(1);
|
||||
expect(mockPg.none).toBeCalledWith(
|
||||
expect.stringContaining('update private_user_message_channel_members'),
|
||||
[mockBody.channelId, mockAuth.uid, 'mockMillisToTs']
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the user account does not exist', async () => {
|
||||
const mockBody = {
|
||||
channelId: 123,
|
||||
notifyAfterTime: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(updatePrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Your account was not found');
|
||||
});
|
||||
|
||||
it('should throw if the user is not authorized in the channel', async () => {
|
||||
const mockBody = {
|
||||
channelId: 123,
|
||||
notifyAfterTime: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(true);
|
||||
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(updatePrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('You are not authorized to this channel');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,86 +1,100 @@
|
||||
jest.mock("shared/supabase/init");
|
||||
jest.mock("shared/supabase/utils");
|
||||
jest.mock("common/util/try-catch");
|
||||
jest.mock("shared/profiles/parse-photos");
|
||||
jest.mock("shared/supabase/users");
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { updateProfile } from "api/update-profile";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as supabaseUtils from "shared/supabase/utils";
|
||||
import * as supabaseUsers from "shared/supabase/users";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import { removePinnedUrlFromPhotoUrls } from "shared/profiles/parse-photos";
|
||||
|
||||
describe('updateProfiles', () => {
|
||||
let mockPg: any;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn(),
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
describe('should', () => {
|
||||
it('update an existing profile when provided the user id', async () => {
|
||||
const mockUserProfile = {
|
||||
user_id: '234',
|
||||
diet: 'Nothing',
|
||||
gender: 'female',
|
||||
is_smoker: true,
|
||||
}
|
||||
const mockUpdateMade = {
|
||||
gender: 'male'
|
||||
}
|
||||
const mockUpdatedProfile = {
|
||||
user_id: '234',
|
||||
diet: 'Nothing',
|
||||
gender: 'male',
|
||||
is_smoker: true,
|
||||
}
|
||||
const mockParams = {} as any;
|
||||
const mockAuth = {
|
||||
uid: '234'
|
||||
}
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
mockPg.oneOrNone.mockResolvedValue(mockUserProfile);
|
||||
(supabaseUtils.update as jest.Mock).mockResolvedValue(mockUpdatedProfile);
|
||||
describe('when given valid input', () => {
|
||||
it('should update an existing profile when provided the user id', async () => {
|
||||
const mockProps = {
|
||||
avatar_url: "mockAvatarUrl"
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockData = "success";
|
||||
|
||||
const result = await updateProfile(
|
||||
mockUpdateMade,
|
||||
mockAuth as AuthedUser,
|
||||
mockParams
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: true})
|
||||
.mockResolvedValueOnce({data: mockData, error: null});
|
||||
|
||||
const result = await updateProfile(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result).toBe(mockData);
|
||||
expect(mockPg.oneOrNone).toBeCalledTimes(1);
|
||||
expect(mockPg.oneOrNone).toBeCalledWith(
|
||||
expect.stringContaining('select * from profiles where user_id = $1'),
|
||||
[mockAuth.uid]
|
||||
);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1);
|
||||
expect(removePinnedUrlFromPhotoUrls).toBeCalledWith(mockProps);
|
||||
expect(supabaseUsers.updateUser).toBeCalledTimes(1);
|
||||
expect(supabaseUsers.updateUser).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
mockAuth.uid,
|
||||
{avatarUrl: mockProps.avatar_url}
|
||||
);
|
||||
expect(supabaseUtils.update).toBeCalledTimes(1);
|
||||
expect(supabaseUtils.update).toBeCalledWith(
|
||||
expect.any(Object),
|
||||
'profiles',
|
||||
'user_id',
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
expect(mockPg.oneOrNone.mock.calls.length).toBe(1);
|
||||
expect(mockPg.oneOrNone.mock.calls[0][1]).toEqual([mockAuth.uid]);
|
||||
expect(result).toEqual(mockUpdatedProfile);
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if the profile does not exist', async () => {
|
||||
const mockProps = {
|
||||
avatar_url: "mockAvatarUrl"
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: false});
|
||||
|
||||
expect(updateProfile(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Profile not found');
|
||||
});
|
||||
|
||||
it('throw an error if a profile is not found', async () => {
|
||||
mockPg.oneOrNone.mockResolvedValue(null);
|
||||
expect(updateProfile({} as any, {} as any, {} as any,))
|
||||
.rejects
|
||||
.toThrowError('Profile not found');
|
||||
});
|
||||
it('should throw if unable to update the profile', async () => {
|
||||
const mockProps = {
|
||||
avatar_url: "mockAvatarUrl"
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
it('throw an error if unable to update the profile', async () => {
|
||||
const mockUserProfile = {
|
||||
user_id: '234',
|
||||
diet: 'Nothing',
|
||||
gender: 'female',
|
||||
is_smoker: true,
|
||||
}
|
||||
const data = null;
|
||||
const error = true;
|
||||
const mockError = {
|
||||
data,
|
||||
error
|
||||
}
|
||||
mockPg.oneOrNone.mockResolvedValue(mockUserProfile);
|
||||
(supabaseUtils.update as jest.Mock).mockRejectedValue(mockError);
|
||||
expect(updateProfile({} as any, {} as any, {} as any,))
|
||||
(tryCatch as jest.Mock)
|
||||
.mockResolvedValueOnce({data: true})
|
||||
.mockResolvedValueOnce({data: null, error: Error});
|
||||
|
||||
expect(updateProfile(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Error updating profile');
|
||||
|
||||
.toThrow('Error updating profile');
|
||||
});
|
||||
});
|
||||
});
|
||||
101
backend/api/tests/unit/vote-unit.test.ts
Normal file
101
backend/api/tests/unit/vote-unit.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/utils');
|
||||
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { vote } from "api/vote";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as sharedUtils from "shared/utils";
|
||||
|
||||
describe('vote', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
describe('when given valid input', () => {
|
||||
it('should vote successfully', async () => {
|
||||
const mockProps = {
|
||||
voteId: 1,
|
||||
choice: 'for' as const,
|
||||
priority: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockUser = {id: "mockUserId"};
|
||||
const mockResult = "success";
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockResult);
|
||||
|
||||
const result = await vote(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(result.data).toBe(mockResult);
|
||||
expect(sharedUtils.getUser).toBeCalledTimes(1);
|
||||
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
expect.stringContaining('insert into vote_results (user_id, vote_id, choice, priority)'),
|
||||
[mockUser.id, mockProps.voteId, 1, mockProps.priority]
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('when an error occurs', () => {
|
||||
it('should throw if unable to find the account', async () => {
|
||||
const mockProps = {
|
||||
voteId: 1,
|
||||
choice: 'for' as const,
|
||||
priority: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(false);
|
||||
|
||||
expect(vote(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Your account was not found');
|
||||
});
|
||||
|
||||
it('should throw if the choice is invalid', async () => {
|
||||
const mockProps = {
|
||||
voteId: 1,
|
||||
priority: 10
|
||||
} as any;
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockUser = {id: "mockUserId"};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
|
||||
expect(vote(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Invalid choice');
|
||||
});
|
||||
|
||||
it('should throw if unable to record vote', async () => {
|
||||
const mockProps = {
|
||||
voteId: 1,
|
||||
choice: 'for' as const,
|
||||
priority: 10
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockUser = {id: "mockUserId"};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockUser);
|
||||
(mockPg.one as jest.Mock).mockRejectedValue(new Error('Result error'));
|
||||
|
||||
expect(vote(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrow('Error recording vote');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user