diff --git a/packages/console/src/pages/ConnectorDetails/components/SenderTester/index.tsx b/packages/console/src/pages/ConnectorDetails/components/SenderTester/index.tsx index dd29ae73e..c58849add 100644 --- a/packages/console/src/pages/ConnectorDetails/components/SenderTester/index.tsx +++ b/packages/console/src/pages/ConnectorDetails/components/SenderTester/index.tsx @@ -14,6 +14,7 @@ import useApi from '@/hooks/use-api'; import * as styles from './index.module.scss'; type Props = { + connectorId: string; connectorType: Exclude; config?: string; className?: string; @@ -23,7 +24,7 @@ type FormData = { sendTo: string; }; -const SenderTester = ({ connectorType, config, className }: Props) => { +const SenderTester = ({ connectorId, connectorType, config, className }: Props) => { const buttonPosReference = useRef(null); const [showTooltip, setShowTooltip] = useState(false); const [isSubmitting, seIsSubmitting] = useState(false); @@ -62,7 +63,7 @@ const SenderTester = ({ connectorType, config, className }: Props) => { try { await api - .post(`/api/connectors/test/${connectorType.toLowerCase()}`, { + .post(`/api/connectors/${connectorId}/test`, { json: data, }) .json(); diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx index 21e120801..b94f7377c 100644 --- a/packages/console/src/pages/ConnectorDetails/index.tsx +++ b/packages/console/src/pages/ConnectorDetails/index.tsx @@ -213,7 +213,7 @@ const ConnectorDetails = () => { /> {data.type !== ConnectorType.Social && ( - + )} {saveError &&
{saveError}
} diff --git a/packages/console/src/pages/Connectors/components/Guide/index.tsx b/packages/console/src/pages/Connectors/components/Guide/index.tsx index 220668e67..81f6de1bd 100644 --- a/packages/console/src/pages/Connectors/components/Guide/index.tsx +++ b/packages/console/src/pages/Connectors/components/Guide/index.tsx @@ -120,6 +120,7 @@ const Guide = ({ connector, onClose }: Props) => { {!isSocialConnector && ( diff --git a/packages/core/src/routes/connector.test.ts b/packages/core/src/routes/connector.test.ts index c96e343f6..d3189e237 100644 --- a/packages/core/src/routes/connector.test.ts +++ b/packages/core/src/routes/connector.test.ts @@ -101,51 +101,7 @@ describe('connector route', () => { }); }); - describe('POST /connectors/test/email', () => { - afterEach(() => { - jest.clearAllMocks(); - }); - - it('should get email connector and send message', async () => { - const mockedEmailConnector: EmailConnectorInstance = { - connector: mockConnector, - metadata: mockMetadata, - validateConfig: jest.fn(), - getConfig: jest.fn(), - sendMessage: async ( - address: string, - type: keyof EmailMessageTypes, - _payload: EmailMessageTypes[typeof type] - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): Promise => {}, - }; - getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedEmailConnector]); - const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendMessage'); - const response = await connectorRequest - .post('/connectors/test/email') - .send({ email: 'test@email.com', config: { test: 123 } }); - expect(sendMessageSpy).toHaveBeenCalledTimes(1); - expect(sendMessageSpy).toHaveBeenCalledWith( - 'test@email.com', - 'Test', - { - code: 'email-test', - }, - { test: 123 } - ); - expect(response).toHaveProperty('statusCode', 204); - }); - - it('should throw when email connector is not found', async () => { - getConnectorInstancesPlaceHolder.mockResolvedValueOnce([]); - const response = await connectorRequest - .post('/connectors/test/email') - .send({ email: 'test@email.com' }); - expect(response).toHaveProperty('statusCode', 400); - }); - }); - - describe('POST /connectors/test/sms', () => { + describe('POST /connectors/:id/test', () => { afterEach(() => { jest.clearAllMocks(); }); @@ -170,7 +126,7 @@ describe('connector route', () => { getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedSmsConnectorInstance]); const sendMessageSpy = jest.spyOn(mockedSmsConnectorInstance, 'sendMessage'); const response = await connectorRequest - .post('/connectors/test/sms') + .post('/connectors/id/test') .send({ phone: '12345678901', config: { test: 123 } }); expect(sendMessageSpy).toHaveBeenCalledTimes(1); expect(sendMessageSpy).toHaveBeenCalledWith( @@ -184,12 +140,55 @@ describe('connector route', () => { expect(response).toHaveProperty('statusCode', 204); }); + it('should get email connector and send message', async () => { + const mockedEmailConnector: EmailConnectorInstance = { + connector: mockConnector, + metadata: mockMetadata, + validateConfig: jest.fn(), + getConfig: jest.fn(), + sendMessage: async ( + address: string, + type: keyof EmailMessageTypes, + _payload: EmailMessageTypes[typeof type] + // eslint-disable-next-line @typescript-eslint/no-empty-function + ): Promise => {}, + }; + getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedEmailConnector]); + const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendMessage'); + const response = await connectorRequest + .post('/connectors/id/test') + .send({ email: 'test@email.com', config: { test: 123 } }); + expect(sendMessageSpy).toHaveBeenCalledTimes(1); + expect(sendMessageSpy).toHaveBeenCalledWith( + 'test@email.com', + 'Test', + { + code: 'email-test', + }, + { test: 123 } + ); + expect(response).toHaveProperty('statusCode', 204); + }); + + it('should throw when neither phone nor email is provided', async () => { + const response = await connectorRequest.post('/connectors/id/test').send({}); + expect(response).toHaveProperty('statusCode', 400); + }); + it('should throw when sms connector is not found', async () => { getConnectorInstancesPlaceHolder.mockResolvedValueOnce([]); const response = await connectorRequest - .post('/connectors/test/sms') + .post('/connectors/id/test') .send({ phone: '12345678901' }); expect(response).toHaveProperty('statusCode', 400); }); + + it('should throw when email connector is not found', async () => { + getConnectorInstancesPlaceHolder.mockResolvedValueOnce([]); + const response = await connectorRequest + .post('/connectors/id/test') + .send({ email: 'test@email.com' }); + expect(response).toHaveProperty('statusCode', 400); + }); }); }); diff --git a/packages/core/src/routes/connector.ts b/packages/core/src/routes/connector.ts index 46ac14043..1049d7e1b 100644 --- a/packages/core/src/routes/connector.ts +++ b/packages/core/src/routes/connector.ts @@ -149,25 +149,42 @@ export default function connectorRoutes(router: T) { ); router.post( - '/connectors/test/email', + '/connectors/:id/test', koaGuard({ + params: object({ id: string().min(1) }), body: object({ - email: string().regex(emailRegEx), + phone: string().regex(phoneRegEx).optional(), + email: string().regex(emailRegEx).optional(), config: arbitraryObjectGuard.optional(), }), }), async (ctx, next) => { - const { email, config } = ctx.guard.body; + const { + params: { id }, + body, + } = ctx.guard; + const { phone, email, config } = body; const connectorInstances = await getConnectorInstances(); - const connector = connectorInstances.find( - (connector): connector is EmailConnectorInstance => - connector.metadata.type === ConnectorType.Email - ); + const subject = phone ?? email; + assertThat(subject, new RequestError({ code: 'guard.invalid_input' })); + + const connector: SmsConnectorInstance | EmailConnectorInstance | undefined = phone + ? connectorInstances.find( + (connector): connector is SmsConnectorInstance => + connector.metadata.id === id && connector.metadata.type === ConnectorType.SMS + ) + : connectorInstances.find( + (connector): connector is EmailConnectorInstance => + connector.metadata.id === id && connector.metadata.type === ConnectorType.Email + ); assertThat( connector, - new RequestError({ code: 'connector.not_found', type: ConnectorType.Email }) + new RequestError({ + code: 'connector.not_found', + type: phone ? ConnectorType.SMS : ConnectorType.Email, + }) ); if (config) { @@ -175,47 +192,10 @@ export default function connectorRoutes(router: T) { } await connector.sendMessage( - email, + subject, 'Test', { - code: 'email-test', - }, - config - ); - - ctx.status = 204; - - return next(); - } - ); - - router.post( - '/connectors/test/sms', - koaGuard({ - body: object({ - phone: string().regex(phoneRegEx), - config: arbitraryObjectGuard.optional(), - }), - }), - async (ctx, next) => { - const { phone, config } = ctx.guard.body; - - const connectorInstances = await getConnectorInstances(); - const connector = connectorInstances.find( - (connector): connector is SmsConnectorInstance => - connector.metadata.type === ConnectorType.SMS - ); - - assertThat( - connector, - new RequestError({ code: 'connector.not_found', type: ConnectorType.SMS }) - ); - - await connector.sendMessage( - phone, - 'Test', - { - code: '123456', + code: phone ? '123456' : 'email-test', }, config );