0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(core): migrate resource library to factory mode

This commit is contained in:
Gao Sun 2023-01-10 00:38:33 +08:00
parent f7c08332a1
commit 0442efeb60
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
5 changed files with 73 additions and 53 deletions

View file

@ -1,19 +1,19 @@
import { createMockUtils } from '@logto/shared/esm';
import { mockResource, mockResource2, mockResource3, mockScope } from '#src/__mocks__/index.js';
import { MockQueries } from '#src/test-utils/tenant.js';
const { jest } = import.meta;
const { mockEsmWithActual } = createMockUtils(jest);
const { findScopesByResourceIds } = await mockEsmWithActual('#src/queries/scope.js', () => ({
findScopesByResourceIds: jest.fn(async () => [
{ ...mockScope, id: '1', resourceId: mockResource.id },
{ ...mockScope, id: '2', resourceId: mockResource.id },
{ ...mockScope, id: '3', resourceId: mockResource2.id },
]),
}));
const findScopesByResourceIds = jest.fn(async () => [
{ ...mockScope, id: '1', resourceId: mockResource.id },
{ ...mockScope, id: '2', resourceId: mockResource.id },
{ ...mockScope, id: '3', resourceId: mockResource2.id },
]);
const { attachScopesToResources } = await import('./resource.js');
const { createResourceLibrary } = await import('./resource.js');
const { attachScopesToResources } = createResourceLibrary(
new MockQueries({ scopes: { findScopesByResourceIds } })
);
describe('attachScopesToResources', () => {
beforeEach(() => {

View file

@ -1,15 +1,21 @@
import type { Resource, ResourceResponse } from '@logto/schemas';
import { findScopesByResourceIds } from '#src/queries/scope.js';
import type Queries from '#src/tenants/Queries.js';
export const attachScopesToResources = async (
resources: readonly Resource[]
): Promise<ResourceResponse[]> => {
const resourceIds = resources.map(({ id }) => id);
const scopes = await findScopesByResourceIds(resourceIds);
export const createResourceLibrary = (queries: Queries) => {
const { findScopesByResourceIds } = queries.scopes;
return resources.map((resource) => ({
...resource,
scopes: scopes.filter(({ resourceId }) => resourceId === resource.id),
}));
const attachScopesToResources = async (
resources: readonly Resource[]
): Promise<ResourceResponse[]> => {
const resourceIds = resources.map(({ id }) => id);
const scopes = await findScopesByResourceIds(resourceIds);
return resources.map((resource) => ({
...resource,
scopes: scopes.filter(({ resourceId }) => resourceId === resource.id),
}));
};
return { attachScopesToResources };
};

View file

@ -2,21 +2,14 @@ import type { Resource, CreateResource } from '@logto/schemas';
import { pickDefault, createMockUtils } from '@logto/shared/esm';
import { mockResource, mockScope } from '#src/__mocks__/index.js';
import { MockTenant } from '#src/test-utils/tenant.js';
import { createRequester } from '#src/utils/test-utils.js';
const { jest } = import.meta;
const { mockEsm, mockEsmWithActual } = createMockUtils(jest);
const { mockEsm } = createMockUtils(jest);
await mockEsmWithActual('#src/libraries/resource.js', () => ({
attachScopesToResources: async (resources: Resource[]) =>
resources.map((resource) => ({
...resource,
scopes: [],
})),
}));
const { findResourceById } = mockEsm('#src/queries/resource.js', () => ({
const resources = {
findTotalNumberOfResources: async () => ({ count: 10 }),
findAllResources: async (): Promise<Resource[]> => [mockResource],
findResourceById: jest.fn(async (): Promise<Resource> => mockResource),
@ -30,26 +23,40 @@ const { findResourceById } = mockEsm('#src/queries/resource.js', () => ({
}),
deleteResourceById: jest.fn(),
findScopesByResourceId: async () => [mockScope],
}));
};
const { findResourceById } = resources;
const { insertScope, updateScopeById } = await mockEsmWithActual('#src/queries/scope.js', () => ({
const scopes = {
findScopesByResourceId: async () => [mockScope],
findScopes: async () => [mockScope],
insertScope: jest.fn(async () => mockScope),
updateScopeById: jest.fn(async () => mockScope),
deleteScopeById: jest.fn(),
findScopeByNameAndResourceId: jest.fn(),
}));
};
const { insertScope, updateScopeById } = scopes;
const libraries = {
resources: {
attachScopesToResources: async (resources: readonly Resource[]) =>
resources.map((resource) => ({
...resource,
scopes: [],
})),
},
};
mockEsm('@logto/core-kit', () => ({
// eslint-disable-next-line unicorn/consistent-function-scoping
buildIdGenerator: () => () => 'randomId',
}));
const tenantContext = new MockTenant(undefined, { scopes, resources }, libraries);
const resourceRoutes = await pickDefault(import('./resource.js'));
describe('resource routes', () => {
const resourceRequest = createRequester({ authedRoutes: resourceRoutes });
const resourceRequest = createRequester({ authedRoutes: resourceRoutes, tenantContext });
it('GET /resources', async () => {
const response = await resourceRequest.get('/resources');

View file

@ -5,25 +5,8 @@ import { object, string } from 'zod';
import { isTrue } from '#src/env-set/parameters.js';
import RequestError from '#src/errors/RequestError/index.js';
import { attachScopesToResources } from '#src/libraries/resource.js';
import koaGuard from '#src/middleware/koa-guard.js';
import koaPagination from '#src/middleware/koa-pagination.js';
import {
findTotalNumberOfResources,
findAllResources,
findResourceById,
insertResource,
updateResourceById,
deleteResourceById,
} from '#src/queries/resource.js';
import {
countScopes,
deleteScopeById,
findScopeByNameAndResourceId,
findScopes,
insertScope,
updateScopeById,
} from '#src/queries/scope.js';
import assertThat from '#src/utils/assert-that.js';
import { parseSearchParamsForSearch } from '#src/utils/search.js';
@ -32,7 +15,29 @@ import type { AuthedRouter, RouterInitArgs } from './types.js';
const resourceId = buildIdGenerator(21);
const scopeId = resourceId;
export default function resourceRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
export default function resourceRoutes<T extends AuthedRouter>(
...[router, { queries, libraries }]: RouterInitArgs<T>
) {
const {
resources: {
findTotalNumberOfResources,
findAllResources,
findResourceById,
insertResource,
updateResourceById,
deleteResourceById,
},
scopes: {
countScopes,
deleteScopeById,
findScopes,
findScopeByNameAndResourceId,
insertScope,
updateScopeById,
},
} = queries;
const { attachScopesToResources } = libraries.resources;
router.get(
'/resources',
koaPagination({ isOptional: true }),

View file

@ -1,5 +1,6 @@
import { createConnectorLibrary } from '#src/libraries/connector.js';
import { createPhraseLibrary } from '#src/libraries/phrase.js';
import { createResourceLibrary } from '#src/libraries/resource.js';
import { createSignInExperienceLibrary } from '#src/libraries/sign-in-experience/index.js';
import { createUserLibrary } from '#src/libraries/user.js';
@ -10,6 +11,7 @@ export default class Libraries {
users = createUserLibrary(this.queries);
signInExperiences = createSignInExperienceLibrary(this.queries, this.connectors);
phrases = createPhraseLibrary(this.queries);
resources = createResourceLibrary(this.queries);
constructor(public readonly queries: Queries) {}
}