mirror of
https://github.com/CompassConnections/Compass.git
synced 2025-12-23 22:18:43 -05:00
Add API unit tests for create-* endpoints (#23)
* setting up test structure * . * added playwright config file, deleted original playwright folder and moved "some.test" file * continued test structure setup * Updating test folder structure * Added database seeding script and backend testing folder structure * removed the database test * Replaced db seeding script * Updated userInformation.ts to use values from choices.tsx * merge prep * removing extra unit test, moving api test to correct folder * Pushing to get help with sql Unit test * Updating get-profiles unit tests * Added more unit tests * . * Added more unit tests * Added getSupabaseToken unit test * . * excluding supabase token test so ci can pass * . * Seperated the seedDatabase func into its own file so it can be accessed seperatly * Fixed failing test * . * . * Fix tests * Fix lint * Clean * Fixed module paths in compute-score unit test * Updated root tsconfig to recognise backend/shared * Added create comment unit test * Added some unit tests * Working on createProfile return issue * . * Fixes --------- Co-authored-by: MartinBraquet <martin.braquet@gmail.com>
This commit is contained in:
committed by
GitHub
parent
be2e19db8d
commit
28ce878b34
@@ -15,7 +15,7 @@ module.exports = {
|
||||
"^email/(.*)$": "<rootDir>/../email/emails/$1"
|
||||
},
|
||||
|
||||
moduleFileExtensions: ["ts", "js", "json"],
|
||||
moduleFileExtensions: ["tsx","ts", "js", "json"],
|
||||
clearMocks: true,
|
||||
|
||||
globals: {
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/supabase/notifications');
|
||||
jest.mock('email/functions/helpers');
|
||||
jest.mock('common/supabase/comment');
|
||||
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";
|
||||
|
||||
describe('createComment', () => {
|
||||
let mockPg: any;
|
||||
@@ -14,6 +27,12 @@ describe('createComment', () => {
|
||||
|
||||
(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(() => {
|
||||
@@ -22,13 +41,17 @@ describe('createComment', () => {
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a comment with information provided', async () => {
|
||||
const mockUserId = {userId: '123'}
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
}
|
||||
const mockOnUser = {id: '123'}
|
||||
const mockCreator = {
|
||||
id: '123',
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl'
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: false
|
||||
}
|
||||
const mockContent = {
|
||||
content: {
|
||||
@@ -48,9 +71,307 @@ describe('createComment', () => {
|
||||
userId: '123'
|
||||
};
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockComment = {id: 12};
|
||||
const mockNotificationDestination = {} as any;
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator)
|
||||
.mockResolvedValueOnce(mockOnUser);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockUserId)
|
||||
.mockResolvedValueOnce(mockOnUser);
|
||||
(mockPg.one as jest.Mock).mockResolvedValue(mockComment);
|
||||
(notificationPrefs.getNotificationDestinationsForUser as jest.Mock)
|
||||
.mockReturnValue(mockNotificationDestination);
|
||||
|
||||
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.getPrivateUser).toBeCalledTimes(2);
|
||||
expect(mockPg.one).toBeCalledTimes(1);
|
||||
expect(mockPg.one).toBeCalledWith(
|
||||
expect.stringContaining('insert into profile_comments'),
|
||||
expect.arrayContaining([mockCreator.id])
|
||||
);
|
||||
expect(websocketHelpers.broadcastUpdatedComment).toBeCalledTimes(1)
|
||||
|
||||
});
|
||||
|
||||
it('throw an error if there is no user matching the userId', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
};
|
||||
const mockCreator = {
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This is the comment text'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator)
|
||||
.mockResolvedValueOnce(null);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserId);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('User not found');
|
||||
});
|
||||
|
||||
it('throw an error if there is no account associated with the authId', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This is the comment text'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(null);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('Your account was not found');
|
||||
});
|
||||
|
||||
it('throw an error if the account is banned from posting', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
};
|
||||
const mockCreator = {
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: true
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This is the comment text'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('You are banned');
|
||||
});
|
||||
|
||||
it('throw an error if the other user is not found', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
};
|
||||
const mockCreator = {
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This is the comment text'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('Other user not found');
|
||||
});
|
||||
|
||||
it('throw an error if the user has blocked you', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['321']
|
||||
};
|
||||
const mockCreator = {
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This is the comment text'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValueOnce(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserId);
|
||||
|
||||
expect(createComment( mockProps, mockAuth, mockReq )).rejects.toThrowError('User has blocked you');
|
||||
});
|
||||
|
||||
it('throw an error if the comment is too long', async () => {
|
||||
const mockAuth = { uid: '321' } as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockReplyToCommentId = {} as any;
|
||||
const mockUserId = {
|
||||
userId: '123',
|
||||
blockedUserIds: ['111']
|
||||
};
|
||||
const mockCreator = {
|
||||
id: '1234',
|
||||
name: 'Mock Creator',
|
||||
username: 'mock.creator.username',
|
||||
avatarUrl: 'mock.creator.avatarurl',
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
const mockContent = {
|
||||
content: {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'This '.repeat(30000),
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
userId: '123'
|
||||
};
|
||||
const mockProps = {
|
||||
userId: mockUserId.userId,
|
||||
content: mockContent.content,
|
||||
replyToCommentId: mockReplyToCommentId
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.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');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/utils');
|
||||
jest.mock('shared/supabase/utils');
|
||||
jest.mock('common/util/try-catch');
|
||||
|
||||
import { createCompatibilityQuestion } from "api/create-compatibility-question";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as shareUtils from "shared/utils";
|
||||
import { tryCatch } from "common/util/try-catch";
|
||||
import * as supabaseUtils from "shared/supabase/utils";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('createCompatibilityQuestion', () => {
|
||||
const mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
describe('should', () => {
|
||||
it('successfully create compatibility questions', 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;
|
||||
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:mockData, error: null});
|
||||
|
||||
const results = await createCompatibilityQuestion(mockProps, mockAuth, mockReq);
|
||||
|
||||
expect(results.question).toEqual(mockData);
|
||||
|
||||
});
|
||||
|
||||
it('throws an error 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);
|
||||
|
||||
expect(createCompatibilityQuestion(mockProps, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found')
|
||||
|
||||
});
|
||||
|
||||
it('throws an error if unable to create the question', 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;
|
||||
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')
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
98
backend/api/tests/unit/create-notification.unit.test.ts
Normal file
98
backend/api/tests/unit/create-notification.unit.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/supabase/notifications');
|
||||
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as createNotificationModules from "api/create-notification";
|
||||
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', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
const 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 () => {
|
||||
const mockUsers = [
|
||||
{
|
||||
created_time: "mockCreatedTime",
|
||||
data: {"mockData": "mockDataJson"},
|
||||
id: "mockId",
|
||||
name: "mockName",
|
||||
name_user_vector: "mockNUV",
|
||||
username: "mockUsername"
|
||||
},
|
||||
];
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockUsers, error:null});
|
||||
(supabaseNotifications.insertNotificationToSupabase as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
const results = await createNotificationModules.createNotifications(mockNotification as Notification);
|
||||
expect(results?.success).toBeTruthy;
|
||||
});
|
||||
|
||||
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"
|
||||
},
|
||||
];
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValue({data: mockUsers, error:Error});
|
||||
|
||||
await createNotificationModules.createNotifications(mockNotification as Notification)
|
||||
expect(errorSpy).toHaveBeenCalledWith('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"
|
||||
},
|
||||
];
|
||||
const mockNotification = {
|
||||
userId: "mockUserId"
|
||||
} as MockNotificationUser;
|
||||
|
||||
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')
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,229 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('common/util/array');
|
||||
jest.mock('api/helpers/private-messages');
|
||||
jest.mock('shared/utils');
|
||||
|
||||
import { createPrivateUserMessageChannel } from "api/create-private-user-message-channel";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as sharedUtils from "shared/utils";
|
||||
import * as utilArrayModules from "common/util/array";
|
||||
import * as privateMessageModules from "api/helpers/private-messages";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('createPrivateUserMessageChannel', () => {
|
||||
let mockPg = {} as any;
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn(),
|
||||
one: jest.fn(),
|
||||
none: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a private user message channel (currentChannel)', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['123', '321'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
{
|
||||
id: '321',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
];
|
||||
const mockCurrentChannel = {
|
||||
channel_id: "444"
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
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);
|
||||
|
||||
const results = await createPrivateUserMessageChannel(mockBody, mockAuth, mockReq);
|
||||
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)
|
||||
|
||||
});
|
||||
|
||||
it('successfully create a private user message channel (channel)', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['123', '321'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
{
|
||||
id: '321',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
];
|
||||
const mockChannel = {
|
||||
id: "333"
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
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);
|
||||
|
||||
const results = await createPrivateUserMessageChannel(mockBody, mockAuth, mockReq);
|
||||
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)
|
||||
|
||||
});
|
||||
|
||||
it('throw an error 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);
|
||||
|
||||
expect(createPrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('Your account was not found');
|
||||
});
|
||||
|
||||
it('throw an error if the authId is banned from posting', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
isBannedFromPosting: true
|
||||
};
|
||||
|
||||
(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 () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['123'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
];
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
|
||||
expect(createPrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`Private user ${mockAuth.uid} not found`);
|
||||
});
|
||||
|
||||
it('throw an error if there is a blocked user in the userId list', async () => {
|
||||
const mockBody = {
|
||||
userIds: ["123"]
|
||||
};
|
||||
const mockUserIds = ['321'];
|
||||
const mockPrivateUsers = [
|
||||
{
|
||||
id: '123',
|
||||
blockedUserIds: ['111'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
{
|
||||
id: '321',
|
||||
blockedUserIds: ['123'],
|
||||
blockedByUserIds: [],
|
||||
},
|
||||
];
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock)
|
||||
.mockResolvedValue(mockCreator);
|
||||
(sharedUtils.getPrivateUser as jest.Mock)
|
||||
.mockResolvedValue(mockUserIds);
|
||||
(utilArrayModules.filterDefined as jest.Mock)
|
||||
.mockReturnValue(mockPrivateUsers);
|
||||
|
||||
expect(createPrivateUserMessageChannel(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`One of the users has blocked another user in the list`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
jest.mock('shared/utils');
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('api/helpers/private-messages');
|
||||
|
||||
import { createPrivateUserMessage } from "api/create-private-user-message";
|
||||
import * as sharedUtils from "shared/utils";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as helpersPrivateMessagesModules from "api/helpers/private-messages";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
import { MAX_COMMENT_JSON_LENGTH } from "api/create-comment";
|
||||
|
||||
describe('createPrivateUserMessage', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
const mockPg = {} as any;
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a private user message', async () => {
|
||||
const mockBody = {
|
||||
content: {"": "x".repeat((MAX_COMMENT_JSON_LENGTH-8))},
|
||||
channelId: 123
|
||||
};
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
isBannedFromPosting: false
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
(helpersPrivateMessagesModules.createPrivateUserMessageMain as jest.Mock)
|
||||
.mockResolvedValue(null);
|
||||
|
||||
await createPrivateUserMessage(mockBody, mockAuth, mockReq);
|
||||
expect(helpersPrivateMessagesModules.createPrivateUserMessageMain).toBeCalledWith(
|
||||
mockCreator,
|
||||
mockBody.channelId,
|
||||
mockBody.content,
|
||||
expect.any(Object),
|
||||
'private'
|
||||
);
|
||||
});
|
||||
|
||||
it('throw an error if the content is too long', async () => {
|
||||
const mockBody = {
|
||||
content: {"": "x".repeat((MAX_COMMENT_JSON_LENGTH))},
|
||||
channelId: 123
|
||||
}
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
expect(createPrivateUserMessage(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`Message JSON should be less than ${MAX_COMMENT_JSON_LENGTH}`);
|
||||
});
|
||||
|
||||
it('throw an error if the user does not exist', async () => {
|
||||
const mockBody = {
|
||||
content: {"mockJson": "mockJsonContent"},
|
||||
channelId: 123
|
||||
}
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
expect(createPrivateUserMessage(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`Your account was not found`);
|
||||
});
|
||||
|
||||
it('throw an error if the user does not exist', async () => {
|
||||
const mockBody = {
|
||||
content: {"mockJson": "mockJsonContent"},
|
||||
channelId: 123
|
||||
}
|
||||
const mockAuth = {uid: '321'} as AuthedUser;
|
||||
const mockReq = {} as any;
|
||||
const mockCreator = {
|
||||
isBannedFromPosting: true
|
||||
};
|
||||
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(mockCreator);
|
||||
|
||||
expect(createPrivateUserMessage(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError(`You are banned`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
160
backend/api/tests/unit/create-profile.unit.test.ts
Normal file
160
backend/api/tests/unit/create-profile.unit.test.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
jest.mock('shared/supabase/init');
|
||||
jest.mock('shared/utils');
|
||||
jest.mock('shared/profiles/parse-photos');
|
||||
jest.mock('shared/supabase/users');
|
||||
jest.mock('shared/supabase/utils');
|
||||
jest.mock('common/util/try-catch');
|
||||
jest.mock('shared/analytics');
|
||||
jest.mock('common/discord/core');
|
||||
|
||||
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 * as sharedAnalytics from "shared/analytics";
|
||||
import { sendDiscordMessage } from "common/discord/core";
|
||||
import { AuthedUser } from "api/helpers/endpoint";
|
||||
|
||||
describe('createProfile', () => {
|
||||
let mockPg = {} as any;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockPg = {
|
||||
oneOrNone: jest.fn().mockReturnValue(null),
|
||||
one: jest.fn()
|
||||
};
|
||||
|
||||
(supabaseInit.createSupabaseDirectClient as jest.Mock)
|
||||
.mockReturnValue(mockPg);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('should', () => {
|
||||
it('successfully create a 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 mockExistingUser = {id: "mockExistingUserId"};
|
||||
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});
|
||||
(sharedAnalytics.track as jest.Mock).mockResolvedValue(null);
|
||||
(sendDiscordMessage as jest.Mock).mockResolvedValueOnce(null);
|
||||
(mockPg.one as jest.Mock).mockReturnValue(10);
|
||||
|
||||
const results: any = await createProfile(mockBody, mockAuth, mockReq);
|
||||
expect(results.result).toEqual(mockData)
|
||||
});
|
||||
|
||||
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});
|
||||
|
||||
await expect(createProfile(mockBody, mockAuth, mockReq))
|
||||
.rejects
|
||||
.toThrowError('User already exists');
|
||||
});
|
||||
|
||||
it('throws an error if the user 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;
|
||||
|
||||
(tryCatch as jest.Mock).mockResolvedValueOnce({data: null, error: null});
|
||||
(sharedUtils.getUser as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
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 () => {
|
||||
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 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: 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
7
backend/api/tests/unit/create-user.unit.test.ts
Normal file
7
backend/api/tests/unit/create-user.unit.test.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
describe('createUser', () => {
|
||||
describe('should', () => {
|
||||
it('', async () => {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -13,5 +13,10 @@
|
||||
"email/*": ["../email/emails/*"]
|
||||
}
|
||||
},
|
||||
"include": ["tests/**/*.ts", "src/**/*.ts"]
|
||||
"include": [
|
||||
"tests/**/*.ts",
|
||||
"src/**/*.ts",
|
||||
"../shared/src/**/*.ts",
|
||||
"../../common/src/**/*.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ module.exports = {
|
||||
],
|
||||
|
||||
moduleNameMapper: {
|
||||
"^api/(.*)$": "<rootDir>/src/$1",
|
||||
"^shared/(.*)$": "<rootDir>/../shared/src/$1",
|
||||
"^api/(.*)$": "<rootDir>/../api/src/$1",
|
||||
"^shared/(.*)$": "<rootDir>/src/$1",
|
||||
"^common/(.*)$": "<rootDir>/../../common/src/$1",
|
||||
"^email/(.*)$": "<rootDir>/../email/emails/$1"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {recomputeCompatibilityScoresForUser} from "api/compatibility/compute-scores";
|
||||
import {recomputeCompatibilityScoresForUser} from "shared/compatibility/compute-scores";
|
||||
import * as supabaseInit from "shared/supabase/init";
|
||||
import * as profilesSupabaseModules from "shared/profiles/supabase";
|
||||
import * as compatibilityScoreModules from "common/profiles/compatibility-score";
|
||||
|
||||
@@ -15,10 +15,23 @@
|
||||
"lib": ["esnext"],
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"common/*": ["../../common/src/*", "../../../common/lib/*"],
|
||||
"shared/*": ["./src/*"]
|
||||
"common/*": ["../../common/src/*",
|
||||
"../../../common/lib/*"
|
||||
],
|
||||
"shared/*": [
|
||||
"./src/*"
|
||||
],
|
||||
}
|
||||
},
|
||||
"references": [{ "path": "../../common" }],
|
||||
"ts-node": {
|
||||
"require": [
|
||||
"tsconfig-paths/register"
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../../common"
|
||||
},
|
||||
],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
"rootDir": "../..",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"api/*": ["src/*"],
|
||||
"shared/*": ["../shared/src/*"],
|
||||
"api/*": ["../api/src/*"],
|
||||
"shared/*": ["src/*"],
|
||||
"common/*": ["../../common/src/*"],
|
||||
"email/*": ["../email/emails/*"]
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./backend/api" },
|
||||
{ "path": "./backend/api/tsconfig.test.json" }
|
||||
{ "path": "./backend/api/tsconfig.test.json" },
|
||||
{ "path": "./backend/shared" },
|
||||
{ "path": "./backend/shared/tsconfig.test.json" }
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user