1
1
import Vue from 'vue'
2
+ import WS from 'jest-websocket-mock'
2
3
import WebSocketManager from '../src/templates/WebSocketManager'
3
4
5
+ let ws = { } as WS
6
+ let client = { } as WebSocketManager
7
+
4
8
describe ( 'WebSocketManager' , ( ) => {
5
- const getInstance = ( ) => {
9
+ beforeEach ( async ( ) => {
6
10
const emitter = new Vue ( )
7
- return new WebSocketManager ( 'ws://localhost:8025' , emitter , 1000 )
8
- }
11
+
12
+ // create a WS instance, listening on port 8025 on localhost.
13
+ ws = new WS ( 'ws://localhost:8025' )
14
+
15
+ // Connect to the mock websocket server.
16
+ client = new WebSocketManager ( 'ws://localhost:8025' , emitter , 1000 )
17
+
18
+ // Wait for the server to have established the connection.
19
+ await ws . connected
20
+ } )
9
21
10
22
afterEach ( ( ) => {
11
23
jest . restoreAllMocks ( )
24
+ WS . clean ( )
12
25
} )
13
26
14
- test ( 'constructor sets the properties and invokes connect method' , ( ) => {
15
- // Track connect method calls.
16
- jest . spyOn ( WebSocketManager . prototype , 'connect' )
27
+ test ( 'connect method establishes websocket connection' , ( ) => {
28
+ // connect method is invoked by the constructor.
17
29
18
- const instance = getInstance ( )
30
+ // Assertions
31
+ expect ( client . url ) . toBe ( 'ws://localhost:8025' )
32
+ expect ( client . emitter ) . toBeInstanceOf ( Vue )
33
+ expect ( client . reconnectInterval ) . toBe ( 1000 )
34
+ expect ( client . ws ) . toBeInstanceOf ( WebSocket )
35
+ } )
36
+
37
+ test ( 'emits an event of the type `message` on receiving the data as a string' , ( ) => {
38
+ // Mock
39
+ Vue . prototype . $emit = jest . fn ( )
40
+
41
+ // Send dato the client.
42
+ ws . send ( 'Test message' )
19
43
20
44
// Assertions
21
- expect ( instance . url ) . toBe ( 'ws://localhost:8025' )
22
- expect ( instance . emitter ) . toBeInstanceOf ( Vue )
23
- expect ( instance . reconnectInterval ) . toBe ( 1000 )
24
- expect ( instance . ws ) . toBeInstanceOf ( WebSocket )
25
- expect ( instance . connect ) . toBeCalled ( )
45
+ expect ( Vue . prototype . $emit . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'message' )
46
+ expect ( Vue . prototype . $emit . mock . calls [ 0 ] [ 1 ] . data ) . toBe ( 'Test message' )
26
47
} )
27
48
28
- test ( 'connect method establishes websocket connection' , ( ) => {
29
- // connect method is invoked by the constructor.
30
- const instance = getInstance ( )
49
+ test ( 'emits an event of the type based on value for the event key when the data is an object' , ( ) => {
50
+ // Mock
51
+ Vue . prototype . $emit = jest . fn ( )
52
+
53
+ // Send data to the client.
54
+ ws . send ( JSON . stringify ( { event : 'socket' , data : 'Hello world' } ) )
31
55
32
56
// Assertions
33
- expect ( instance . reconnectInterval ) . toBe ( 1000 )
34
- expect ( instance . ws ) . toBeInstanceOf ( WebSocket )
57
+ expect ( Vue . prototype . $emit . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'socket' )
58
+ expect ( Vue . prototype . $emit . mock . calls [ 0 ] [ 1 ] ) . toBe ( 'Hello world' )
35
59
} )
36
60
37
- test ( 'ready method ensures the websocket connection is open' , ( ) => {
38
- const instance = getInstance ( )
61
+ test ( 'attempts reconnection on a close event which is not normal' , async ( ) => {
62
+ // Mocks
63
+ client . connect = jest . fn ( )
64
+ jest . spyOn ( global , 'setTimeout' )
39
65
66
+ // Close the connection with a code that is not normal.
67
+ ws . close ( { wasClean : false , code : 1003 , reason : 'nope' } )
68
+
69
+ // Assertions
70
+ expect ( global . setTimeout ) . toBeCalledWith ( expect . any ( Function ) , 1000 )
71
+
72
+ // Wait for 1s and assert for the reconnection attempt.
73
+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) )
74
+ expect ( client . connect ) . toBeCalled ( )
75
+ } )
76
+
77
+ test ( 'closes the websocket connection on error event' , ( ) => {
78
+ // Mocks
79
+ console . error = jest . fn ( ) ; // eslint-disable-line
80
+ client . ws . close = jest . fn ( )
81
+
82
+ // Simulate an error and close the connection.
83
+ ws . error ( )
84
+
85
+ // Assertions
86
+ expect ( console . error ) . toBeCalled ( ) ; // eslint-disable-line
87
+ expect ( client . ws . close ) . toBeCalled ( )
88
+ } )
89
+
90
+ test ( 'ready method ensures the websocket connection is open' , ( ) => {
40
91
// The promise is resolved straightaway if the readyState is not 1.
41
- expect ( instance . ready ( ) ) . resolves . toBe ( undefined )
92
+ expect ( client . ready ( ) ) . resolves . toBe ( undefined )
42
93
} )
43
94
44
95
test ( 'send method transmits the data received as a string' , async ( ) => {
45
- const instance = getInstance ( )
46
-
47
96
// Mock implementations of other function calls.
48
- jest . spyOn ( instance , 'ready' ) . mockResolvedValue ( Promise . resolve ( ) )
49
- jest . spyOn ( instance . ws , 'send' ) . mockReturnValue ( undefined )
97
+ jest . spyOn ( client , 'ready' ) . mockResolvedValue ( Promise . resolve ( ) )
98
+ jest . spyOn ( client . ws , 'send' ) . mockReturnValue ( undefined )
50
99
51
100
// Invoke send method with the message as a string.
52
- await instance . send ( 'Hello world' )
101
+ await client . send ( 'Hello world' )
53
102
54
103
// Assertions
55
- expect ( instance . ready ) . toBeCalled ( )
56
- expect ( instance . ws . send ) . toBeCalledWith ( 'Hello world' )
104
+ expect ( client . ready ) . toBeCalled ( )
105
+ expect ( client . ws . send ) . toBeCalledWith ( 'Hello world' )
57
106
} )
58
107
59
108
test ( 'send method transmits the data received as an object' , async ( ) => {
60
- const instance = getInstance ( )
61
-
62
109
// Mock implementations of other function calls.
63
- jest . spyOn ( instance , 'ready' ) . mockResolvedValue ( Promise . resolve ( ) )
64
- jest . spyOn ( instance . ws , 'send' ) . mockReturnValue ( undefined )
110
+ jest . spyOn ( client , 'ready' ) . mockResolvedValue ( Promise . resolve ( ) )
111
+ jest . spyOn ( client . ws , 'send' ) . mockReturnValue ( undefined )
65
112
66
113
// Invoke send method with the message as an object.
67
114
const msg = {
@@ -74,23 +121,21 @@ describe('WebSocketManager', () => {
74
121
. slice ( 2 ) ,
75
122
date : Date . now ( )
76
123
}
77
- await instance . send ( msg )
124
+ await client . send ( msg )
78
125
79
126
// Assertions
80
- expect ( instance . ready ) . toBeCalled ( )
81
- expect ( instance . ws . send ) . toBeCalledWith ( JSON . stringify ( msg ) )
127
+ expect ( client . ready ) . toBeCalled ( )
128
+ expect ( client . ws . send ) . toBeCalledWith ( JSON . stringify ( msg ) )
82
129
} )
83
130
84
131
test ( 'close method closes the websocket connection' , ( ) => {
85
- const instance = getInstance ( )
86
-
87
132
// Track WebSocket instance close method calls.
88
- instance . ws . close = jest . fn ( )
133
+ client . ws . close = jest . fn ( )
89
134
90
135
// Invoke close method.
91
- instance . close ( )
136
+ client . close ( )
92
137
93
138
// Assertion
94
- expect ( instance . ws . close ) . toBeCalled ( )
139
+ expect ( client . ws . close ) . toBeCalled ( )
95
140
} )
96
141
} )
0 commit comments