mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat: add DELETE /connectors/:id (#2478)
This commit is contained in:
parent
a5c6fc41b4
commit
536a8d7e82
4 changed files with 86 additions and 2 deletions
|
@ -4,12 +4,14 @@ import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
|||
|
||||
import { mockConnector } from '@/__mocks__';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
import type { QueryType } from '@/utils/test-utils';
|
||||
import { expectSqlAssert } from '@/utils/test-utils';
|
||||
|
||||
import {
|
||||
findAllConnectors,
|
||||
countConnectorByConnectorId,
|
||||
deleteConnectorById,
|
||||
insertConnector,
|
||||
updateConnector,
|
||||
} from './connector';
|
||||
|
@ -64,6 +66,43 @@ describe('connector queries', () => {
|
|||
await expect(countConnectorByConnectorId(rowData.connectorId)).resolves.toEqual(rowData);
|
||||
});
|
||||
|
||||
it('deleteConnectorById', async () => {
|
||||
const rowData = { id: 'foo' };
|
||||
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([rowData]);
|
||||
});
|
||||
|
||||
await deleteConnectorById(id);
|
||||
});
|
||||
|
||||
it('deleteConnectorById should throw with zero response', 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([]);
|
||||
});
|
||||
|
||||
await expect(deleteConnectorById(id)).rejects.toMatchError(
|
||||
new DeletionError(Connectors.table, id)
|
||||
);
|
||||
});
|
||||
|
||||
it('insertConnector', async () => {
|
||||
const connector = {
|
||||
...mockConnector,
|
||||
|
|
|
@ -6,6 +6,7 @@ import { sql } from 'slonik';
|
|||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Connectors);
|
||||
|
||||
|
@ -25,6 +26,17 @@ export const countConnectorByConnectorId = async (connectorId: string) =>
|
|||
where ${fields.connectorId}=${connectorId}
|
||||
`);
|
||||
|
||||
export const deleteConnectorById = async (id: string) => {
|
||||
const { rowCount } = await envSet.pool.query(sql`
|
||||
delete from ${table}
|
||||
where ${fields.id}=${id}
|
||||
`);
|
||||
|
||||
if (rowCount < 1) {
|
||||
throw new DeletionError(Connectors.table, id);
|
||||
}
|
||||
};
|
||||
|
||||
export const insertConnector = buildInsertInto<CreateConnector, Connector>(Connectors, {
|
||||
returning: true,
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { defaultConnectorMethods } from '@/connectors/consts';
|
||||
import type { VirtualConnector, LogtoConnector } from '@/connectors/types';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { countConnectorByConnectorId } from '@/queries/connector';
|
||||
import { countConnectorByConnectorId, deleteConnectorById } from '@/queries/connector';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
import { createRequester } from '@/utils/test-utils';
|
||||
|
||||
|
@ -27,6 +27,7 @@ const getLogtoConnectorsPlaceHolder = jest.fn() as jest.MockedFunction<
|
|||
|
||||
jest.mock('@/queries/connector', () => ({
|
||||
countConnectorByConnectorId: jest.fn(),
|
||||
deleteConnectorById: jest.fn(),
|
||||
insertConnector: jest.fn(async (body: unknown) => body),
|
||||
}));
|
||||
|
||||
|
@ -274,4 +275,15 @@ describe('connector route', () => {
|
|||
expect(response).toHaveProperty('statusCode', 400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /connectors/:id', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('delete connector instance', async () => {
|
||||
await connectorRequest.delete('/connectors/id').send({});
|
||||
expect(deleteConnectorById).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,12 @@ import type { LogtoConnector } from '@/connectors/types';
|
|||
import RequestError from '@/errors/RequestError';
|
||||
import { removeUnavailableSocialConnectorTargets } from '@/lib/sign-in-experience';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { countConnectorByConnectorId, insertConnector, updateConnector } from '@/queries/connector';
|
||||
import {
|
||||
countConnectorByConnectorId,
|
||||
deleteConnectorById,
|
||||
insertConnector,
|
||||
updateConnector,
|
||||
} from '@/queries/connector';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
||||
import type { AuthedRouter } from './types';
|
||||
|
@ -255,4 +260,20 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
|
|||
return next();
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
'/connectors/:id',
|
||||
koaGuard({ params: object({ id: string().min(1) }) }),
|
||||
async (ctx, next) => {
|
||||
const {
|
||||
params: { id },
|
||||
} = ctx.guard;
|
||||
|
||||
await deleteConnectorById(id);
|
||||
|
||||
ctx.status = 204;
|
||||
|
||||
return next();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue