-
Notifications
You must be signed in to change notification settings - Fork 308
/
setup.ts
137 lines (120 loc) · 4.22 KB
/
setup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { ServerInstance } from '@chainlink/external-adapter-framework'
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
import { WebSocketClassProvider } from '@chainlink/external-adapter-framework/transports'
import { Server, WebSocket } from 'mock-socket'
import { AddressInfo } from 'net'
import * as nock from 'nock'
import * as process from 'process'
import request, { SuperTest, Test } from 'supertest'
import { price } from '../../src/endpoint'
import dxfeed from '@chainlink/dxfeed-adapter'
export type SuiteContext = {
req: SuperTest<Test> | null
server: () => Promise<ServerInstance>
fastify?: ServerInstance
}
export type EnvVariables = { [key: string]: string }
export type TestOptions = { cleanNock?: boolean; fastify?: boolean }
export const setupExternalAdapterTest = (
envVariables: NodeJS.ProcessEnv,
context: SuiteContext,
options: TestOptions = { cleanNock: true, fastify: false },
): void => {
let fastify: ServerInstance
beforeAll(async () => {
process.env['METRICS_ENABLED'] = 'false'
for (const key in envVariables) {
process.env[key] = envVariables[key]
}
if (process.env['RECORD']) {
nock.recorder.rec()
}
fastify = await context.server()
// eslint-disable-next-line require-atomic-updates
context.req = request(`localhost:${(fastify.server.address() as AddressInfo).port}`)
// Only for edge cases when someone needs to use the fastify instance outside this function
if (options.fastify) {
// eslint-disable-next-line require-atomic-updates
context.fastify = fastify
}
})
afterAll(async () => {
if (process.env['RECORD']) {
nock.recorder.play()
}
const asd = 123
if (asd > 0) {
// Options.cleanNock) {
nock.restore()
nock.cleanAll()
nock.enableNetConnect()
}
await fastify.close()
})
}
/**
* Sets the mocked websocket instance in the provided provider class.
* We need this here, because the tests will connect using their instance of WebSocketClassProvider;
* fetching from this library to the \@chainlink/ea-bootstrap package would access _another_ instance
* of the same constructor. Although it should be a singleton, dependencies are different so that
* means that the static classes themselves are also different.
*
* @param provider - singleton WebSocketClassProvider
*/
export const mockWebSocketProvider = (provider: typeof WebSocketClassProvider): void => {
// Extend mock WebSocket class to bypass protocol headers error
class MockWebSocket extends WebSocket {
constructor(url: string, protocol: string | string[] | Record<string, string> | undefined) {
super(url, protocol instanceof Object ? undefined : protocol)
}
// This is part of the 'ws' node library but not the common interface, but it's used in our WS transport
removeAllListeners() {
for (const eventType in this.listeners) {
// We have to manually check because the mock-socket library shares this instance, and adds the server listeners to the same obj
if (!eventType.startsWith('server')) {
delete this.listeners[eventType]
}
}
}
}
// Need to disable typing, the mock-socket impl does not implement the ws interface fully
provider.set(MockWebSocket as any) // eslint-disable-line @typescript-eslint/no-explicit-any
}
export const mockWebSocketServer = (URL: string): Server => {
const wsReponse = [
{
data: [
'Quote',
['TSLA:BFX', 0, 0, 0, 1670868378000, 'V', 170.0, 148.0, 1670868370000, 'V', 172.0, 100.0],
],
channel: '/service/data',
},
]
const mockWsServer = new Server(URL, { mock: false })
mockWsServer.on('connection', (socket) => {
socket.send(
JSON.stringify([
{
channel: '/meta/connect',
},
]),
)
socket.on('message', () => {
socket.send(JSON.stringify(wsReponse))
})
})
return mockWsServer
}
export const createAdapter = () => {
return new Adapter({
name: 'TEST',
defaultEndpoint: price.name,
endpoints: [price],
config: dxfeed.config,
})
}
export function setEnvVariables(envVariables: NodeJS.ProcessEnv): void {
for (const key in envVariables) {
process.env[key] = envVariables[key]
}
}