Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e62ea91
setting up test structure
O-Bots Nov 7, 2025
0add06b
.
O-Bots Nov 7, 2025
ae75bdb
added playwright config file, deleted original playwright folder and …
O-Bots Nov 7, 2025
b3a6b31
continued test structure setup
O-Bots Nov 7, 2025
d91d2af
Updating test folder structure
O-Bots Nov 7, 2025
68011f8
Merge branch 'main' into main
O-Bots Nov 7, 2025
8671300
Merge branch 'CompassConnections:main' into main
O-Bots Nov 8, 2025
b13b8d4
Merge branch 'CompassConnections:main' into main
O-Bots Nov 11, 2025
266a2b4
Added database seeding script and backend testing folder structure
O-Bots Nov 11, 2025
062b6f2
Merge branch 'main' of https://github.com/O-Bots/Obots_Compass
O-Bots Nov 11, 2025
18f24e2
removed the database test
O-Bots Nov 11, 2025
c949891
Replaced db seeding script
O-Bots Nov 11, 2025
dfd5b6f
Updated userInformation.ts to use values from choices.tsx
O-Bots Nov 11, 2025
8bd9f45
merge prep
O-Bots Nov 15, 2025
834c433
Merge branch 'main' of https://github.com/O-Bots/Obots_Compass
O-Bots Nov 15, 2025
7115c22
removing extra unit test, moving api test to correct folder
O-Bots Nov 15, 2025
c039a10
Merge branch 'CompassConnections:main' into main
O-Bots Nov 15, 2025
750d7c9
Pushing to get help with sql Unit test
O-Bots Nov 17, 2025
a7f36c5
Merge branch 'main' of https://github.com/O-Bots/Obots_Compass
O-Bots Nov 17, 2025
e30eac9
Merge branch 'main' into main
O-Bots Nov 17, 2025
f3f2ebf
Updating get-profiles unit tests
O-Bots Nov 19, 2025
48ef836
Added more unit tests
O-Bots Nov 19, 2025
ea7ef9c
.
O-Bots Nov 20, 2025
443996a
Added more unit tests
O-Bots Nov 21, 2025
10f17af
Added getSupabaseToken unit test
O-Bots Nov 21, 2025
a0e48aa
.
O-Bots Nov 21, 2025
f96c122
excluding supabase token test so ci can pass
O-Bots Nov 22, 2025
2a4b002
.
O-Bots Nov 22, 2025
f9bebe3
Seperated the seedDatabase func into its own file so it can be access…
O-Bots Nov 29, 2025
4cd3327
Fixed failing test
O-Bots Nov 29, 2025
25e4d91
.
O-Bots Nov 29, 2025
6f014bb
.
O-Bots Nov 29, 2025
da0a911
Merge branch 'refs/heads/main' into fork/O-Bots/main
MartinBraquet Nov 29, 2025
d658211
Fix tests
MartinBraquet Nov 29, 2025
d76fd2a
Fix lint
MartinBraquet Nov 29, 2025
0359742
Clean
MartinBraquet Nov 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
// {
// "type": "node",
// "request": "launch",
// "name": "Launch Program",
// "skipFiles": [
// "<node_internals>/**"
// ],
// "program": "${workspaceFolder}/backend/api/tests/unit/get-profiles.unit.test.ts",
// "outFiles": [
// "${workspaceFolder}/**/*.js"
// ]
// }
]
}
2 changes: 1 addition & 1 deletion backend/api/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
project: ['./tsconfig.json', './tsconfig.test.json'],
},
rules: {
'@typescript-eslint/ban-types': [
Expand Down
3 changes: 3 additions & 0 deletions backend/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,6 @@ docker rmi -f $(docker images -aq)
### Documentation

The API doc is available at https://api.compassmeet.com. It's dynamically prepared in [app.ts](src/app.ts).

### Todo (Tests)
- [ ] Finish get-supabase-token unit test when endpoint is implemented
24 changes: 12 additions & 12 deletions backend/api/src/get-profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@ export type profileQueryType = {
after?: string | undefined,
// Search and filter parameters
name?: string | undefined,
genders?: String[] | undefined,
education_levels?: String[] | undefined,
pref_gender?: String[] | undefined,
genders?: string[] | undefined,
education_levels?: string[] | undefined,
pref_gender?: string[] | undefined,
pref_age_min?: number | undefined,
pref_age_max?: number | undefined,
drinks_min?: number | undefined,
drinks_max?: number | undefined,
pref_relation_styles?: String[] | undefined,
pref_romantic_styles?: String[] | undefined,
diet?: String[] | undefined,
political_beliefs?: String[] | undefined,
mbti?: String[] | undefined,
relationship_status?: String[] | undefined,
languages?: String[] | undefined,
religion?: String[] | undefined,
pref_relation_styles?: string[] | undefined,
pref_romantic_styles?: string[] | undefined,
diet?: string[] | undefined,
political_beliefs?: string[] | undefined,
mbti?: string[] | undefined,
relationship_status?: string[] | undefined,
languages?: string[] | undefined,
religion?: string[] | undefined,
wants_kids_strength?: number | undefined,
has_kids?: number | undefined,
is_smoker?: boolean | undefined,
shortBio?: boolean | undefined,
geodbCityIds?: String[] | undefined,
geodbCityIds?: string[] | undefined,
lat?: number | undefined,
lon?: number | undefined,
radius?: number | undefined,
Expand Down
3 changes: 1 addition & 2 deletions backend/api/src/get-user.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { toUserAPIResponse } from 'common/api/user-types'
import { convertUser, displayUserColumns } from 'common/supabase/users'
import { convertUser } from 'common/supabase/users'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { APIError } from 'common/api/utils'
import { removeNullOrUndefinedProps } from 'common/util/object'

export const getUser = async (props: { id: string } | { username: string }) => {
const pg = createSupabaseDirectClient()
Expand Down
2 changes: 1 addition & 1 deletion backend/api/src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const report: APIHandler<'report'> = async (body, auth) => {
console.error('Failed to get reported user for report', userError)
return
}
let message: string = `
const message: string = `
🚨 **New Report** 🚨
**Type:** ${contentType}
**Content ID:** ${contentId}
Expand Down
115 changes: 115 additions & 0 deletions backend/api/tests/unit/ban-user.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
jest.mock('shared/supabase/init')
jest.mock('shared/helpers/auth')
jest.mock('common/envs/constants')
jest.mock('shared/supabase/users')
jest.mock('shared/analytics')
jest.mock('shared/utils')

import { banUser } from "api/ban-user";
import * as supabaseInit from "shared/supabase/init";
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"


describe('banUser', () => {
const mockPg = {} as any;

beforeEach(() => {
jest.resetAllMocks();

(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg);
});

afterEach(() => {
jest.restoreAllMocks();
});

describe('should', () => {
it('ban a user successfully', async () => {
const mockUser = {
userId: '123',
unban: false
};
const mockAuth = {uid: '321'} as AuthedUser;
const mockReq = {} as any;

(constants.isAdminId as jest.Mock).mockReturnValue(false);

await banUser(mockUser, mockAuth, mockReq);

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: true});
});

it('unban a user successfully', async () => {
const mockUser = {
userId: '123',
unban: true
};
const mockAuth = {uid: '321'} as AuthedUser;
const mockReq = {} as any;

(constants.isAdminId as jest.Mock).mockReturnValue(false);

await banUser(mockUser, mockAuth, mockReq);

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});
});

it('throw and error if the ban requester is not a mod or admin', async () => {
const mockUser = {
userId: '123',
unban: false
};
const mockAuth = {uid: '321'} as AuthedUser;
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.`
)
);

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 () => {
const mockUser = {
userId: '123',
unban: false
};
const mockAuth = {uid: '321'} as AuthedUser;
const mockReq = {} as any;

(constants.isAdminId as jest.Mock).mockReturnValue(true);

await expect(banUser(mockUser, mockAuth, mockReq))
.rejects
.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);
});
});
});
119 changes: 119 additions & 0 deletions backend/api/tests/unit/block-user.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
jest.mock('shared/supabase/init')
jest.mock('shared/supabase/users')
jest.mock('shared/supabase/utils')

import * as blockUserModule from "api/block-user";
import { AuthedUser } from "api/helpers/endpoint";
import * as supabaseInit from "shared/supabase/init";
import * as supabaseUsers from "shared/supabase/users";
import * as supabaseUtils from "shared/supabase/utils";

describe('blockUser', () => {
let mockPg: any;

beforeEach(() => {
jest.resetAllMocks()
mockPg = {
tx: jest.fn(async (cb) => {
const mockTx = {};
await cb(mockTx);
}),
};

(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg)
});

afterEach(() => {
jest.restoreAllMocks();
});

describe('should', () => {
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)}
);
});

it('throw an error if the user tries to block themselves', async () => {
const mockParams = { id: '123' }
const mockAuth = {uid: '123'} as AuthedUser;
const mockReq = {} as any;

expect(blockUserModule.blockUser(mockParams, mockAuth, mockReq))
.rejects
.toThrowError('You cannot block yourself')

expect(mockPg.tx).toHaveBeenCalledTimes(0)
});
});

});

describe('unblockUser', () => {
let mockPg: any;

beforeEach(() => {
jest.resetAllMocks()
mockPg = {
tx: jest.fn(async (cb) => {
const mockTx = {};
await cb(mockTx);
}),
};

(supabaseInit.createSupabaseDirectClient as jest.Mock)
.mockReturnValue(mockPg)
});

afterEach(() => {
jest.restoreAllMocks();
});

describe('should', () => {
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.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)}
);
});
});

});
32 changes: 32 additions & 0 deletions backend/api/tests/unit/compatible-profiles.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as supabaseInit from "shared/supabase/init";
import {getCompatibleProfiles} from "api/compatible-profiles";

jest.mock('shared/supabase/init')

describe('getCompatibleProfiles', () => {
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;
(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}});
});

});
});
Loading