2020import wsChannel from '../../src/v1/internal/ch-websocket' ;
2121import ChannelConfig from '../../src/v1/internal/ch-config' ;
2222import urlUtil from '../../src/v1/internal/url-util' ;
23- import { SERVICE_UNAVAILABLE } from '../../src/v1/error' ;
23+ import { Neo4jError , SERVICE_UNAVAILABLE } from '../../src/v1/error' ;
2424import { setTimeoutMock } from './timers-util' ;
25+ import { ENCRYPTION_OFF , ENCRYPTION_ON } from '../../src/v1/internal/util' ;
2526
2627describe ( 'WebSocketChannel' , ( ) => {
2728
@@ -30,11 +31,16 @@ describe('WebSocketChannel', () => {
3031
3132 let OriginalWebSocket ;
3233 let webSocketChannel ;
34+ let originalConsoleWarn ;
3335
3436 beforeEach ( ( ) => {
3537 if ( webSocketChannelAvailable ) {
3638 OriginalWebSocket = WebSocket ;
3739 }
40+ originalConsoleWarn = console . warn ;
41+ console . warn = ( ) => {
42+ // mute by default
43+ } ;
3844 } ) ;
3945
4046 afterEach ( ( ) => {
@@ -44,6 +50,7 @@ describe('WebSocketChannel', () => {
4450 if ( webSocketChannel ) {
4551 webSocketChannel . close ( ) ;
4652 }
53+ console . warn = originalConsoleWarn ;
4754 } ) ;
4855
4956 it ( 'should fallback to literal IPv6 when SyntaxError is thrown' , ( ) => {
@@ -95,6 +102,64 @@ describe('WebSocketChannel', () => {
95102 }
96103 } ) ;
97104
105+ it ( 'should select wss when running on https page' , ( ) => {
106+ testWebSocketScheme ( 'https:' , { } , 'wss' ) ;
107+ } ) ;
108+
109+ it ( 'should select ws when running on http page' , ( ) => {
110+ testWebSocketScheme ( 'http:' , { } , 'ws' ) ;
111+ } ) ;
112+
113+ it ( 'should select ws when running on https page but encryption turned off with boolean' , ( ) => {
114+ testWebSocketScheme ( 'https:' , { encrypted : false } , 'ws' ) ;
115+ } ) ;
116+
117+ it ( 'should select ws when running on https page but encryption turned off with string' , ( ) => {
118+ testWebSocketScheme ( 'https:' , { encrypted : ENCRYPTION_OFF } , 'ws' ) ;
119+ } ) ;
120+
121+ it ( 'should select wss when running on http page but encryption configured with boolean' , ( ) => {
122+ testWebSocketScheme ( 'http:' , { encrypted : true } , 'wss' ) ;
123+ } ) ;
124+
125+ it ( 'should select wss when running on http page but encryption configured with string' , ( ) => {
126+ testWebSocketScheme ( 'http:' , { encrypted : ENCRYPTION_ON } , 'wss' ) ;
127+ } ) ;
128+
129+ it ( 'should fail when encryption configured with unsupported trust strategy' , ( ) => {
130+ if ( ! webSocketChannelAvailable ) {
131+ return ;
132+ }
133+
134+ const protocolSupplier = ( ) => 'http:' ;
135+
136+ WebSocket = ( ) => {
137+ return {
138+ close : ( ) => {
139+ }
140+ } ;
141+ } ;
142+
143+ const url = urlUtil . parseDatabaseUrl ( 'bolt://localhost:8989' ) ;
144+ const driverConfig = { encrypted : true , trust : 'TRUST_ON_FIRST_USE' } ;
145+ const channelConfig = new ChannelConfig ( url , driverConfig , SERVICE_UNAVAILABLE ) ;
146+
147+ const channel = new WebSocketChannel ( channelConfig , protocolSupplier ) ;
148+
149+ expect ( channel . _error ) . toBeDefined ( ) ;
150+ expect ( channel . _error . name ) . toEqual ( 'Neo4jError' ) ;
151+ } ) ;
152+
153+ it ( 'should generate a warning when encryption turned on for HTTP web page' , ( ) => {
154+ testWarningInMixedEnvironment ( true , 'http' ) ;
155+ testWarningInMixedEnvironment ( ENCRYPTION_ON , 'http' ) ;
156+ } ) ;
157+
158+ it ( 'should generate a warning when encryption turned off for HTTPS web page' , ( ) => {
159+ testWarningInMixedEnvironment ( false , 'https' ) ;
160+ testWarningInMixedEnvironment ( ENCRYPTION_OFF , 'https' ) ;
161+ } ) ;
162+
98163 function testFallbackToLiteralIPv6 ( boltAddress , expectedWsAddress ) {
99164 if ( ! webSocketChannelAvailable ) {
100165 return ;
@@ -122,4 +187,55 @@ describe('WebSocketChannel', () => {
122187 expect ( webSocketChannel . _ws . url ) . toEqual ( expectedWsAddress ) ;
123188 }
124189
190+ function testWebSocketScheme ( windowLocationProtocol , driverConfig , expectedScheme ) {
191+ if ( ! webSocketChannelAvailable ) {
192+ return ;
193+ }
194+
195+ const protocolSupplier = ( ) => windowLocationProtocol ;
196+
197+ // replace real WebSocket with a function that memorizes the url
198+ WebSocket = url => {
199+ return {
200+ url : url ,
201+ close : ( ) => {
202+ }
203+ } ;
204+ } ;
205+
206+ const url = urlUtil . parseDatabaseUrl ( 'bolt://localhost:8989' ) ;
207+ const channelConfig = new ChannelConfig ( url , driverConfig , SERVICE_UNAVAILABLE ) ;
208+ const channel = new WebSocketChannel ( channelConfig , protocolSupplier ) ;
209+
210+ expect ( channel . _ws . url ) . toEqual ( expectedScheme + '://localhost:8989' ) ;
211+ }
212+
213+ function testWarningInMixedEnvironment ( encrypted , scheme ) {
214+ if ( ! webSocketChannelAvailable ) {
215+ return ;
216+ }
217+
218+ // replace real WebSocket with a function that memorizes the url
219+ WebSocket = url => {
220+ return {
221+ url : url ,
222+ close : ( ) => {
223+ }
224+ } ;
225+ } ;
226+
227+ // replace console.warn with a function that memorizes the message
228+ const warnMessages = [ ] ;
229+ console . warn = message => warnMessages . push ( message ) ;
230+
231+ const url = urlUtil . parseDatabaseUrl ( 'bolt://localhost:8989' ) ;
232+ const config = new ChannelConfig ( url , { encrypted : encrypted } , SERVICE_UNAVAILABLE ) ;
233+ const protocolSupplier = ( ) => scheme + ':' ;
234+
235+ const channel = new WebSocketChannel ( config , protocolSupplier ) ;
236+
237+ expect ( channel ) . toBeDefined ( ) ;
238+ expect ( warnMessages . length ) . toEqual ( 1 ) ;
239+ }
240+
125241} ) ;
0 commit comments