1+ import { INestApplication } from '@nestjs/common' ;
2+ import { Transport } from '@nestjs/microservices' ;
3+ import { Test } from '@nestjs/testing' ;
4+ import * as express from 'express' ;
5+ import { join } from 'path' ;
6+ import * as request from 'supertest' ;
7+ import * as ProtoLoader from '@grpc/proto-loader' ;
8+ import * as GRPC from 'grpc' ;
9+ import { expect } from 'chai' ;
10+ import { fail } from 'assert' ;
11+ import { AdvancedGrpcController } from '../src/grpc-advanced/advanced.grpc.controller' ;
12+
13+ describe ( 'Advanced GRPC transport' , ( ) => {
14+ let server ;
15+ let app : INestApplication ;
16+ let client : any ;
17+
18+ before ( async ( ) => {
19+ const module = await Test . createTestingModule ( {
20+ controllers : [ AdvancedGrpcController ] ,
21+ } ) . compile ( ) ;
22+ // Create gRPC + HTTP server
23+ server = express ( ) ;
24+ app = module . createNestApplication ( server ) ;
25+ /*
26+ * Create microservice configuration
27+ */
28+ app . connectMicroservice ( {
29+ transport : Transport . GRPC ,
30+ options : {
31+ package : 'proto_example' ,
32+ protoPath : 'root.proto' ,
33+ loader : {
34+ includeDirs : [ join ( __dirname , '../src/grpc-advanced/proto' ) ] ,
35+ keepCase : true ,
36+ } ,
37+ } ,
38+ } ) ;
39+ // Start gRPC microservice
40+ await app . startAllMicroservicesAsync ( ) ;
41+ await app . init ( ) ;
42+ // Load proto-buffers for test gRPC dispatch
43+ const proto = ProtoLoader . loadSync ( 'root.proto' , {
44+ includeDirs : [ join ( __dirname , '../src/grpc-advanced/proto' ) ] ,
45+ } ) as any ;
46+ // Create Raw gRPC client object
47+ const protoGRPC = GRPC . loadPackageDefinition ( proto ) as any ;
48+ // Create client connected to started services at standard 5000 port
49+ client = new protoGRPC . proto_example . orders . OrderService (
50+ 'localhost:5000' ,
51+ GRPC . credentials . createInsecure ( ) ,
52+ ) ;
53+
54+ } ) ;
55+
56+ it ( `GRPC Sending and Receiving HTTP POST` , ( ) => {
57+ return request ( server )
58+ . post ( '/' )
59+ . send ( '1' )
60+ . expect ( 200 , {
61+ id : 1 ,
62+ itemTypes : [ 1 ] ,
63+ shipmentType : {
64+ from : 'test' ,
65+ to : 'test1' ,
66+ carrier : 'test-carrier' ,
67+ } ,
68+ } ) ;
69+ } ) ;
70+
71+ it ( 'GRPC Sending and receiving message' , async ( ) => {
72+
73+ // Execute find in Promise
74+ return new Promise ( resolve => {
75+ client . find ( {
76+ id : 1 ,
77+ } , ( err , result ) => {
78+ // Compare results
79+ expect ( err ) . to . be . null ;
80+ expect ( result ) . to . eql ( {
81+ id : 1 ,
82+ itemTypes : [ 1 ] ,
83+ shipmentType : {
84+ from : 'test' ,
85+ to : 'test1' ,
86+ carrier : 'test-carrier' ,
87+ } ,
88+ } ) ;
89+ // Resolve after checkups
90+ resolve ( ) ;
91+ } ) ;
92+
93+ } ) ;
94+
95+ } ) ;
96+
97+ it ( 'GRPC Sending and receiving Stream from RX handler' , async ( ) => {
98+
99+ const callHandler = client . sync ( ) ;
100+
101+ callHandler . on ( 'data' , ( msg : number ) => {
102+ // Do deep comparison (to.eql)
103+ expect ( msg ) . to . eql ( {
104+ id : 1 ,
105+ itemTypes : [ 1 ] ,
106+ shipmentType : {
107+ from : 'test' ,
108+ to : 'test1' ,
109+ carrier : 'test-carrier' ,
110+ } ,
111+ } ) ;
112+ callHandler . cancel ( ) ;
113+ } ) ;
114+
115+ callHandler . on ( 'error' , ( err : any ) => {
116+ // We want to fail only on real errors while Cancellation error
117+ // is expected
118+ if ( String ( err ) . toLowerCase ( ) . indexOf ( 'cancelled' ) === - 1 ) {
119+ fail ( 'gRPC Stream error happened, error: ' + err ) ;
120+ }
121+ } ) ;
122+
123+ return new Promise ( ( resolve , reject ) => {
124+ callHandler . write ( {
125+ id : 1 ,
126+ } ) ;
127+ setTimeout ( ( ) => resolve ( ) , 1000 ) ;
128+ } ) ;
129+
130+ } ) ;
131+
132+ } ) ;
0 commit comments