diff --git a/packages/nice-grpc-client-middleware-devtools/jest.config.js b/packages/nice-grpc-client-middleware-devtools/jest.config.js index d4c74235..5bb07079 100644 --- a/packages/nice-grpc-client-middleware-devtools/jest.config.js +++ b/packages/nice-grpc-client-middleware-devtools/jest.config.js @@ -1,6 +1,6 @@ /** @type {import('@jest/types').Config.GlobalConfig} */ module.exports = { - testPathIgnorePatterns: ['/node_modules/', '/lib/'], + testPathIgnorePatterns: ['/node_modules/', '/lib/', '/fixtures/'], preset: 'ts-jest', testEnvironment: 'node', testTimeout: 15000, @@ -9,4 +9,9 @@ module.exports = { coverageDirectory: 'coverage', coverageReporters: ['lcov', 'text'], coveragePathIgnorePatterns: ['/node_modules/', '/lib/'], + globals: { + window: { + postMessage: () => ({}), + }, + }, }; diff --git a/packages/nice-grpc-client-middleware-devtools/package.json b/packages/nice-grpc-client-middleware-devtools/package.json index 952e3ff0..afb4d27f 100644 --- a/packages/nice-grpc-client-middleware-devtools/package.json +++ b/packages/nice-grpc-client-middleware-devtools/package.json @@ -16,8 +16,10 @@ "test": "jest", "build": "tsc -P tsconfig.build.json", "prepublishOnly": "npm run clean && npm run build && npm test", - "build:proto": "grpc_tools_node_protoc --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures --ts_out=grpc_js:./fixtures --grpc_out=grpc_js:./fixtures -I fixtures fixtures/*.proto", - "prepare": "npm run build:proto" + "prepare:proto:grpc-js": "mkdirp ./fixtures/grpc-js && grpc_tools_node_protoc --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-js --ts_out=grpc_js:./fixtures/grpc-js --grpc_out=grpc_js:./fixtures/grpc-js -I fixtures fixtures/*.proto", + "prepare:proto:ts-proto": "mkdirp ./fixtures/ts-proto && grpc_tools_node_protoc --ts_proto_out=./fixtures/ts-proto --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false,esModuleInterop=true -I fixtures fixtures/*.proto", + "prepare:proto": "npm run prepare:proto:grpc-js && npm run prepare:proto:ts-proto", + "prepare": "npm run prepare:proto" }, "author": "Sebastian Halder", "license": "MIT", diff --git a/packages/nice-grpc-client-middleware-devtools/src/index.test.ts b/packages/nice-grpc-client-middleware-devtools/src/index.test.ts index f87cee07..cd9182f2 100644 --- a/packages/nice-grpc-client-middleware-devtools/src/index.test.ts +++ b/packages/nice-grpc-client-middleware-devtools/src/index.test.ts @@ -8,7 +8,120 @@ import { Status, } from 'nice-grpc'; import {devtoolsLoggingMiddleware} from '.'; -import {TestService} from '../fixtures/test_grpc_pb'; -import {TestRequest, TestResponse} from '../fixtures/test_pb'; +import {TestService} from '../fixtures/grpc-js/test_grpc_pb'; +import { + TestDefinition, + TestRequest as TestRequestTS, +} from '../fixtures/ts-proto/test'; +import { + TestRequest as TestRequestJS, + TestResponse as TestResponseJS, +} from '../fixtures/grpc-js/test_pb'; + +function throwUnimplemented(): never { + throw new ServerError(Status.UNIMPLEMENTED, ''); +} + +let windowSpy: jest.SpyInstance; +let postMessageMock: jest.Mock; + +beforeEach(() => { + postMessageMock = jest.fn(); + windowSpy = jest.spyOn(window, 'postMessage'); + windowSpy.mockImplementation(postMessageMock); +}); + +afterEach(() => { + windowSpy.mockRestore(); +}); + +describe('devtools', () => { + test('grpc-js logs unary calls', async () => { + const server = createServer(); + + server.add(TestService, { + async testUnary(request: TestRequestJS, {signal}) { + return new TestResponseJS(); + }, + testServerStream: throwUnimplemented, + testClientStream: throwUnimplemented, + testBidiStream: throwUnimplemented, + }); + + const port = await server.listen('localhost:0'); + + const channel = createChannel(`localhost:${port}`); + const client = createClientFactory() + .use(devtoolsLoggingMiddleware) + .create(TestService, channel); + + const req = new TestRequestJS(); + req.setId('test-id'); + + const promise = client.testUnary(req); + + await expect(promise).resolves.toEqual(new TestResponseJS()); + await expect(postMessageMock).toHaveBeenCalledTimes(1); + await expect(postMessageMock).toHaveBeenCalledWith( + expect.objectContaining({ + request: { + id: 'test-id', + }, + response: { + id: '', + }, + methodType: 'unary', + method: '/nice_grpc.test.Test/TestUnary', + }), + '*', + ); + + channel.close(); + + await server.shutdown(); + }); + + test('ts-proto logs unary calls', async () => { + const server = createServer(); + + server.add(TestService, { + async testUnary(request: TestRequestJS, {signal}) { + return new TestResponseJS(); + }, + testServerStream: throwUnimplemented, + testClientStream: throwUnimplemented, + testBidiStream: throwUnimplemented, + }); + + const port = await server.listen('localhost:0'); + + const channel = createChannel(`localhost:${port}`); + const client = createClientFactory() + .use(devtoolsLoggingMiddleware) + .create(TestDefinition, channel); + + const req: TestRequestTS = {id: 'test-id'}; + + const promise = client.testUnary(req); + + await expect(promise).resolves.toEqual({id: ''}); + await expect(postMessageMock).toHaveBeenCalledTimes(1); + await expect(postMessageMock).toHaveBeenCalledWith( + expect.objectContaining({ + request: { + id: 'test-id', + }, + response: { + id: '', + }, + methodType: 'unary', + method: '/nice_grpc.test.Test/TestUnary', + }), + '*', + ); + + channel.close(); -// TODO: Can this middleware be tested? \ No newline at end of file + await server.shutdown(); + }); +});