-
Notifications
You must be signed in to change notification settings - Fork 31
#4 Add tests for using a proxy. #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4b51907
f208ff4
ca829ca
67fdde3
f0a5080
8daa0bb
7835b32
1b96fad
171ebd4
18590c4
bbc4b9f
5986d0b
d8b9565
5bfc3da
b4b69ce
01ca674
32e6eba
8c5ee0b
516df56
d427d1c
2164dc3
57c6a9f
c08491b
76ec9a3
de3313b
4d23a6d
7c38752
f929aee
8618392
3f09fbc
ea0d8a2
8f25e12
454311b
eeb064e
94a25e2
22661fe
39a0eea
f199f0a
d798325
53707d4
1cddc75
745ea4b
1a1a505
9676c02
40ffa3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import { | ||
| AsyncQueue, | ||
| SSEItem, | ||
| TestHttpHandlers, | ||
| TestHttpServer, | ||
| } from 'launchdarkly-js-test-helpers'; | ||
| import { basicLogger, LDLogger } from '../src'; | ||
|
|
||
| import LDClientNode from '../src/LDClientNode'; | ||
|
|
||
| const sdkKey = 'sdkKey'; | ||
| const flagKey = 'flagKey'; | ||
| const expectedFlagValue = 'yes'; | ||
| const flag = { | ||
| key: flagKey, | ||
| version: 1, | ||
| on: false, | ||
| offVariation: 0, | ||
| variations: [expectedFlagValue, 'no'], | ||
| }; | ||
| const allData = { flags: { flagKey: flag }, segments: {} }; | ||
|
|
||
| describe('When using a proxy', () => { | ||
| let logger: LDLogger; | ||
| let closeable: { close: () => void }[]; | ||
|
|
||
| beforeEach(() => { | ||
| closeable = []; | ||
| logger = basicLogger({ | ||
| destination: () => { }, | ||
| }); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| closeable.forEach((item) => item.close()); | ||
| }); | ||
|
|
||
| it('can use proxy in polling mode', async () => { | ||
| const proxy = await TestHttpServer.startProxy(); | ||
| const server = await TestHttpServer.start(); | ||
| server.forMethodAndPath('get', '/sdk/latest-all', TestHttpHandlers.respondJson(allData)); | ||
|
|
||
| const client = new LDClientNode(sdkKey, { | ||
| baseUri: server.url, | ||
| proxyOptions: { | ||
| host: proxy.hostname, | ||
| port: proxy.port, | ||
| }, | ||
| stream: false, | ||
| sendEvents: false, | ||
| logger, | ||
| }); | ||
|
|
||
| closeable.push(proxy, server, client); | ||
|
|
||
| await client.waitForInitialization(); | ||
| expect(client.initialized()).toBe(true); | ||
|
|
||
| // If the proxy server did not log a request then the SDK did not actually use the proxy | ||
| expect(proxy.requestCount()).toEqual(1); | ||
| const req = await proxy.nextRequest(); | ||
| expect(req.path).toEqual(server.url); | ||
| }); | ||
|
|
||
| it('can use proxy in streaming mode', async () => { | ||
| const proxy = await TestHttpServer.startProxy(); | ||
| const server = await TestHttpServer.start(); | ||
| const events = new AsyncQueue<SSEItem>(); | ||
| events.add({ type: 'put', data: JSON.stringify({ data: allData }) }); | ||
| server.forMethodAndPath('get', '/all', TestHttpHandlers.sseStream(events)); | ||
|
|
||
| const client = new LDClientNode(sdkKey, { | ||
| streamUri: server.url, | ||
| proxyOptions: { | ||
| host: proxy.hostname, | ||
| port: proxy.port, | ||
| }, | ||
| sendEvents: false, | ||
| logger, | ||
| }); | ||
|
|
||
| closeable.push(proxy, server, events, client); | ||
|
|
||
| await client.waitForInitialization(); | ||
| expect(client.initialized()).toBe(true); | ||
|
|
||
| // If the proxy server did not log a request then the SDK did not actually use the proxy | ||
| expect(proxy.requestCount()).toEqual(1); | ||
| const req = await proxy.nextRequest(); | ||
| expect(req.path).toEqual(server.url); | ||
| }); | ||
|
|
||
| it('can use proxy for events', async () => { | ||
| const proxy = await TestHttpServer.startProxy(); | ||
| const pollingServer = await TestHttpServer.start(); | ||
| const eventsServer = await TestHttpServer.start(); | ||
| pollingServer.forMethodAndPath('get', '/sdk/latest-all', TestHttpHandlers.respondJson(allData)); | ||
| eventsServer.forMethodAndPath('post', '/diagnostic', TestHttpHandlers.respond(200)); | ||
|
|
||
| const client = new LDClientNode(sdkKey, { | ||
| baseUri: pollingServer.url, | ||
| eventsUri: eventsServer.url, | ||
| proxyOptions: { | ||
| host: proxy.hostname, | ||
| port: proxy.port, | ||
| }, | ||
| stream: false, | ||
| logger, | ||
| }); | ||
|
|
||
| closeable.push(proxy, pollingServer, eventsServer, client); | ||
|
|
||
| await client.waitForInitialization(); | ||
| expect(client.initialized()).toBe(true); | ||
|
|
||
| // If the proxy server did not log a request then the SDK did not actually use the proxy | ||
| expect(proxy.requestCount()).toEqual(2); | ||
| const req0 = await proxy.nextRequest(); | ||
| const req1 = await proxy.nextRequest(); | ||
| if (req0.path === pollingServer.url) { | ||
| expect(req1.path).toEqual(eventsServer.url); | ||
| } else { | ||
| expect(req0.path).toEqual(eventsServer.url); | ||
| expect(req1.path).toEqual(pollingServer.url); | ||
| } | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| import createHttpsProxyAgent, { HttpsProxyAgentOptions } from 'https-proxy-agent'; | ||
| import * as createHttpsProxyAgent from 'https-proxy-agent'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The typings are odd here. Importing this way will give me the correct behavior. The typings were clearly happy with the other way, but runtime was not. (The downside of typescript being that it cannot really tell what is going on in the non-typescript parts all the time.) |
||
| import { HttpsProxyAgentOptions } from 'https-proxy-agent'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I only care about the .d.ts, so this import is fine. |
||
|
|
||
| import { platform, LDTLSOptions, LDProxyOptions } from '@launchdarkly/js-server-sdk-common'; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's another kind of situation where I would favor using a helper to construct the flag data. I mean, if I understand correctly, all that matters is that we want the flag to return
expectedFlagValueat all times; the literal data here is just boilerplate to accomplish that.