mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
feat(core): add jwt-customizer test script deployment (#5686)
feat(core): call cloud worker deploy service on custom jwt test call cloud worker deploy service on custom jwt test
This commit is contained in:
parent
63639ad502
commit
568e3dc202
4 changed files with 86 additions and 28 deletions
|
@ -1,13 +1,17 @@
|
|||
import { LogtoJwtTokenKey } from '@logto/schemas';
|
||||
import {
|
||||
LogtoJwtTokenKey,
|
||||
LogtoJwtTokenKeyType,
|
||||
type JwtCustomizerTestRequestBody,
|
||||
} from '@logto/schemas';
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
import { pick } from '@silverhand/essentials';
|
||||
import Sinon from 'sinon';
|
||||
|
||||
import {
|
||||
mockJwtCustomizerConfigForAccessToken,
|
||||
mockJwtCustomizerConfigForClientCredentials,
|
||||
mockLogtoConfigRows,
|
||||
} from '#src/__mocks__/index.js';
|
||||
import { mockCloudClient, mockLogtoConfigsLibrary } from '#src/test-utils/mock-libraries.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
|
@ -18,20 +22,16 @@ const logtoConfigQueries = {
|
|||
deleteJwtCustomizer: jest.fn(),
|
||||
};
|
||||
|
||||
const logtoConfigLibraries = {
|
||||
upsertJwtCustomizer: jest.fn(),
|
||||
getJwtCustomizer: jest.fn(),
|
||||
getJwtCustomizers: jest.fn(),
|
||||
updateJwtCustomizer: jest.fn(),
|
||||
deployJwtCustomizerScript: jest.fn(),
|
||||
undeployJwtCustomizerScript: jest.fn(),
|
||||
};
|
||||
|
||||
const settingRoutes = await pickDefault(import('./index.js'));
|
||||
|
||||
describe('configs JWT customizer routes', () => {
|
||||
const tenantContext = new MockTenant(undefined, { logtoConfigs: logtoConfigQueries });
|
||||
Sinon.stub(tenantContext, 'logtoConfigs').value(logtoConfigLibraries);
|
||||
const tenantContext = new MockTenant(
|
||||
undefined,
|
||||
{ logtoConfigs: logtoConfigQueries },
|
||||
undefined,
|
||||
undefined,
|
||||
mockLogtoConfigsLibrary
|
||||
);
|
||||
|
||||
const routeRequester = createRequester({
|
||||
authedRoutes: settingRoutes,
|
||||
|
@ -48,16 +48,22 @@ describe('configs JWT customizer routes', () => {
|
|||
rows: [],
|
||||
rowCount: 0,
|
||||
});
|
||||
logtoConfigLibraries.upsertJwtCustomizer.mockResolvedValueOnce(
|
||||
mockLogtoConfigsLibrary.upsertJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken
|
||||
);
|
||||
const response = await routeRequester
|
||||
.put(`/configs/jwt-customizer/access-token`)
|
||||
.send(mockJwtCustomizerConfigForAccessToken.value);
|
||||
|
||||
expect(logtoConfigLibraries.upsertJwtCustomizer).toHaveBeenCalled();
|
||||
expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith(
|
||||
tenantContext.cloudConnection,
|
||||
{
|
||||
key: LogtoJwtTokenKey.AccessToken,
|
||||
value: mockJwtCustomizerConfigForAccessToken.value,
|
||||
}
|
||||
);
|
||||
|
||||
expect(logtoConfigLibraries.upsertJwtCustomizer).toHaveBeenCalledWith(
|
||||
expect(mockLogtoConfigsLibrary.upsertJwtCustomizer).toHaveBeenCalledWith(
|
||||
LogtoJwtTokenKey.AccessToken,
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
|
@ -71,13 +77,13 @@ describe('configs JWT customizer routes', () => {
|
|||
rows: [mockJwtCustomizerConfigForAccessToken],
|
||||
rowCount: 1,
|
||||
});
|
||||
logtoConfigLibraries.upsertJwtCustomizer.mockResolvedValueOnce(
|
||||
mockLogtoConfigsLibrary.upsertJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken
|
||||
);
|
||||
const response = await routeRequester
|
||||
.put('/configs/jwt-customizer/access-token')
|
||||
.send(mockJwtCustomizerConfigForAccessToken.value);
|
||||
expect(logtoConfigLibraries.upsertJwtCustomizer).toHaveBeenCalledWith(
|
||||
expect(mockLogtoConfigsLibrary.upsertJwtCustomizer).toHaveBeenCalledWith(
|
||||
LogtoJwtTokenKey.AccessToken,
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
|
@ -86,16 +92,22 @@ describe('configs JWT customizer routes', () => {
|
|||
});
|
||||
|
||||
it('PATCH /configs/jwt-customizer/:tokenType should update a record successfully', async () => {
|
||||
logtoConfigLibraries.updateJwtCustomizer.mockResolvedValueOnce(
|
||||
mockLogtoConfigsLibrary.updateJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
const response = await routeRequester
|
||||
.patch('/configs/jwt-customizer/access-token')
|
||||
.send(mockJwtCustomizerConfigForAccessToken.value);
|
||||
|
||||
expect(logtoConfigLibraries.deployJwtCustomizerScript).toHaveBeenCalled();
|
||||
expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith(
|
||||
tenantContext.cloudConnection,
|
||||
{
|
||||
key: LogtoJwtTokenKey.AccessToken,
|
||||
value: mockJwtCustomizerConfigForAccessToken.value,
|
||||
}
|
||||
);
|
||||
|
||||
expect(logtoConfigLibraries.updateJwtCustomizer).toHaveBeenCalledWith(
|
||||
expect(mockLogtoConfigsLibrary.updateJwtCustomizer).toHaveBeenCalledWith(
|
||||
LogtoJwtTokenKey.AccessToken,
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
|
@ -104,7 +116,7 @@ describe('configs JWT customizer routes', () => {
|
|||
});
|
||||
|
||||
it('GET /configs/jwt-customizer should return all records', async () => {
|
||||
logtoConfigLibraries.getJwtCustomizers.mockResolvedValueOnce({
|
||||
mockLogtoConfigsLibrary.getJwtCustomizers.mockResolvedValueOnce({
|
||||
[LogtoJwtTokenKey.AccessToken]: mockJwtCustomizerConfigForAccessToken.value,
|
||||
[LogtoJwtTokenKey.ClientCredentials]: mockJwtCustomizerConfigForClientCredentials.value,
|
||||
});
|
||||
|
@ -117,7 +129,7 @@ describe('configs JWT customizer routes', () => {
|
|||
});
|
||||
|
||||
it('GET /configs/jwt-customizer/:tokenType should return the record', async () => {
|
||||
logtoConfigLibraries.getJwtCustomizer.mockResolvedValueOnce(
|
||||
mockLogtoConfigsLibrary.getJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
const response = await routeRequester.get('/configs/jwt-customizer/access-token');
|
||||
|
@ -127,7 +139,7 @@ describe('configs JWT customizer routes', () => {
|
|||
|
||||
it('DELETE /configs/jwt-customizer/:tokenType should delete the record', async () => {
|
||||
const response = await routeRequester.delete('/configs/jwt-customizer/client-credentials');
|
||||
expect(logtoConfigLibraries.undeployJwtCustomizerScript).toHaveBeenCalledWith(
|
||||
expect(mockLogtoConfigsLibrary.undeployJwtCustomizerScript).toHaveBeenCalledWith(
|
||||
tenantContext.cloudConnection,
|
||||
LogtoJwtTokenKey.ClientCredentials
|
||||
);
|
||||
|
@ -136,4 +148,35 @@ describe('configs JWT customizer routes', () => {
|
|||
);
|
||||
expect(response.status).toEqual(204);
|
||||
});
|
||||
|
||||
it('POST /configs/jwt-customizer/test should return 200', async () => {
|
||||
const cloudConnectionResponse = { success: true };
|
||||
jest.spyOn(tenantContext.cloudConnection, 'getClient').mockResolvedValue(mockCloudClient);
|
||||
jest.spyOn(mockCloudClient, 'post').mockResolvedValue(cloudConnectionResponse);
|
||||
|
||||
const payload: JwtCustomizerTestRequestBody = {
|
||||
tokenType: LogtoJwtTokenKeyType.AccessToken,
|
||||
token: {},
|
||||
script: mockJwtCustomizerConfigForAccessToken.value.script,
|
||||
environmentVariables: mockJwtCustomizerConfigForAccessToken.value.environmentVariables,
|
||||
context: mockJwtCustomizerConfigForAccessToken.value.contextSample,
|
||||
};
|
||||
|
||||
const response = await routeRequester.post('/configs/jwt-customizer/test').send(payload);
|
||||
|
||||
expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith(
|
||||
tenantContext.cloudConnection,
|
||||
{
|
||||
key: LogtoJwtTokenKey.AccessToken,
|
||||
value: payload,
|
||||
isTest: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(mockCloudClient.post).toHaveBeenCalledWith('/api/services/custom-jwt', {
|
||||
body: payload,
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -200,7 +200,7 @@ export default function logtoConfigJwtCustomizerRoutes<T extends AuthedRouter>(
|
|||
}
|
||||
);
|
||||
|
||||
if (!EnvSet.values.isCloud) {
|
||||
if (!EnvSet.values.isCloud && !EnvSet.values.isUnitTest) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -219,6 +219,16 @@ export default function logtoConfigJwtCustomizerRoutes<T extends AuthedRouter>(
|
|||
async (ctx, next) => {
|
||||
const { body } = ctx.guard;
|
||||
|
||||
// Deploy the test script
|
||||
await deployJwtCustomizerScript(cloudConnection, {
|
||||
key:
|
||||
body.tokenType === LogtoJwtTokenKeyType.AccessToken
|
||||
? LogtoJwtTokenKey.AccessToken
|
||||
: LogtoJwtTokenKey.ClientCredentials,
|
||||
value: body,
|
||||
isTest: true,
|
||||
});
|
||||
|
||||
const client = await cloudConnection.getClient();
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import type router from '@logto/cloud/routes';
|
||||
import Client from '@withtyped/client';
|
||||
|
||||
import { type LogtoConfigLibrary } from '#src/libraries/logto-config.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
|
||||
export const mockLogtoConfigsLibrary: LogtoConfigLibrary = {
|
||||
export const mockLogtoConfigsLibrary: jest.Mocked<LogtoConfigLibrary> = {
|
||||
getCloudConnectionData: jest.fn(),
|
||||
getOidcConfigs: jest.fn(),
|
||||
upsertJwtCustomizer: jest.fn(),
|
||||
|
@ -12,3 +15,5 @@ export const mockLogtoConfigsLibrary: LogtoConfigLibrary = {
|
|||
deployJwtCustomizerScript: jest.fn(),
|
||||
undeployJwtCustomizerScript: jest.fn(),
|
||||
};
|
||||
|
||||
export const mockCloudClient = new Client<typeof router>({ baseUrl: 'http://localhost:3001' });
|
||||
|
|
|
@ -7,8 +7,7 @@ import type { CloudConnectionLibrary } from '#src/libraries/cloud-connection.js'
|
|||
import { createCloudConnectionLibrary } from '#src/libraries/cloud-connection.js';
|
||||
import type { ConnectorLibrary } from '#src/libraries/connector.js';
|
||||
import { createConnectorLibrary } from '#src/libraries/connector.js';
|
||||
import { createLogtoConfigLibrary } from '#src/libraries/logto-config.js';
|
||||
import { type LogtoConfigLibrary } from '#src/libraries/logto-config.js';
|
||||
import { createLogtoConfigLibrary, type LogtoConfigLibrary } from '#src/libraries/logto-config.js';
|
||||
import Libraries from '#src/tenants/Libraries.js';
|
||||
import Queries from '#src/tenants/Queries.js';
|
||||
import type TenantContext from '#src/tenants/TenantContext.js';
|
||||
|
@ -78,6 +77,7 @@ export class MockTenant implements TenantContext {
|
|||
logtoConfigsOverride?: Partial<LogtoConfigLibrary>
|
||||
) {
|
||||
this.queries = new MockQueries(queriesOverride);
|
||||
|
||||
this.logtoConfigs = { ...createLogtoConfigLibrary(this.queries), ...logtoConfigsOverride };
|
||||
this.cloudConnection = createCloudConnectionLibrary(this.logtoConfigs);
|
||||
this.connectors = {
|
||||
|
|
Loading…
Add table
Reference in a new issue