mirror of
https://github.com/logto-io/logto.git
synced 2025-02-10 21:58:23 -05:00
177 lines
4.4 KiB
TypeScript
177 lines
4.4 KiB
TypeScript
|
import { Applications } from '@logto/schemas';
|
||
|
import {
|
||
|
createMockPool,
|
||
|
createMockQueryResult,
|
||
|
sql,
|
||
|
QueryResultType,
|
||
|
QueryResultRowType,
|
||
|
} from 'slonik';
|
||
|
import { PrimitiveValueExpressionType } from 'slonik/dist/src/types.d';
|
||
|
import { snakeCase } from 'snake-case';
|
||
|
|
||
|
import {
|
||
|
convertToIdentifiers,
|
||
|
convertToPrimitiveOrSql,
|
||
|
excludeAutoSetFields,
|
||
|
} from '@/database/utils';
|
||
|
import { DeletionError } from '@/errors/SlonikError';
|
||
|
import { mockApplication } from '@/utils/mock';
|
||
|
import { expectSqlAssert } from '@/utils/test-utils';
|
||
|
|
||
|
import {
|
||
|
findTotalNumberOfApplications,
|
||
|
findAllApplications,
|
||
|
findApplicationById,
|
||
|
insertApplication,
|
||
|
updateApplicationById,
|
||
|
deleteApplicationById,
|
||
|
} from './application';
|
||
|
|
||
|
type MockQuery = (
|
||
|
sql: string,
|
||
|
values: PrimitiveValueExpressionType
|
||
|
) => Promise<QueryResultType<QueryResultRowType>>;
|
||
|
|
||
|
const mockQuery: jest.MockedFunction<MockQuery> = jest.fn();
|
||
|
|
||
|
jest.mock('@/database/pool', () =>
|
||
|
createMockPool({
|
||
|
query: async (sql, values) => {
|
||
|
return mockQuery(sql, values);
|
||
|
},
|
||
|
})
|
||
|
);
|
||
|
|
||
|
describe('appliaction query', () => {
|
||
|
const { table, fields } = convertToIdentifiers(Applications);
|
||
|
|
||
|
it('findTotalNumberOfApplications', async () => {
|
||
|
const expectSql = sql`
|
||
|
select count(*)
|
||
|
from ${table}
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
expectSqlAssert(sql, expectSql.sql);
|
||
|
expect(values).toEqual(expectSql.values);
|
||
|
|
||
|
return createMockQueryResult([{ count: 10 }]);
|
||
|
});
|
||
|
|
||
|
await expect(findTotalNumberOfApplications()).resolves.toEqual({ count: 10 });
|
||
|
});
|
||
|
|
||
|
it('findAllApplications', async () => {
|
||
|
const limit = 10;
|
||
|
const offset = 1;
|
||
|
const rowData = { id: 'foo' };
|
||
|
|
||
|
const expectSql = sql`
|
||
|
select ${sql.join(Object.values(fields), sql`, `)}
|
||
|
from ${table}
|
||
|
limit $1
|
||
|
offset $2
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
expectSqlAssert(sql, expectSql.sql);
|
||
|
expect(values).toEqual([limit, offset]);
|
||
|
|
||
|
return createMockQueryResult([rowData]);
|
||
|
});
|
||
|
|
||
|
await expect(findAllApplications(limit, offset)).resolves.toEqual([rowData]);
|
||
|
});
|
||
|
|
||
|
it('findApplicationById', async () => {
|
||
|
const id = 'foo';
|
||
|
const rowData = { id };
|
||
|
|
||
|
const expectSql = sql`
|
||
|
select ${sql.join(Object.values(fields), sql`, `)}
|
||
|
from ${table}
|
||
|
where ${fields.id}=$1
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
expectSqlAssert(sql, expectSql.sql);
|
||
|
expect(values).toEqual([id]);
|
||
|
|
||
|
return createMockQueryResult([rowData]);
|
||
|
});
|
||
|
|
||
|
await findApplicationById(id);
|
||
|
});
|
||
|
|
||
|
it('insertApplication', async () => {
|
||
|
const keys = excludeAutoSetFields(Applications.fieldKeys);
|
||
|
|
||
|
const expectSql = `
|
||
|
insert into "applications" (${keys.map((k) => `"${snakeCase(k)}"`).join(', ')})
|
||
|
values (${keys.map((_, index) => `$${index + 1}`).join(', ')})
|
||
|
returning *
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
const rowData = { id: 'foo' };
|
||
|
expectSqlAssert(sql, expectSql);
|
||
|
|
||
|
expect(values).toEqual(keys.map((k) => convertToPrimitiveOrSql(k, mockApplication[k])));
|
||
|
|
||
|
return createMockQueryResult([rowData]);
|
||
|
});
|
||
|
|
||
|
await insertApplication(mockApplication);
|
||
|
});
|
||
|
|
||
|
it('updateApplicationById', async () => {
|
||
|
const id = 'foo';
|
||
|
const description = 'des';
|
||
|
|
||
|
const expectSql = sql`
|
||
|
update ${table}
|
||
|
set ${fields.description}=$1
|
||
|
where ${fields.id}=$2
|
||
|
returning *
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
expectSqlAssert(sql, expectSql.sql);
|
||
|
expect(values).toEqual([description, id]);
|
||
|
|
||
|
return createMockQueryResult([{ id, description }]);
|
||
|
});
|
||
|
|
||
|
await updateApplicationById(id, { description });
|
||
|
});
|
||
|
|
||
|
it('deleteApplicationById', async () => {
|
||
|
const id = 'foo';
|
||
|
const expectSql = sql`
|
||
|
delete from ${table}
|
||
|
where ${fields.id}=$1
|
||
|
`;
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||
|
expectSqlAssert(sql, expectSql.sql);
|
||
|
expect(values).toEqual([id]);
|
||
|
|
||
|
return createMockQueryResult([{ id }]);
|
||
|
});
|
||
|
|
||
|
await deleteApplicationById(id);
|
||
|
});
|
||
|
|
||
|
it('deleteApplicationById throw error if return row count is 0', async () => {
|
||
|
const id = 'foo';
|
||
|
|
||
|
mockQuery.mockImplementationOnce(async () => {
|
||
|
return createMockQueryResult([]);
|
||
|
});
|
||
|
|
||
|
await expect(deleteApplicationById(id)).rejects.toMatchError(
|
||
|
new DeletionError(Applications.table, id)
|
||
|
);
|
||
|
});
|
||
|
});
|