msw/node#SetupServerApi TypeScript Examples

The following examples show how to use msw/node#SetupServerApi. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: tests-utils.mock-server.ts    From jitsu with MIT License 7 votes vote down vote up
/**
 * Mock server setup
 */

/**
 * Sets up the mock server with some default endpoints that are required globally
 * along with the endpoints provided by user. User endpoints will override the defaults
 * if their keys match.
 *
 * @param endpoints
 * Endpoints to use for the mock server.
 *
 * Use `setupMockServer.endpoints.catalog` to get some handy defaults.
 *
 * To override one of the required endpoints just copy it from
 * `setupMockServer.endpoints.required`, change the data or the implementation
 * and pass it in `endpoints` under the same key as it appears in the
 * `setupMockServer.endpoints.required` catalog.
 *
 * @returns configured mock server instance.
 */
export function setupMockServer(endpoints: MockServerConfig = {}): SetupServerApi {
  const _endpoints: MockServerConfig = {
    ...mockObligatoryEndpoints,
    ...mockEndpointsCatalog,
    ...endpoints,
  }
  const _endpointsList = Object.values(_endpoints).map(({ responseData, requestFactory }) =>
    requestFactory(responseData)
  )
  return setupServer(..._endpointsList)
}
Example #2
Source File: client.test.ts    From backstage with Apache License 2.0 6 votes vote down vote up
function setupFakeFourPageURL(srv: SetupServerApi, url: string) {
  srv.use(
    rest.get(url, (req, res, ctx) => {
      const page = req.url.searchParams.get('page');
      const currentPage = page ? Number(page) : 1;
      const fakePageCount = 4;

      return res(
        // set next page number header if page requested is less than count
        ctx.set(
          'x-next-page',
          currentPage < fakePageCount ? String(currentPage + 1) : '',
        ),
        ctx.json([{ someContentOfPage: currentPage }]),
      );
    }),
  );
}
Example #3
Source File: client.test.ts    From backstage with Apache License 2.0 6 votes vote down vote up
function setupFakeGroupProjectsEndpoint(
  srv: SetupServerApi,
  apiBaseUrl: string,
  groupID: string,
) {
  srv.use(
    rest.get(`${apiBaseUrl}/groups/${groupID}/projects`, (_, res, ctx) => {
      return res(
        ctx.set('x-next-page', ''),
        ctx.json([
          {
            id: 1,
            description: 'Project One Description',
            name: 'Project One',
            path: 'project-one',
          },
        ]),
      );
    }),
  );
}
Example #4
Source File: client.test.ts    From backstage with Apache License 2.0 6 votes vote down vote up
function setupFakeInstanceProjectsEndpoint(
  srv: SetupServerApi,
  apiBaseUrl: string,
) {
  srv.use(
    rest.get(`${apiBaseUrl}/projects`, (_, res, ctx) => {
      return res(
        ctx.set('x-next-page', ''),
        ctx.json([
          {
            id: 1,
            description: 'Project One Description',
            name: 'Project One',
            path: 'project-one',
          },
          {
            id: 2,
            description: 'Project Two Description',
            name: 'Project Two',
            path: 'project-two',
          },
        ]),
      );
    }),
  );
}
Example #5
Source File: json-rpc-server.mock.ts    From cloud-cryptographic-wallet with MIT License 5 votes vote down vote up
export function getServer(rpcUrl: string, mocks: Mock[]): SetupServerApi {
  const handlers = mocks.map((mock) => makeHandler(rpcUrl, mock));
  return setupServer(...handlers);
}
Example #6
Source File: PermissionIntegrationClient.test.ts    From backstage with Apache License 2.0 4 votes vote down vote up
describe('PermissionIntegrationClient', () => {
  describe('applyConditions', () => {
    let server: SetupServerApi;

    const mockConditions: PermissionCriteria<PermissionCondition> = {
      not: {
        allOf: [
          { rule: 'RULE_1', resourceType: 'test-resource', params: [] },
          { rule: 'RULE_2', resourceType: 'test-resource', params: ['abc'] },
        ],
      },
    };

    const mockApplyConditionsHandler = jest.fn(
      (_req, res, { json }: RestContext) => {
        return res(
          json({ items: [{ id: '123', result: AuthorizeResult.ALLOW }] }),
        );
      },
    );

    const mockBaseUrl = 'http://backstage:9191';
    const discovery: PluginEndpointDiscovery = {
      async getBaseUrl(pluginId) {
        return `${mockBaseUrl}/${pluginId}`;
      },
      async getExternalBaseUrl() {
        throw new Error('Not implemented.');
      },
    };

    const client: PermissionIntegrationClient = new PermissionIntegrationClient(
      {
        discovery,
      },
    );

    beforeAll(() => {
      server = setupServer();
      server.listen({ onUnhandledRequest: 'error' });
      server.use(
        rest.post(
          `${mockBaseUrl}/plugin-1/.well-known/backstage/permissions/apply-conditions`,
          mockApplyConditionsHandler,
        ),
      );
    });

    afterAll(() => server.close());

    afterEach(() => {
      jest.clearAllMocks();
    });

    it('should make a POST request to the correct endpoint', async () => {
      await client.applyConditions('plugin-1', [
        {
          id: '123',
          resourceRef: 'testResource1',
          resourceType: 'test-resource',
          conditions: mockConditions,
        },
      ]);

      expect(mockApplyConditionsHandler).toHaveBeenCalled();
    });

    it('should include a request body', async () => {
      await client.applyConditions('plugin-1', [
        {
          id: '123',
          resourceRef: 'testResource1',
          resourceType: 'test-resource',
          conditions: mockConditions,
        },
      ]);

      expect(mockApplyConditionsHandler).toHaveBeenCalledWith(
        expect.objectContaining({
          body: {
            items: [
              {
                id: '123',
                resourceRef: 'testResource1',
                resourceType: 'test-resource',
                conditions: mockConditions,
              },
            ],
          },
        }),
        expect.anything(),
        expect.anything(),
      );
    });

    it('should return the response from the fetch request', async () => {
      const response = await client.applyConditions('plugin-1', [
        {
          id: '123',
          resourceRef: 'testResource1',
          resourceType: 'test-resource',
          conditions: mockConditions,
        },
      ]);

      expect(response).toEqual(
        expect.objectContaining([{ id: '123', result: AuthorizeResult.ALLOW }]),
      );
    });

    it('should not include authorization headers if no token is supplied', async () => {
      await client.applyConditions('plugin-1', [
        {
          id: '123',
          resourceRef: 'testResource1',
          resourceType: 'test-resource',
          conditions: mockConditions,
        },
      ]);

      const request = mockApplyConditionsHandler.mock.calls[0][0];
      expect(request.headers.has('authorization')).toEqual(false);
    });

    it('should include correctly-constructed authorization header if token is supplied', async () => {
      await client.applyConditions(
        'plugin-1',
        [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
        ],
        'Bearer fake-token',
      );

      const request = mockApplyConditionsHandler.mock.calls[0][0];
      expect(request.headers.get('authorization')).toEqual('Bearer fake-token');
    });

    it('should forward response errors', async () => {
      mockApplyConditionsHandler.mockImplementationOnce(
        (_req, res, { status }: RestContext) => {
          return res(status(401));
        },
      );

      await expect(
        client.applyConditions('plugin-1', [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
        ]),
      ).rejects.toThrowError(/401/i);
    });

    it('should reject invalid responses', async () => {
      mockApplyConditionsHandler.mockImplementationOnce(
        (_req, res, { json }: RestContext) => {
          return res(
            json({ items: [{ id: '123', outcome: AuthorizeResult.ALLOW }] }),
          );
        },
      );

      await expect(
        client.applyConditions('plugin-1', [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
        ]),
      ).rejects.toThrowError(/invalid input/i);
    });

    it('should batch requests to plugin backends', async () => {
      mockApplyConditionsHandler.mockImplementationOnce(
        (_req, res, { json }: RestContext) => {
          return res(
            json({
              items: [
                { id: '123', result: AuthorizeResult.ALLOW },
                { id: '456', result: AuthorizeResult.DENY },
                { id: '789', result: AuthorizeResult.ALLOW },
              ],
            }),
          );
        },
      );

      await expect(
        client.applyConditions('plugin-1', [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
          {
            id: '456',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
          {
            id: '789',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: mockConditions,
          },
        ]),
      ).resolves.toEqual([
        { id: '123', result: AuthorizeResult.ALLOW },
        { id: '456', result: AuthorizeResult.DENY },
        { id: '789', result: AuthorizeResult.ALLOW },
      ]);

      expect(mockApplyConditionsHandler).toHaveBeenCalledTimes(1);
    });
  });

  describe('integration with @backstage/plugin-permission-node', () => {
    let server: Server;
    let client: PermissionIntegrationClient;
    let routerSpy: RequestHandler;

    beforeAll(async () => {
      const router = Router();

      router.use(
        createPermissionIntegrationRouter({
          resourceType: 'test-resource',
          getResources: async resourceRefs =>
            resourceRefs.map(resourceRef => ({
              id: resourceRef,
            })),
          rules: [
            createPermissionRule({
              name: 'RULE_1',
              description: 'Test rule 1',
              resourceType: 'test-resource',
              apply: (_resource: any, input: 'yes' | 'no') => input === 'yes',
              toQuery: () => {
                throw new Error('Not implemented');
              },
            }),
            createPermissionRule({
              name: 'RULE_2',
              description: 'Test rule 2',
              resourceType: 'test-resource',
              apply: (_resource: any, input: 'yes' | 'no') => input === 'yes',
              toQuery: () => {
                throw new Error('Not implemented');
              },
            }),
          ],
        }),
      );

      const app = express();

      routerSpy = jest.fn(router);

      app.use('/plugin-1', routerSpy);

      await new Promise<void>(resolve => {
        server = app.listen(resolve);
      });

      const discovery: PluginEndpointDiscovery = {
        async getBaseUrl(pluginId: string) {
          const listenPort = (server.address()! as AddressInfo).port;

          return `http://0.0.0.0:${listenPort}/${pluginId}`;
        },
        async getExternalBaseUrl() {
          throw new Error('Not implemented.');
        },
      };

      client = new PermissionIntegrationClient({
        discovery,
      });
    });

    afterAll(
      async () =>
        new Promise<void>((resolve, reject) =>
          server.close(err => (err ? reject(err) : resolve())),
        ),
    );

    afterEach(() => {
      jest.clearAllMocks();
    });

    it('works for simple conditions', async () => {
      await expect(
        client.applyConditions('plugin-1', [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: {
              rule: 'RULE_1',
              resourceType: 'test-resource',
              params: ['no'],
            },
          },
        ]),
      ).resolves.toEqual([{ id: '123', result: AuthorizeResult.DENY }]);
    });

    it('works for complex criteria', async () => {
      await expect(
        client.applyConditions('plugin-1', [
          {
            id: '123',
            resourceRef: 'testResource1',
            resourceType: 'test-resource',
            conditions: {
              allOf: [
                {
                  allOf: [
                    {
                      rule: 'RULE_1',
                      resourceType: 'test-resource',
                      params: ['yes'],
                    },
                    {
                      not: {
                        rule: 'RULE_2',
                        resourceType: 'test-resource',
                        params: ['no'],
                      },
                    },
                  ],
                },
                {
                  not: {
                    allOf: [
                      {
                        rule: 'RULE_1',
                        resourceType: 'test-resource',
                        params: ['no'],
                      },
                      {
                        rule: 'RULE_2',
                        resourceType: 'test-resource',
                        params: ['yes'],
                      },
                    ],
                  },
                },
              ],
            },
          },
        ]),
      ).resolves.toEqual([{ id: '123', result: AuthorizeResult.ALLOW }]);
    });
  });
});