-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from mollie/feature/MOL-401
Feature/mol 401
- Loading branch information
Showing
15 changed files
with
487 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { logger } from '../utils/logger.utils'; | ||
import { Request, Response } from 'express'; | ||
import CustomError from '../errors/custom.error'; | ||
import { apiError } from '../api/error.api'; | ||
import { formatErrorResponse } from '../errors/mollie.error'; | ||
import { createExtensionAndCustomFields, removeExtension } from '../service/connector.service'; | ||
import { getProfile } from '../mollie/profile.mollie'; | ||
|
||
export const healthCheck = async (request: Request, response: Response) => { | ||
try { | ||
logger.debug('SCTM - healthCheck - The connector is running healthily.'); | ||
return response.status(200).json('The connector is running healthily.'); | ||
} catch (error) { | ||
logger.error('SCTM - healthCheck - Unexpected error occurred when processing request', error); | ||
return apiError(response, formatErrorResponse(error).errors); | ||
} | ||
}; | ||
|
||
export const mollieStatus = async (request: Request, response: Response) => { | ||
try { | ||
logger.debug('SCTM - mollieStatus - Checking Mollie API status.'); | ||
const profile = await getProfile(); | ||
logger.debug('SCTM - mollieStatus - Mollie API status is functioning.'); | ||
return response.status(200).json({ | ||
mode: profile.mode, | ||
name: profile.name, | ||
website: profile.website, | ||
status: profile.status, | ||
}); | ||
} catch (error) { | ||
logger.error('SCTM - healthCheck - Unexpected error occurred when processing request', error); | ||
return response.status(400).json(error).send(); | ||
} | ||
}; | ||
|
||
export const install = async (request: Request, response: Response) => { | ||
const { extensionUrl } = request.body; | ||
|
||
if (!extensionUrl) { | ||
logger.debug('SCTM - install - Missing body parameters {extensionUrl}.'); | ||
return apiError(response, formatErrorResponse(new CustomError(400, 'Missing body parameters.')).errors); | ||
} | ||
|
||
try { | ||
await createExtensionAndCustomFields(extensionUrl); | ||
logger.debug( | ||
'SCTM - install - The connector was installed successfully with required extensions and custom fields.', | ||
); | ||
return response | ||
.status(200) | ||
.json('The connector was installed successfully with required extensions and custom fields.'); | ||
} catch (error) { | ||
logger.error('SCTM - install - Unexpected error occurred when processing request', error); | ||
return apiError(response, formatErrorResponse(error).errors); | ||
} | ||
}; | ||
|
||
export const uninstall = async (request: Request, response: Response) => { | ||
try { | ||
await removeExtension(); | ||
logger.debug('SCTM - uninstall - The connector was uninstalled successfully.'); | ||
return response.status(200).json('The connector was uninstalled successfully.'); | ||
} catch (error) { | ||
logger.error('SCTM - uninstallation - Unexpected error occurred when processing request', error); | ||
return apiError(response, formatErrorResponse(error).errors); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { initMollieClient } from '../client/mollie.client'; | ||
import { MollieApiError, Profile } from '@mollie/api-client'; | ||
import { logger } from '../utils/logger.utils'; | ||
import CustomError from '../errors/custom.error'; | ||
|
||
export const getProfile = async (): Promise<Profile> => { | ||
try { | ||
return await initMollieClient().profiles.getCurrent(); | ||
} catch (error) { | ||
let errorMessage; | ||
if (error instanceof MollieApiError) { | ||
errorMessage = `SCTM - getProfile - error: ${error.message}, field: ${error.field}`; | ||
} else { | ||
errorMessage = `SCTM - getProfile - Failed to get Mollie profile with unknown errors`; | ||
} | ||
|
||
logger.error(errorMessage, { | ||
error, | ||
}); | ||
throw new CustomError(400, errorMessage); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,17 @@ | ||
import { Router } from 'express'; | ||
import { post } from '../controllers/processor.controller'; | ||
import { install, healthCheck, uninstall, mollieStatus } from '../controllers/connector.controller'; | ||
|
||
const serviceRouter = Router(); | ||
|
||
serviceRouter.get('/health-check', async (req, res) => { | ||
res.status(200).send('Mollie processor is successfully running'); | ||
}); | ||
|
||
serviceRouter.post('/', post); | ||
|
||
serviceRouter.get('/health-check', healthCheck); | ||
|
||
serviceRouter.get('/mollie/status', mollieStatus); | ||
|
||
serviceRouter.post('/install', install); | ||
|
||
serviceRouter.post('/uninstall', uninstall); | ||
|
||
export default serviceRouter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { createPaymentExtension, deletePaymentExtension } from '../commercetools/extensions.commercetools'; | ||
import { | ||
createCustomPaymentType, | ||
createCustomPaymentInterfaceInteractionType, | ||
createCustomPaymentTransactionCancelReasonType, | ||
} from '../commercetools/customFields.commercetools'; | ||
export const createExtensionAndCustomFields = async (extensionUrl: string): Promise<void> => { | ||
await createPaymentExtension(extensionUrl); | ||
await createCustomPaymentType(); | ||
await createCustomPaymentInterfaceInteractionType(); | ||
await createCustomPaymentTransactionCancelReasonType(); | ||
}; | ||
|
||
export const removeExtension = async (): Promise<void> => { | ||
await deletePaymentExtension(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { describe, it, jest, expect } from '@jest/globals'; | ||
import { createClient } from '../../src/client/build.client'; | ||
import { ClientBuilder } from '@commercetools/sdk-client-v2'; | ||
import { readConfiguration } from '../../src/utils/config.utils'; | ||
|
||
jest.mock('@commercetools/sdk-client-v2', () => ({ | ||
ClientBuilder: jest.fn().mockImplementation(() => ({ | ||
withProjectKey: jest.fn().mockReturnThis(), | ||
withClientCredentialsFlow: jest.fn().mockReturnThis(), | ||
withHttpMiddleware: jest.fn().mockReturnThis(), | ||
withUserAgentMiddleware: jest.fn().mockReturnThis(), | ||
build: jest.fn(), | ||
})), | ||
})); | ||
|
||
jest.mock('../../src/utils/config.utils', () => ({ | ||
readConfiguration: jest.fn(() => { | ||
return { | ||
commerceTools: { | ||
projectKey: 'test-project-key', | ||
region: 'europe-west1.gcp', | ||
clientId: 'test-client-id', | ||
clientSecret: 'test-client-secret', | ||
}, | ||
}; | ||
}), | ||
})); | ||
|
||
describe('createClient', () => { | ||
it('should create a client with the correct configuration', () => { | ||
(readConfiguration as jest.Mock).mockReturnValueOnce({ | ||
commerceTools: { | ||
projectKey: 'test-project-key', | ||
region: 'europe-west1.gcp', | ||
clientId: 'test-client-id', | ||
clientSecret: 'test-client-secret', | ||
}, | ||
}); | ||
createClient(); | ||
expect(ClientBuilder).toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { describe, jest, beforeEach, afterEach, it, expect } from '@jest/globals'; | ||
import { Request, Response } from 'express'; | ||
import { healthCheck, install, uninstall } from '../../src/controllers/connector.controller'; | ||
import { logger } from '../../src/utils/logger.utils'; | ||
|
||
jest.mock('../../src/service/connector.service', () => ({ | ||
createExtensionAndCustomFields: jest.fn(), | ||
removeExtension: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../src/utils/logger.utils'); | ||
|
||
describe('Test connector.controller.ts', () => { | ||
let req: Partial<Request>; | ||
let res: Partial<Response>; | ||
|
||
beforeEach(() => { | ||
res = { | ||
// @ts-expect-error: ignore type error | ||
status: jest.fn().mockReturnThis(), | ||
// @ts-expect-error: ignore type error | ||
send: jest.fn(), | ||
// @ts-expect-error: ignore type error | ||
json: jest.fn(), | ||
}; | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should return status code 200 with a successful health check response', async () => { | ||
req = {}; | ||
await healthCheck(req as Request, res as Response); | ||
expect(logger.debug).toBeCalledTimes(1); | ||
expect(logger.debug).toHaveBeenCalledWith('SCTM - healthCheck - The connector is running healthily.'); | ||
expect(res.status).toBeCalledWith(200); | ||
}); | ||
|
||
it('should return status code 200 with a successful install response', async () => { | ||
req = { | ||
body: { extensionUrl: 'https://example.com/extensionUrl' }, | ||
}; | ||
await install(req as Request, res as Response); | ||
expect(logger.debug).toBeCalledTimes(1); | ||
expect(logger.debug).toHaveBeenCalledWith( | ||
'SCTM - install - The connector was installed successfully with required extensions and custom fields.', | ||
); | ||
expect(res.status).toBeCalledWith(200); | ||
}); | ||
|
||
it('should return status code 400 when extensionUrl is missing during install', async () => { | ||
req = { | ||
body: { extensionUrl: '' }, | ||
}; | ||
await install(req as Request, res as Response); | ||
expect(logger.debug).toBeCalledTimes(1); | ||
expect(logger.debug).toHaveBeenCalledWith('SCTM - install - Missing body parameters {extensionUrl}.'); | ||
expect(res.status).toBeCalledWith(400); | ||
}); | ||
|
||
it('should return status code 200 with a successful uninstall response', async () => { | ||
req = {}; | ||
await uninstall(req as Request, res as Response); | ||
expect(logger.debug).toBeCalledTimes(1); | ||
expect(logger.debug).toHaveBeenCalledWith('SCTM - uninstall - The connector was uninstalled successfully.'); | ||
expect(res.status).toBeCalledWith(200); | ||
}); | ||
}); |
Oops, something went wrong.