Skip to content

Commit d0774f4

Browse files
authored
Merge pull request #150 from brendandburns/ut
Improve tests.
2 parents 076cd77 + d2b4995 commit d0774f4

File tree

3 files changed

+245
-6
lines changed

3 files changed

+245
-6
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
],
2828
"exclude": [
2929
"src/api.ts",
30+
"src/index.ts",
3031
"src/*_test.ts"
3132
],
3233
"extension": [

src/web-socket-handler.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ export class WebSocketHandler implements WebSocketInterface {
7474
return true;
7575
}
7676

77-
public 'config': KubeConfig;
78-
79-
public constructor(config: KubeConfig) {
80-
this.config = config;
77+
// factory is really just for test injection
78+
public constructor(readonly config: KubeConfig,
79+
readonly socketFactory?:
80+
(uri: string, opts: WebSocket.ClientOptions) => WebSocket) {
8181
}
8282

8383
/**
@@ -109,7 +109,7 @@ export class WebSocketHandler implements WebSocketInterface {
109109
this.config.applytoHTTPSOptions(opts);
110110

111111
return new Promise((resolve, reject) => {
112-
const client = new WebSocket(uri, opts);
112+
const client = (this.socketFactory ? this.socketFactory(uri, opts) : new WebSocket(uri, opts));
113113
let resolved = false;
114114

115115
client.onopen = () => {

src/web-socket-handler_test.ts

Lines changed: 239 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,52 @@
11
import { expect } from 'chai';
2+
import WebSocket = require('isomorphic-ws');
23
import { ReadableStreamBuffer, WritableStreamBuffer } from 'stream-buffers';
34
import { anyFunction, capture, instance, mock, reset, verify } from 'ts-mockito';
45

6+
import { V1Status } from './api';
57
import { KubeConfig } from './config';
6-
import { PortForward } from './portforward';
8+
import { Cluster, Context, User } from './config_types';
79
import { WebSocketHandler, WebSocketInterface } from './web-socket-handler';
810

911
describe('WebSocket', () => {
12+
it('should throw on unknown code', () => {
13+
const osStream = new WritableStreamBuffer();
14+
const errStream = new WritableStreamBuffer();
15+
const buff = Buffer.alloc(30, 20);
16+
const badStream = 10;
17+
18+
expect(() => WebSocketHandler.handleStandardStreams(badStream, buff, osStream, errStream))
19+
.to.throw(`Unknown stream: ${badStream}`);
20+
});
21+
it('should handle a status to end', () => {
22+
const osStream = new WritableStreamBuffer();
23+
const errStream = new WritableStreamBuffer();
24+
25+
const status = new V1Status();
26+
status.message = 'Some message';
27+
status.reason = 'Some Reason';
28+
const data = JSON.stringify(status);
29+
30+
const buff = Buffer.alloc(data.length);
31+
buff.write(data);
32+
33+
const output = WebSocketHandler.handleStandardStreams(WebSocketHandler.StatusStream, buff, osStream, errStream);
34+
35+
expect(osStream.size()).to.equal(0);
36+
expect(errStream.size()).to.equal(0);
37+
/* tslint:disable:no-unused-expression */
38+
expect(output).to.not.be.null;
39+
});
40+
it('should handle empty buffers', () => {
41+
const osStream = new WritableStreamBuffer();
42+
const errStream = new WritableStreamBuffer();
43+
const buff = Buffer.alloc(0, 20);
44+
45+
WebSocketHandler.handleStandardStreams(WebSocketHandler.StdoutStream, buff, osStream, errStream);
46+
47+
expect(osStream.size()).to.equal(0);
48+
expect(errStream.size()).to.equal(0);
49+
});
1050
it('should handle output streams', () => {
1151
const osStream = new WritableStreamBuffer();
1252
const errStream = new WritableStreamBuffer();
@@ -37,4 +77,202 @@ describe('WebSocket', () => {
3777
expect(outputBuffer2[i]).to.equal(fill2);
3878
}
3979
});
80+
it('should throw on a config with no cluster', () => {
81+
const config = new KubeConfig();
82+
const handler = new WebSocketHandler(config);
83+
expect(() => handler.connect('/some/path', null, null)).to.throw('No cluster is defined.');
84+
});
85+
it('should error on bad connection', async () => {
86+
const kc = new KubeConfig();
87+
const server = 'foo.company.nonexistent';
88+
kc.clusters = [
89+
{
90+
name: 'cluster',
91+
server,
92+
} as Cluster,
93+
] as Cluster[];
94+
kc.contexts = [
95+
{
96+
cluster: 'cluster',
97+
user: 'user',
98+
} as Context,
99+
] as Context[];
100+
kc.users = [
101+
{
102+
name: 'user',
103+
} as User,
104+
];
105+
106+
const mockWs = {} as WebSocket;
107+
let uriOut = '';
108+
109+
const handler = new WebSocketHandler(kc, (uri: string, opts: WebSocket.ClientOptions): WebSocket => {
110+
uriOut = uri;
111+
return mockWs as WebSocket;
112+
});
113+
const path = '/some/path';
114+
115+
const promise = handler.connect(path, null, null);
116+
117+
mockWs.onerror({
118+
error: 'some error',
119+
message: 'some message',
120+
type: 'type',
121+
target: mockWs,
122+
});
123+
124+
let rejected = false;
125+
try {
126+
const val = await promise;
127+
} catch (err) {
128+
rejected = true;
129+
}
130+
expect(rejected).to.equal(true);
131+
});
132+
it('should connect properly', async () => {
133+
const kc = new KubeConfig();
134+
const host = 'foo.company.com';
135+
const server = `https://${host}`;
136+
kc.clusters = [
137+
{
138+
name: 'cluster',
139+
server,
140+
} as Cluster,
141+
] as Cluster[];
142+
kc.contexts = [
143+
{
144+
cluster: 'cluster',
145+
user: 'user',
146+
} as Context,
147+
] as Context[];
148+
kc.users = [
149+
{
150+
name: 'user',
151+
} as User,
152+
];
153+
154+
const mockWs = {} as WebSocket;
155+
let uriOut = '';
156+
157+
const handler = new WebSocketHandler(kc, (uri: string, opts: WebSocket.ClientOptions): WebSocket => {
158+
uriOut = uri;
159+
return mockWs as WebSocket;
160+
});
161+
const path = '/some/path';
162+
163+
const promise = handler.connect(path, null, null);
164+
165+
expect(uriOut).to.equal(`wss://${host}${path}`);
166+
167+
const event = {
168+
target: mockWs,
169+
};
170+
mockWs.onopen(event);
171+
const errEvt = {
172+
error: {},
173+
message: 'some message',
174+
type: 'some type',
175+
target: mockWs,
176+
};
177+
mockWs.onmessage({
178+
data: 'string data',
179+
type: 'type',
180+
target: mockWs,
181+
});
182+
const buff = Buffer.alloc(10, 100);
183+
mockWs.onmessage({
184+
data: buff,
185+
type: 'type',
186+
target: mockWs,
187+
});
188+
mockWs.onerror(errEvt);
189+
await promise;
190+
});
191+
it('should connect properly with handlers', async () => {
192+
const kc = new KubeConfig();
193+
const host = 'foo.company.com';
194+
const server = `https://${host}`;
195+
kc.clusters = [
196+
{
197+
name: 'cluster',
198+
server,
199+
} as Cluster,
200+
] as Cluster[];
201+
kc.contexts = [
202+
{
203+
cluster: 'cluster',
204+
user: 'user',
205+
} as Context,
206+
] as Context[];
207+
kc.users = [
208+
{
209+
name: 'user',
210+
} as User,
211+
];
212+
213+
let closeCount = 0;
214+
const mockWs = {
215+
close: () => { closeCount++; },
216+
} as WebSocket;
217+
let uriOut = '';
218+
219+
const handler = new WebSocketHandler(kc, (uri: string, opts: WebSocket.ClientOptions): WebSocket => {
220+
uriOut = uri;
221+
return mockWs as WebSocket;
222+
});
223+
const path = '/some/path';
224+
225+
let textReceived = '';
226+
const textHandler = (text: string): boolean => {
227+
textReceived = text;
228+
return false;
229+
};
230+
231+
let dataReceived: Buffer = Buffer.alloc(0, 0);
232+
let streamNumber = -1;
233+
const binaryHandler = (stream: number, data: Buffer): boolean => {
234+
streamNumber = stream;
235+
dataReceived = data;
236+
return false;
237+
};
238+
239+
const promise = handler.connect(path, textHandler, binaryHandler);
240+
241+
expect(uriOut).to.equal(`wss://${host}${path}`);
242+
243+
const event = {
244+
target: mockWs,
245+
};
246+
mockWs.onopen(event);
247+
const errEvt = {
248+
error: {},
249+
message: 'some message',
250+
type: 'some type',
251+
target: mockWs,
252+
};
253+
mockWs.onmessage({
254+
data: 'string data',
255+
type: 'type',
256+
target: mockWs,
257+
});
258+
const fill = 100;
259+
const size = 10;
260+
const buff = Buffer.alloc(size, fill);
261+
mockWs.onmessage({
262+
data: buff,
263+
type: 'type',
264+
target: mockWs,
265+
});
266+
mockWs.onerror(errEvt);
267+
await promise;
268+
269+
expect(closeCount).to.equal(2);
270+
expect(textReceived).to.equal('string data');
271+
272+
expect(streamNumber).to.equal(fill);
273+
expect(dataReceived.length).to.equal(size - 1);
274+
for (const datum of dataReceived) {
275+
expect(datum).to.equal(fill);
276+
}
277+
});
40278
});

0 commit comments

Comments
 (0)