|
19 | 19 | import wsChannel from '../../src/v1/internal/ch-websocket'; |
20 | 20 | import ChannelConfig from '../../src/v1/internal/ch-config'; |
21 | 21 | import urlUtil from '../../src/v1/internal/url-util'; |
22 | | -import {SERVICE_UNAVAILABLE} from '../../src/v1/error'; |
| 22 | +import {Neo4jError, SERVICE_UNAVAILABLE} from '../../src/v1/error'; |
23 | 23 | import {setTimeoutMock} from './timers-util'; |
| 24 | +import {ENCRYPTION_OFF, ENCRYPTION_ON} from '../../src/v1/internal/util'; |
24 | 25 |
|
25 | 26 | describe('WebSocketChannel', () => { |
26 | 27 |
|
@@ -94,6 +95,54 @@ describe('WebSocketChannel', () => { |
94 | 95 | } |
95 | 96 | }); |
96 | 97 |
|
| 98 | + it('should select wss when running on https page', () => { |
| 99 | + testWebSocketScheme('https:', {}, 'wss'); |
| 100 | + }); |
| 101 | + |
| 102 | + it('should select ws when running on http page', () => { |
| 103 | + testWebSocketScheme('http:', {}, 'ws'); |
| 104 | + }); |
| 105 | + |
| 106 | + it('should select ws when running on https page but encryption turned off with boolean', () => { |
| 107 | + testWebSocketScheme('https:', {encrypted: false}, 'ws'); |
| 108 | + }); |
| 109 | + |
| 110 | + it('should select ws when running on https page but encryption turned off with string', () => { |
| 111 | + testWebSocketScheme('https:', {encrypted: ENCRYPTION_OFF}, 'ws'); |
| 112 | + }); |
| 113 | + |
| 114 | + it('should select wss when running on http page but encryption configured with boolean', () => { |
| 115 | + testWebSocketScheme('http:', {encrypted: true}, 'wss'); |
| 116 | + }); |
| 117 | + |
| 118 | + it('should select wss when running on http page but encryption configured with string', () => { |
| 119 | + testWebSocketScheme('http:', {encrypted: ENCRYPTION_ON}, 'wss'); |
| 120 | + }); |
| 121 | + |
| 122 | + it('should fail when encryption configured with unsupported trust strategy', () => { |
| 123 | + if (!webSocketChannelAvailable) { |
| 124 | + return; |
| 125 | + } |
| 126 | + |
| 127 | + const protocolSupplier = () => 'http:'; |
| 128 | + |
| 129 | + WebSocket = () => { |
| 130 | + return { |
| 131 | + close: () => { |
| 132 | + } |
| 133 | + }; |
| 134 | + }; |
| 135 | + |
| 136 | + const url = urlUtil.parseDatabaseUrl('bolt://localhost:8989'); |
| 137 | + const driverConfig = {encrypted: true, trust: 'TRUST_ON_FIRST_USE'}; |
| 138 | + const channelConfig = new ChannelConfig(url, driverConfig, SERVICE_UNAVAILABLE); |
| 139 | + |
| 140 | + const channel = new WebSocketChannel(channelConfig, protocolSupplier); |
| 141 | + |
| 142 | + expect(channel._error).toBeDefined(); |
| 143 | + expect(channel._error.name).toEqual('Neo4jError'); |
| 144 | + }); |
| 145 | + |
97 | 146 | function testFallbackToLiteralIPv6(boltAddress, expectedWsAddress) { |
98 | 147 | if (!webSocketChannelAvailable) { |
99 | 148 | return; |
@@ -121,4 +170,27 @@ describe('WebSocketChannel', () => { |
121 | 170 | expect(webSocketChannel._ws.url).toEqual(expectedWsAddress); |
122 | 171 | } |
123 | 172 |
|
| 173 | + function testWebSocketScheme(windowLocationProtocol, driverConfig, expectedScheme) { |
| 174 | + if (!webSocketChannelAvailable) { |
| 175 | + return; |
| 176 | + } |
| 177 | + |
| 178 | + const protocolSupplier = () => windowLocationProtocol; |
| 179 | + |
| 180 | + // replace real WebSocket with a function that memorizes the url |
| 181 | + WebSocket = url => { |
| 182 | + return { |
| 183 | + url: url, |
| 184 | + close: () => { |
| 185 | + } |
| 186 | + }; |
| 187 | + }; |
| 188 | + |
| 189 | + const url = urlUtil.parseDatabaseUrl('bolt://localhost:8989'); |
| 190 | + const channelConfig = new ChannelConfig(url, driverConfig, SERVICE_UNAVAILABLE); |
| 191 | + const channel = new WebSocketChannel(channelConfig, protocolSupplier); |
| 192 | + |
| 193 | + expect(channel._ws.url).toEqual(expectedScheme + '://localhost:8989'); |
| 194 | + } |
| 195 | + |
124 | 196 | }); |
0 commit comments