Refactor unit tests to use sqlMatch for SQL query assertions

This commit is contained in:
MartinBraquet
2026-02-17 22:37:32 +01:00
parent 07ce2780c6
commit fc6628be08
32 changed files with 431 additions and 390 deletions

View File

@@ -32,7 +32,7 @@ export const updateMe: APIHandler<'me/update'> = async (props, auth) => {
const pg = createSupabaseDirectClient()
const { name, username, avatarUrl, link = {}, ...rest } = update
const {name, username, avatarUrl, link = {}, ...rest} = update
await updateUser(pg, auth.uid, removeUndefinedProps(rest))
const stripped = mapValues(
@@ -53,14 +53,14 @@ export const updateMe: APIHandler<'me/update'> = async (props, auth) => {
let newLinks: any = null
if (Object.keys(adds).length > 0 || removes.length > 0) {
const data = await pg.oneOrNone(
`update users
set data = jsonb_set(
data, '{link}',
(data->'link' || $(adds)) - $(removes)
)
where id = $(id)
returning data->'link' as link`,
{ adds, removes, id: auth.uid }
`update users
set data = jsonb_set(
data, '{link}',
(data -> 'link' || $(adds)) - $(removes)
)
where id = $(id)
returning data -> 'link' as link`,
{adds, removes, id: auth.uid}
)
newLinks = data?.link
}
@@ -73,10 +73,7 @@ export const updateMe: APIHandler<'me/update'> = async (props, auth) => {
if (username) {
await pg.none(`update users
set username = $1
where id = $2`, [
username,
auth.uid,
])
where id = $2`, [username, auth.uid])
}
if (avatarUrl) {
await updateUser(pg, auth.uid, {avatarUrl})
@@ -96,5 +93,5 @@ export const updateMe: APIHandler<'me/update'> = async (props, auth) => {
)
}
return toUserAPIResponse({ ...user, ...update, link: newLinks })
return toUserAPIResponse({...user, ...update, link: newLinks})
}

View File

@@ -3,167 +3,169 @@ jest.mock('shared/supabase/utils');
jest.mock('shared/supabase/init');
jest.mock('common/util/try-catch');
import { contact } from "api/contact";
import {contact} from "api/contact";
import * as supabaseInit from "shared/supabase/init";
import * as supabaseUtils from "shared/supabase/utils";
import { tryCatch } from "common/util/try-catch";
import { sendDiscordMessage } from "common/discord/core";
import { AuthedUser } from "api/helpers/endpoint";
import {tryCatch} from "common/util/try-catch";
import {sendDiscordMessage} from "common/discord/core";
import {AuthedUser} from "api/helpers/endpoint";
import {sqlMatch} from 'common/test-utils'
describe('contact', () => {
let mockPg: any;
beforeEach(() => {
jest.resetAllMocks();
mockPg = {
oneOrNone: jest.fn(),
};
let mockPg: any;
beforeEach(() => {
jest.resetAllMocks();
mockPg = {
oneOrNone: jest.fn(),
};
(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg);
});
afterEach(() => {
jest.restoreAllMocks();
});
(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('when given valid input', () => {
it('should send a discord message to the user', 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(
expect.any(Object),
'contact',
describe('when given valid input', () => {
it('should send a discord message to the user', async () => {
const mockProps = {
content: {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
user_id: mockProps.userId,
content: JSON.stringify(mockProps.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;
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockDbUser);
(tryCatch as jest.Mock).mockResolvedValue({data: mockReturnData, error: null});
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'
);
});
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(
expect.any(Object),
'contact',
{
user_id: mockProps.userId,
content: JSON.stringify(mockProps.content)
}
);
(mockPg.oneOrNone as jest.Mock).mockResolvedValue(mockDbUser);
await results.continue();
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
sqlMatch('select name from users where id = $1'),
[mockProps.userId]
);
expect(sendDiscordMessage).toBeCalledTimes(1);
expect(sendDiscordMessage).toBeCalledWith(
expect.stringContaining(`New message from ${mockDbUser.name}`),
'contact'
);
});
describe('when an error occurs', () => {
it('should throw if the insert function fails', 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;
});
(tryCatch as jest.Mock).mockResolvedValue({ data: null, error: Error });
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(
expect.any(Object),
'contact',
describe('when an error occurs', () => {
it('should throw if the insert function fails', async () => {
const mockProps = {
content: {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
user_id: mockProps.userId,
content: JSON.stringify(mockProps.content)
type: 'text',
text: 'Error test message'
}
);
]
}
]
},
userId: '123'
};
const mockAuth = {uid: '321'} as AuthedUser;
const mockReq = {} as any;
(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(() => {});
(tryCatch as jest.Mock).mockResolvedValue({data: null, error: Error});
await results.continue();
expect(errorSpy).toBeCalledTimes(1);
expect(errorSpy).toBeCalledWith(
expect.stringContaining('Failed to send discord contact'),
expect.objectContaining({name: 'Error'})
);
});
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(
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'})
);
});
});
});

View File

@@ -1,50 +1,51 @@
jest.mock('shared/supabase/init');
import { createBookmarkedSearch } from "api/create-bookmarked-search";
import { AuthedUser } from "api/helpers/endpoint";
import {sqlMatch} from "common/test-utils";
import {createBookmarkedSearch} from "api/create-bookmarked-search";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
jest.mock('shared/supabase/init');
describe('createBookmarkedSearch', () => {
let mockPg: any;
beforeEach(() => {
jest.resetAllMocks();
mockPg = {
one: jest.fn(),
};
let mockPg: 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 insert a bookmarked search into the database', async () => {
const mockProps = {
search_filters: 'mock_search_filters',
location: 'mock_location',
search_name: 'mock_search_name'
};
const mockAuth = { uid: '321' } as AuthedUser;
const mockReq = {} as any;
const mockInserted = "mockInsertedReturn";
(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'),
[
mockAuth.uid,
mockProps.search_filters,
mockProps.location,
mockProps.search_name
]
);
});
(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg);
});
afterEach(() => {
jest.restoreAllMocks();
});
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',
search_name: 'mock_search_name'
};
const mockAuth = {uid: '321'} as AuthedUser;
const mockReq = {} as any;
const mockInserted = "mockInsertedReturn";
(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(
sqlMatch('INSERT INTO bookmarked_searches'),
[
mockAuth.uid,
mockProps.search_filters,
mockProps.location,
mockProps.search_name
]
);
});
});
});

View File

@@ -1,3 +1,15 @@
import {sqlMatch} from "common/test-utils";
import * as supabaseInit from "shared/supabase/init";
import {AuthedUser} from "api/helpers/endpoint";
import * as sharedUtils from "shared/utils";
import {createComment} from "api/create-comment";
import * as notificationPrefs from "common/user-notification-preferences";
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";
jest.mock('shared/supabase/init');
jest.mock('shared/supabase/notifications');
jest.mock('email/functions/helpers');
@@ -6,17 +18,6 @@ jest.mock('shared/utils');
jest.mock('common/user-notification-preferences');
jest.mock('shared/websockets/helpers');
import * as supabaseInit from "shared/supabase/init";
import { AuthedUser } from "api/helpers/endpoint";
import * as sharedUtils from "shared/utils";
import { createComment } from "api/create-comment";
import * as notificationPrefs from "common/user-notification-preferences";
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(() => {
@@ -102,7 +103,7 @@ describe('createComment', () => {
expect(sharedUtils.getPrivateUser).toHaveBeenNthCalledWith(2, mockOnUser.id);
expect(mockPg.one).toBeCalledTimes(1);
expect(mockPg.one).toBeCalledWith(
expect.stringContaining('insert into profile_comments'),
sqlMatch('insert into profile_comments'),
[
mockCreator.id,
mockCreator.name,

View File

@@ -1,11 +1,4 @@
jest.mock('shared/supabase/init');
jest.mock('common/util/array');
jest.mock('api/helpers/private-messages');
jest.mock('shared/utils');
jest.mock('firebase-admin', () => ({
auth: jest.fn()
}));
import {sqlMatch} from "common/test-utils";
import {createPrivateUserMessageChannel} from "api/create-private-user-message-channel";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
@@ -14,6 +7,14 @@ import * as privateMessageModules from "api/helpers/private-messages";
import * as admin from 'firebase-admin';
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('common/util/array');
jest.mock('api/helpers/private-messages');
jest.mock('shared/utils');
jest.mock('firebase-admin', () => ({
auth: jest.fn()
}));
describe('createPrivateUserMessageChannel', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -77,7 +78,7 @@ describe('createPrivateUserMessageChannel', () => {
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[1]);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select channel_id\n from private_user_message_channel_members'),
sqlMatch('select channel_id\n from private_user_message_channel_members'),
[mockUserIds]
);
});
@@ -124,11 +125,11 @@ describe('createPrivateUserMessageChannel', () => {
expect(sharedUtils.getPrivateUser).toBeCalledWith(mockUserIds[1]);
expect(mockPg.one).toBeCalledTimes(1);
expect(mockPg.one).toBeCalledWith(
expect.stringContaining('insert into private_user_message_channels default\n values\n returning id')
sqlMatch('insert into private_user_message_channels default\n values\n 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)'),
sqlMatch('insert into private_user_message_channel_members (channel_id, user_id, role, status)'),
[mockChannel.id, mockAuth.uid]
);
expect(privateMessageModules.addUsersToPrivateMessageChannel).toBeCalledTimes(1);

View File

@@ -8,16 +8,17 @@ jest.mock('shared/analytics');
jest.mock('common/discord/core');
jest.mock('common/util/time');
import { createProfile } from "api/create-profile";
import {createProfile} from "api/create-profile";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
import * as supabaseUsers from "shared/supabase/users";
import * as supabaseUtils from "shared/supabase/utils";
import { tryCatch } from "common/util/try-catch";
import { removePinnedUrlFromPhotoUrls } from "shared/profiles/parse-photos";
import {tryCatch} from "common/util/try-catch";
import {removePinnedUrlFromPhotoUrls} from "shared/profiles/parse-photos";
import * as sharedAnalytics from "shared/analytics";
import { sendDiscordMessage } from "common/discord/core";
import { AuthedUser } from "api/helpers/endpoint";
import {sendDiscordMessage} from "common/discord/core";
import {AuthedUser} from "api/helpers/endpoint";
import {sqlMatch} from 'common/test-utils'
describe('createProfile', () => {
let mockPg = {} as any;
@@ -71,7 +72,7 @@ describe('createProfile', () => {
expect(tryCatch).toBeCalledTimes(2);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select id from profiles where user_id = $1'),
sqlMatch('select id from profiles where user_id = $1'),
[mockAuth.uid]
);
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1);
@@ -147,7 +148,7 @@ describe('createProfile', () => {
expect(mockPg.one).toBeCalledTimes(1);
expect(mockPg.one).toBeCalledWith(
expect.stringContaining('SELECT count(*) FROM profiles'),
sqlMatch('SELECT count(*) FROM profiles'),
[],
expect.any(Function)
);

View File

@@ -1,9 +1,10 @@
jest.mock('shared/supabase/init');
import { deleteBookmarkedSearch } from "api/delete-bookmarked-search";
import { AuthedUser } from "api/helpers/endpoint";
import {sqlMatch} from "common/test-utils";
import {deleteBookmarkedSearch} from "api/delete-bookmarked-search";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
jest.mock('shared/supabase/init');
describe('deleteBookmarkedSearch', () => {
let mockPg = {} as any;
@@ -32,7 +33,7 @@ describe('deleteBookmarkedSearch', () => {
expect(result).toStrictEqual({});
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('DELETE FROM bookmarked_searches'),
sqlMatch('DELETE FROM bookmarked_searches'),
[
mockProps.id,
mockAuth.uid

View File

@@ -1,3 +1,11 @@
import {sqlMatch} from "common/test-utils";
import {deleteMe} from "api/delete-me";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
import * as firebaseAdmin from "firebase-admin";
import * as firebaseUtils from "shared/firebase-utils";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('shared/utils');
jest.mock('firebase-admin', () => ({
@@ -5,13 +13,6 @@ jest.mock('firebase-admin', () => ({
}));
jest.mock('shared/firebase-utils');
import { deleteMe } from "api/delete-me";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
import * as firebaseAdmin from "firebase-admin";
import * as firebaseUtils from "shared/firebase-utils";
import { AuthedUser } from "api/helpers/endpoint";
describe('deleteMe', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -50,7 +51,7 @@ describe('deleteMe', () => {
expect(sharedUtils.getUser).toBeCalledWith(mockAuth.uid);
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('DELETE FROM users WHERE id = $1'),
sqlMatch('DELETE FROM users WHERE id = $1'),
[mockUser.id]
);
expect(firebaseUtils.deleteUserFiles).toBeCalledTimes(1);

View File

@@ -1,11 +1,12 @@
import {sqlMatch} from "common/test-utils";
import {getCurrentPrivateUser} from "api/get-current-private-user";
import * as supabaseInit from "shared/supabase/init";
import {tryCatch} from "common/util/try-catch";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('common/util/try-catch');
import { getCurrentPrivateUser } from "api/get-current-private-user";
import * as supabaseInit from "shared/supabase/init";
import { tryCatch } from "common/util/try-catch";
import { AuthedUser } from "api/helpers/endpoint";
describe('getCurrentPrivateUser', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -36,7 +37,7 @@ describe('getCurrentPrivateUser', () => {
expect(result).toBe(mockData.data);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select * from private_users where id = $1'),
sqlMatch('select * from private_users where id = $1'),
[mockAuth.uid]
);
});

View File

@@ -1,9 +1,10 @@
jest.mock('shared/supabase/init');
import { getMessagesCount } from "api/get-messages-count";
import { AuthedUser } from "api/helpers/endpoint";
import {sqlMatch} from "common/test-utils";
import {getMessagesCount} from "api/get-messages-count";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
jest.mock('shared/supabase/init');
describe('getMessagesCount', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -32,7 +33,7 @@ describe('getMessagesCount', () => {
expect(result.count).toBe(Number(mockResults.count));
expect(mockPg.one).toBeCalledTimes(1);
expect(mockPg.one).toBeCalledWith(
expect.stringContaining('SELECT COUNT(*) AS count'),
sqlMatch('SELECT COUNT(*) AS count'),
expect.any(Object)
);
});

View File

@@ -1,8 +1,9 @@
jest.mock('shared/supabase/init');
import { getNotifications } from "api/get-notifications";
import { AuthedUser } from "api/helpers/endpoint";
import {getNotifications} from "api/get-notifications";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
import {sqlMatch} from 'common/test-utils'
describe('getNotifications', () => {
let mockPg = {} as any;
@@ -35,7 +36,7 @@ describe('getNotifications', () => {
expect(result).toBe(mockNotifications);
expect(mockPg.map).toBeCalledTimes(1);
expect(mockPg.map).toBeCalledWith(
expect.stringContaining('select data from user_notifications'),
sqlMatch('select data from user_notifications'),
[mockAuth.uid, mockProps.limit, mockProps.after],
expect.any(Function)
);

View File

@@ -1,12 +1,13 @@
import {sqlMatch} from "common/test-utils";
import * as getPrivateMessages from "api/get-private-messages";
import * as supabaseInit from "shared/supabase/init";
import {tryCatch} from "common/util/try-catch";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('common/util/try-catch');
jest.mock('shared/supabase/messages');
import * as getPrivateMessages from "api/get-private-messages";
import * as supabaseInit from "shared/supabase/init";
import { tryCatch } from "common/util/try-catch";
import { AuthedUser } from "api/helpers/endpoint";
describe('getChannelMemberships', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -58,13 +59,13 @@ describe('getChannelMemberships', () => {
expect(mockPg.map).toBeCalledTimes(2);
expect(mockPg.map).toHaveBeenNthCalledWith(
1,
expect.stringContaining('select channel_id, notify_after_time, pumcm.created_time, last_updated_time'),
sqlMatch('select channel_id, notify_after_time, pumcm.created_time, last_updated_time'),
[mockAuth.uid, mockProps.channelId, mockProps.limit],
expect.any(Function)
);
expect(mockPg.map).toHaveBeenNthCalledWith(
2,
expect.stringContaining('select channel_id, user_id'),
sqlMatch('select channel_id, user_id'),
[mockAuth.uid, [mockChannels[0].channel_id]],
expect.any(Function)
);
@@ -105,13 +106,13 @@ describe('getChannelMemberships', () => {
expect(mockPg.map).toBeCalledTimes(2);
expect(mockPg.map).toHaveBeenNthCalledWith(
1,
expect.stringContaining('with latest_channels as (select distinct on (pumc.id) pumc.id as channel_id'),
sqlMatch('with latest_channels as (select distinct on (pumc.id) pumc.id as channel_id'),
[mockAuth.uid, mockProps.createdTime, mockProps.limit, mockProps.lastUpdatedTime],
expect.any(Function)
);
expect(mockPg.map).toHaveBeenNthCalledWith(
2,
expect.stringContaining('select channel_id, user_id'),
sqlMatch('select channel_id, user_id'),
[mockAuth.uid, [mockChannels[0].channel_id]],
expect.any(Function)
);
@@ -138,7 +139,7 @@ describe('getChannelMemberships', () => {
expect(mockPg.map).toBeCalledTimes(1);
expect(mockPg.map).toHaveBeenNthCalledWith(
1,
expect.stringContaining('select channel_id, notify_after_time, pumcm.created_time, last_updated_time'),
sqlMatch('select channel_id, notify_after_time, pumcm.created_time, last_updated_time'),
[mockAuth.uid, mockProps.channelId, mockProps.limit],
expect.any(Function)
);
@@ -179,7 +180,7 @@ describe('getChannelMessagesEndpoint', () => {
expect(result).toBe(mockData);
expect(mockPg.map).toBeCalledTimes(1);
expect(mockPg.map).toBeCalledWith(
expect.stringContaining('select *, created_time as created_time_ts'),
sqlMatch('select *, created_time as created_time_ts'),
[mockProps.channelId, mockAuth.uid, mockProps.limit, mockProps.id],
expect.any(Function)
);
@@ -244,7 +245,7 @@ describe('getLastSeenChannelTime', () => {
expect(result).toBe(mockUnseens);
expect(mockPg.map).toBeCalledTimes(1);
expect(mockPg.map).toBeCalledWith(
expect.stringContaining('select distinct on (channel_id) channel_id, created_time'),
sqlMatch('select distinct on (channel_id) channel_id, created_time'),
[mockProps.channelIds, mockAuth.uid],
expect.any(Function)
);
@@ -281,7 +282,7 @@ describe('setChannelLastSeenTime', () => {
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('insert into private_user_seen_message_channels (user_id, channel_id)'),
sqlMatch('insert into private_user_seen_message_channels (user_id, channel_id)'),
[mockAuth.uid, mockProps.channelId]
);
});

View File

@@ -1,9 +1,10 @@
jest.mock('shared/supabase/init');
import { getProfileAnswers } from "api/get-profile-answers";
import { AuthedUser } from "api/helpers/endpoint";
import {sqlMatch} from "common/test-utils";
import {getProfileAnswers} from "api/get-profile-answers";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
jest.mock('shared/supabase/init');
describe('getProfileAnswers', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -45,7 +46,7 @@ describe('getProfileAnswers', () => {
expect(result.answers).toBe(mockAnswers);
expect(mockPg.manyOrNone).toBeCalledTimes(1);
expect(mockPg.manyOrNone).toBeCalledWith(
expect.stringContaining('select * from compatibility_answers'),
sqlMatch('select * from compatibility_answers'),
[mockProps.userId]
);
});

View File

@@ -1,11 +1,12 @@
import {sqlMatch} from "common/test-utils";
import {getUser} from "api/get-user";
import * as supabaseInit from "shared/supabase/init";
import {toUserAPIResponse} from "common/api/user-types";
jest.mock("shared/supabase/init");
jest.mock("common/supabase/users");
jest.mock("common/api/user-types");
import { getUser } from "api/get-user";
import * as supabaseInit from "shared/supabase/init";
import { toUserAPIResponse } from "common/api/user-types";
describe('getUser', () =>{
let mockPg: any;
@@ -36,7 +37,7 @@ describe('getUser', () =>{
expect(result).toBe('mockApiResponse');
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select * from users'),
sqlMatch('select * from users'),
[mockProps.id],
expect.any(Function)
);
@@ -55,7 +56,7 @@ describe('getUser', () =>{
await getUser(mockProps)
expect(mockPg.oneOrNone).toHaveBeenCalledWith(
expect.stringContaining('where username = $1'),
sqlMatch('where username = $1'),
[mockProps.username],
expect.any(Function)
);

View File

@@ -1,14 +1,15 @@
import {sqlMatch} from "common/test-utils";
import {hideComment} from "api/hide-comment";
import * as supabaseInit from "shared/supabase/init";
import * as envConsts from "common/envs/constants";
import {convertComment} from "common/supabase/comment";
import * as websocketHelpers from "shared/websockets/helpers";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('common/supabase/comment');
jest.mock('shared/websockets/helpers');
import { hideComment } from "api/hide-comment";
import * as supabaseInit from "shared/supabase/init";
import * as envConsts from "common/envs/constants";
import { convertComment } from "common/supabase/comment";
import * as websocketHelpers from "shared/websockets/helpers";
import { AuthedUser } from "api/helpers/endpoint";
describe('hideComment', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -55,7 +56,7 @@ describe('hideComment', () => {
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select * from profile_comments where id = $1'),
sqlMatch('select * from profile_comments where id = $1'),
[mockProps.commentId]
);
expect(envConsts.isAdminId).toBeCalledTimes(1);

View File

@@ -2,11 +2,12 @@ jest.mock('shared/supabase/init');
jest.mock('shared/utils');
jest.mock('api/helpers/private-messages');
import { leavePrivateUserMessageChannel } from "api/leave-private-user-message-channel";
import {leavePrivateUserMessageChannel} from "api/leave-private-user-message-channel";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
import * as messageHelpers from "api/helpers/private-messages";
import { AuthedUser } from "api/helpers/endpoint";
import {AuthedUser} from "api/helpers/endpoint";
import {sqlMatch} from 'common/test-utils'
describe('leavePrivateUserMessageChannel', () => {
let mockPg = {} as any;
@@ -43,12 +44,12 @@ describe('leavePrivateUserMessageChannel', () => {
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'),
sqlMatch('select status from private_user_message_channel_members'),
[mockProps.channelId, mockAuth.uid]
);
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('update private_user_message_channel_members'),
sqlMatch('update private_user_message_channel_members'),
[mockProps.channelId, mockAuth.uid]
);
expect(messageHelpers.leaveChatContent).toBeCalledTimes(1);

View File

@@ -1,15 +1,16 @@
import {sqlMatch} from "common/test-utils";
import {likeProfile} from "api/like-profile";
import * as supabaseInit from "shared/supabase/init";
import * as profileNotifiction from "shared/create-profile-notification";
import * as likeModules from "api/has-free-like";
import {tryCatch} from "common/util/try-catch";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('shared/create-profile-notification');
jest.mock('api/has-free-like');
jest.mock('common/util/try-catch');
import { likeProfile } from "api/like-profile";
import * as supabaseInit from "shared/supabase/init";
import * as profileNotifiction from "shared/create-profile-notification";
import * as likeModules from "api/has-free-like";
import { tryCatch } from "common/util/try-catch";
import { AuthedUser } from "api/helpers/endpoint";
describe('likeProfile', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -51,13 +52,13 @@ describe('likeProfile', () => {
expect(result.result.status).toBe('success');
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select * from profile_likes where creator_id = $1 and target_id = $2'),
sqlMatch('select * from profile_likes where creator_id = $1 and target_id = $2'),
[mockAuth.uid, mockProps.targetUserId]
);
expect(tryCatch).toBeCalledTimes(2);
expect(mockPg.one).toBeCalledTimes(1);
expect(mockPg.one).toBeCalledWith(
expect.stringContaining('insert into profile_likes (creator_id, target_id) values ($1, $2) returning *'),
sqlMatch('insert into profile_likes (creator_id, target_id) values ($1, $2) returning *'),
[mockAuth.uid, mockProps.targetUserId]
);
@@ -105,7 +106,7 @@ describe('likeProfile', () => {
expect(result.status).toBe('success');
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('delete from profile_likes where creator_id = $1 and target_id = $2'),
sqlMatch('delete from profile_likes where creator_id = $1 and target_id = $2'),
[mockAuth.uid, mockProps.targetUserId]
);
});

View File

@@ -1,8 +1,9 @@
jest.mock('shared/supabase/init');
import { markAllNotifsRead } from "api/mark-all-notifications-read";
import { AuthedUser } from "api/helpers/endpoint";
import {markAllNotifsRead} from "api/mark-all-notifications-read";
import {AuthedUser} from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
import {sqlMatch} from 'common/test-utils'
describe('markAllNotifsRead', () => {
let mockPg = {} as any;
@@ -29,7 +30,7 @@ describe('markAllNotifsRead', () => {
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('update user_notifications'),
sqlMatch('update user_notifications'),
[mockAuth.uid]
);
});

View File

@@ -1,10 +1,11 @@
jest.mock('shared/supabase/init');
jest.mock('api/helpers/private-messages');
import { reactToMessage } from "api/react-to-message";
import {sqlMatch} from "common/test-utils";
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";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('api/helpers/private-messages');
describe('reactToMessage', () => {
let mockPg = {} as any;
@@ -45,18 +46,18 @@ describe('reactToMessage', () => {
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(params).toEqual([mockAuth.uid, mockProps.messageId])
expect(sql).toEqual(
expect.stringContaining('SELECT *')
sqlMatch('SELECT *')
);
expect(sql).toEqual(
expect.stringContaining('FROM private_user_message_channel_members m')
sqlMatch('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')
sqlMatch('UPDATE private_user_messages')
);
expect(sql1).toEqual(
expect.stringContaining('SET reactions =')
sqlMatch('SET reactions =')
);
expect(messageHelpers.broadcastPrivateMessages).toBeCalledTimes(1);
expect(messageHelpers.broadcastPrivateMessages).toBeCalledWith(
@@ -89,10 +90,10 @@ describe('reactToMessage', () => {
expect(mockPg.none).toBeCalledTimes(1);
expect(params1).toEqual([mockProps.reaction, mockProps.messageId, mockAuth.uid])
expect(sql1).toEqual(
expect.stringContaining('UPDATE private_user_messages')
sqlMatch('UPDATE private_user_messages')
);
expect(sql1).toEqual(
expect.stringContaining('SET reactions = reactions - $1')
sqlMatch('SET reactions = reactions - $1')
);
});
});

View File

@@ -2,11 +2,12 @@ jest.mock('shared/supabase/init');
jest.mock('common/envs/constants');
jest.mock('common/util/try-catch');
import { removePinnedPhoto } from "api/remove-pinned-photo";
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";
import {tryCatch} from "common/util/try-catch";
import {AuthedUser} from "api/helpers/endpoint";
import {sqlMatch} from 'common/test-utils'
describe('removePinnedPhoto', () => {
let mockPg = {} as any;
@@ -40,7 +41,7 @@ describe('removePinnedPhoto', () => {
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'),
sqlMatch('update profiles set pinned_url = null where user_id = $1'),
[mockBody.userId]
);
});

View File

@@ -1,15 +1,16 @@
import {sqlMatch} from "common/test-utils";
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";
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(() => {
@@ -72,12 +73,12 @@ describe('report', () => {
expect(mockPg.oneOrNone).toBeCalledTimes(2);
expect(mockPg.oneOrNone).toHaveBeenNthCalledWith(
1,
expect.stringContaining('select * from users where id = $1'),
sqlMatch('select * from users where id = $1'),
[mockAuth.uid]
);
expect(mockPg.oneOrNone).toHaveBeenNthCalledWith(
2,
expect.stringContaining('select * from users where id = $1'),
sqlMatch('select * from users where id = $1'),
[mockBody.contentOwnerId]
);
expect(sendDiscordMessage).toBeCalledTimes(1);

View File

@@ -1,9 +1,10 @@
jest.mock('shared/supabase/init');
import { AuthedUser } from "api/helpers/endpoint";
import { saveSubscriptionMobile } from "api/save-subscription-mobile";
import {sqlMatch} from "common/test-utils";
import {AuthedUser} from "api/helpers/endpoint";
import {saveSubscriptionMobile} from "api/save-subscription-mobile";
import * as supabaseInit from "shared/supabase/init";
jest.mock('shared/supabase/init');
describe('saveSubscriptionMobile', () => {
let mockPg = {} as any;
beforeEach(() => {
@@ -32,7 +33,7 @@ describe('saveSubscriptionMobile', () => {
expect(result.success).toBeTruthy();
expect(mockPg.none).toBeCalledTimes(1);
expect(mockPg.none).toBeCalledWith(
expect.stringContaining('insert into push_subscriptions_mobile(token, platform, user_id)'),
sqlMatch('insert into push_subscriptions_mobile(token, platform, user_id)'),
[mockBody.token, 'android', mockAuth.uid]
);
});

View File

@@ -1,8 +1,9 @@
jest.mock('shared/supabase/init');
import { AuthedUser } from "api/helpers/endpoint";
import { saveSubscription } from "api/save-subscription";
import {AuthedUser} from "api/helpers/endpoint";
import {saveSubscription} from "api/save-subscription";
import * as supabaseInit from "shared/supabase/init";
import {sqlMatch} from 'common/test-utils'
describe('saveSubscription', () => {
let mockPg = {} as any;
@@ -40,12 +41,12 @@ describe('saveSubscription', () => {
expect(result.success).toBeTruthy();
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select id from push_subscriptions where endpoint = $1'),
sqlMatch('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'),
sqlMatch('update push_subscriptions set keys = $1, user_id = $2 where id = $3'),
[mockBody.subscription.keys, mockAuth.uid, mockExists.id]
);
});
@@ -68,12 +69,12 @@ describe('saveSubscription', () => {
expect(result.success).toBeTruthy();
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select id from push_subscriptions where endpoint = $1'),
sqlMatch('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)'),
sqlMatch('insert into push_subscriptions(endpoint, keys, user_id) values($1, $2, $3)'),
[mockBody.subscription.endpoint, mockBody.subscription.keys, mockAuth.uid]
);
});

View File

@@ -1,17 +1,18 @@
import {sqlMatch} from "common/test-utils";
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";
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(() => {
@@ -76,12 +77,12 @@ describe('searchUsers', () => {
expect(sqlBuilderModules.from).toBeCalledWith('users');
expect(sqlBuilderModules.where).toBeCalledTimes(1);
expect(sqlBuilderModules.where).toBeCalledWith(
expect.stringContaining("name_username_vector @@ websearch_to_tsquery('english', $1)"),
sqlMatch("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,"),
sqlMatch("ts_rank(name_username_vector, websearch_to_tsquery($1)) desc,"),
[mockProps.term]
);
expect(sqlBuilderModules.limit).toBeCalledTimes(1);

View File

@@ -3,12 +3,13 @@ jest.mock('common/util/try-catch');
jest.mock('shared/supabase/utils');
jest.mock('shared/create-profile-notification');
import { shipProfiles } from "api/ship-profiles";
import {shipProfiles} from "api/ship-profiles";
import * as supabaseInit from "shared/supabase/init";
import { tryCatch } from "common/util/try-catch";
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";
import {AuthedUser} from "api/helpers/endpoint";
import {sqlMatch} from 'common/test-utils'
describe('shipProfiles', () => {
let mockPg = {} as any;
@@ -49,7 +50,7 @@ describe('shipProfiles', () => {
expect(tryCatch).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select ship_id from profile_ships'),
sqlMatch('select ship_id from profile_ships'),
[mockAuth.uid, mockProps.targetUserId1, mockProps.targetUserId2]
);
});
@@ -79,12 +80,12 @@ describe('shipProfiles', () => {
expect(tryCatch).toBeCalledTimes(2);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select ship_id from profile_ships'),
sqlMatch('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'),
sqlMatch('delete from profile_ships where ship_id = $1'),
[mockExisting.data.ship_id]
);
});
@@ -121,7 +122,7 @@ describe('shipProfiles', () => {
expect(tryCatch).toBeCalledTimes(2);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select ship_id from profile_ships'),
sqlMatch('select ship_id from profile_ships'),
[mockAuth.uid, mockProps.targetUserId1, mockProps.targetUserId2]
);
expect(supabaseUtils.insert).toBeCalledTimes(1);

View File

@@ -1,13 +1,14 @@
import {sqlMatch} from "common/test-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";
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(() => {
@@ -45,7 +46,7 @@ describe('startProfile', () => {
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'),
sqlMatch('select * from profile_stars where creator_id = $1 and target_id = $2'),
[mockAuth.uid, mockProps.targetUserId]
);
expect(supabaseUtils.insert).toBeCalledTimes(1);
@@ -101,7 +102,7 @@ describe('startProfile', () => {
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'),
sqlMatch('delete from profile_stars where creator_id = $1 and target_id = $2'),
[mockAuth.uid, mockProps.targetUserId]
);
});

View File

@@ -18,6 +18,7 @@ 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";
import {sqlMatch} from 'common/test-utils'
describe('updateMe', () => {
let mockPg = {} as any;
@@ -114,12 +115,16 @@ describe('updateMe', () => {
expect(mockPg.none).toBeCalledTimes(2);
expect(mockPg.none).toHaveBeenNthCalledWith(
1,
expect.stringContaining(`update users set name = $1 where id = $2`),
sqlMatch(`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`),
sqlMatch(`update users
set username = $1
where id = $2`),
[mockUpdate.username, mockAuth.uid]
);
expect(objectUtils.removeUndefinedProps).toBeCalledTimes(2);

View File

@@ -1,11 +1,12 @@
jest.mock('common/util/try-catch');
jest.mock('shared/supabase/init');
import {sqlMatch} from "common/test-utils";
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";
jest.mock('common/util/try-catch');
jest.mock('shared/supabase/init');
describe('updateOptions', () => {
let mockPg = {} as any;
let mockTx = {} as any;
@@ -64,30 +65,33 @@ describe('updateOptions', () => {
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'),
sqlMatch('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)`),
sqlMatch(`INSERT INTO ${mockProps.table} (name, creator_id)`),
[mockProps.values[0], mockAuth.uid]
);
expect(mockTx.one).toHaveBeenNthCalledWith(
2,
expect.stringContaining(`INSERT INTO ${mockProps.table} (name, creator_id)`),
sqlMatch(`INSERT INTO ${mockProps.table} (name, creator_id)`),
[mockProps.values[1], mockAuth.uid]
);
expect(mockTx.none).toBeCalledTimes(2);
expect(mockTx.none).toHaveBeenNthCalledWith(
1,
expect.stringContaining(`DELETE FROM profile_${mockProps.table} WHERE profile_id = $1`),
sqlMatch(`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`),
sqlMatch(`INSERT INTO profile_${mockProps.table} (profile_id, option_id)
VALUES`),
[mockProfileIdResult.id, mockRow1.id, mockRow2.id]
);
});

View File

@@ -1,12 +1,13 @@
jest.mock('shared/supabase/init');
jest.mock('shared/utils');
jest.mock('common/supabase/utils');
import {sqlMatch} from "common/test-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";
import {AuthedUser} from "api/helpers/endpoint";
jest.mock('shared/supabase/init');
jest.mock('shared/utils');
jest.mock('common/supabase/utils');
describe('updatePrivateUserMessageChannel', () => {
let mockPg = {} as any;
@@ -45,12 +46,12 @@ describe('updatePrivateUserMessageChannel', () => {
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'),
sqlMatch('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'),
sqlMatch('update private_user_message_channel_members'),
[mockBody.channelId, mockAuth.uid, 'mockMillisToTs']
);
});

View File

@@ -11,6 +11,7 @@ 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";
import {sqlMatch} from 'common/test-utils'
describe('updateProfiles', () => {
let mockPg: any;
@@ -45,7 +46,7 @@ describe('updateProfiles', () => {
expect(result).toBe(mockData);
expect(mockPg.oneOrNone).toBeCalledTimes(1);
expect(mockPg.oneOrNone).toBeCalledWith(
expect.stringContaining('select * from profiles where user_id = $1'),
sqlMatch('select * from profiles where user_id = $1'),
[mockAuth.uid]
);
expect(removePinnedUrlFromPhotoUrls).toBeCalledTimes(1);

View File

@@ -1,10 +1,11 @@
jest.mock('shared/supabase/init');
jest.mock('shared/utils');
import { AuthedUser } from "api/helpers/endpoint";
import { vote } from "api/vote";
import {AuthedUser} from "api/helpers/endpoint";
import {vote} from "api/vote";
import * as supabaseInit from "shared/supabase/init";
import * as sharedUtils from "shared/utils";
import {sqlMatch} from 'common/test-utils'
describe('vote', () => {
let mockPg = {} as any;
@@ -42,7 +43,7 @@ describe('vote', () => {
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)'),
sqlMatch('insert into vote_results (user_id, vote_id, choice, priority)'),
[mockUser.id, mockProps.voteId, 1, mockProps.priority]
);
});

6
common/src/test-utils.ts Normal file
View File

@@ -0,0 +1,6 @@
export function sqlMatch(sql: string) {
// Normalize: collapse all whitespace to single spaces, trim
// Then build a regex that tolerates any whitespace or line break in the real SQL.
const escaped = sql.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').trim()
return expect.stringMatching(new RegExp(escaped.replace(/\s+/g, '\\s+')))
}