Skip to content

Commit cbb16a9

Browse files
authored
Add unit test for Solactive transport (#3985)
* Add unit test for Solactive transport * changeset * move exported for testing * requestKeyForParams
1 parent f8ed287 commit cbb16a9

File tree

3 files changed

+184
-3
lines changed

3 files changed

+184
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/solactive-adapter': patch
3+
---
4+
5+
Minor code change to support unit testing

packages/sources/solactive/src/transport/nav.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { HttpTransport } from '@chainlink/external-adapter-framework/transports'
1+
import {
2+
HttpTransport,
3+
HttpTransportConfig,
4+
} from '@chainlink/external-adapter-framework/transports'
25
import { AdapterInputError } from '@chainlink/external-adapter-framework/validation/error'
36
import { BaseEndpointTypes } from '../endpoint/nav'
47

@@ -49,7 +52,7 @@ export const getPasswordFromEnvVar = (clientId: string): string => {
4952
return password
5053
}
5154

52-
export const httpTransport = new HttpTransport<HttpTransportTypes>({
55+
const transportConfig: HttpTransportConfig<HttpTransportTypes> = {
5356
prepareRequests: (params, config) => {
5457
return params.map((param) => {
5558
return {
@@ -105,4 +108,13 @@ export const httpTransport = new HttpTransport<HttpTransportTypes>({
105108
}
106109
})
107110
},
108-
})
111+
}
112+
113+
// Exported for testing
114+
export class NavTransport extends HttpTransport<HttpTransportTypes> {
115+
constructor() {
116+
super(transportConfig)
117+
}
118+
}
119+
120+
export const httpTransport = new NavTransport()
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter'
2+
import { calculateHttpRequestKey } from '@chainlink/external-adapter-framework/cache'
3+
import { metrics } from '@chainlink/external-adapter-framework/metrics'
4+
import { TransportDependencies } from '@chainlink/external-adapter-framework/transports'
5+
import { LoggerFactoryProvider } from '@chainlink/external-adapter-framework/util'
6+
import { makeStub } from '@chainlink/external-adapter-framework/util/testing-utils'
7+
import { inputParameters } from '../../src/endpoint/nav'
8+
import { HttpTransportTypes, NavTransport } from '../../src/transport/nav'
9+
10+
const originalEnv = { ...process.env }
11+
12+
const restoreEnv = () => {
13+
for (const key of Object.keys(process.env)) {
14+
if (key in originalEnv) {
15+
process.env[key] = originalEnv[key]
16+
} else {
17+
delete process.env[key]
18+
}
19+
}
20+
}
21+
22+
const log = jest.fn()
23+
const logger = {
24+
fatal: log,
25+
error: log,
26+
warn: log,
27+
info: log,
28+
debug: log,
29+
trace: log,
30+
}
31+
32+
const loggerFactory = { child: () => logger }
33+
34+
LoggerFactoryProvider.set(loggerFactory)
35+
metrics.initialize()
36+
37+
describe('NavTransport', () => {
38+
const transportName = 'default_single_transport'
39+
const endpointName = 'nav'
40+
41+
const adapterSettings = makeStub('adapterSettings', {
42+
API_ENDPOINT: 'https://clients.solactive.com/api/rest/v1/indices',
43+
WARMUP_SUBSCRIPTION_TTL: 10_000,
44+
CACHE_MAX_AGE: 90_000,
45+
MAX_COMMON_KEY_SIZE: 300,
46+
DEFAULT_CACHE_KEY: 'default-cache-key',
47+
} as unknown as HttpTransportTypes['Settings'])
48+
49+
const subscriptionSet = makeStub('subscriptionSet', {
50+
getAll: jest.fn(),
51+
})
52+
53+
const subscriptionSetFactory = makeStub('subscriptionSetFactory', {
54+
buildSet() {
55+
return subscriptionSet
56+
},
57+
})
58+
59+
const requester = makeStub('requester', {
60+
request: jest.fn(),
61+
})
62+
63+
const responseCache = {
64+
write: jest.fn(),
65+
}
66+
const dependencies = makeStub('dependencies', {
67+
requester,
68+
responseCache,
69+
subscriptionSetFactory,
70+
} as unknown as TransportDependencies<HttpTransportTypes>)
71+
72+
let transport: NavTransport
73+
74+
const requestKeyForParams = (params: typeof inputParameters.validated) => {
75+
const requestKey = calculateHttpRequestKey<HttpTransportTypes>({
76+
context: {
77+
adapterSettings,
78+
inputParameters,
79+
endpointName,
80+
},
81+
data: [params],
82+
transportName,
83+
})
84+
return requestKey
85+
}
86+
87+
beforeEach(async () => {
88+
restoreEnv()
89+
jest.restoreAllMocks()
90+
jest.useFakeTimers()
91+
92+
transport = new NavTransport()
93+
94+
await transport.initialize(dependencies, adapterSettings, endpointName, transportName)
95+
})
96+
97+
it('should make the request', async () => {
98+
const clientId = 'abc123'
99+
const isin = 'A0B1C2D3'
100+
const clientPassword = 'hunter2'
101+
const expectedNav = 123.45
102+
103+
process.env.PASSWORD_ABC123 = clientPassword
104+
105+
const params = makeStub('params', {
106+
clientId,
107+
isin,
108+
})
109+
subscriptionSet.getAll.mockReturnValue([params])
110+
111+
const context = makeStub('context', {
112+
adapterSettings,
113+
endpointName,
114+
} as EndpointContext<HttpTransportTypes>)
115+
116+
const response = makeStub('response', {
117+
response: {
118+
data: {
119+
level: expectedNav,
120+
cost: {},
121+
},
122+
},
123+
timestamps: {},
124+
})
125+
126+
requester.request.mockResolvedValue(response)
127+
128+
await transport.backgroundExecute(context)
129+
130+
const expectedRequestConfig = {
131+
auth: {
132+
username: clientId,
133+
password: clientPassword,
134+
},
135+
baseURL: adapterSettings.API_ENDPOINT,
136+
params: params,
137+
url: `/${clientId}/${isin}/performance`,
138+
}
139+
const expectedRequestKey = requestKeyForParams(params)
140+
141+
const expectedResponse = {
142+
data: {
143+
result: expectedNav,
144+
},
145+
result: expectedNav,
146+
timestamps: {},
147+
}
148+
149+
expect(requester.request).toHaveBeenCalledWith(
150+
expectedRequestKey,
151+
expectedRequestConfig,
152+
undefined,
153+
)
154+
expect(requester.request).toHaveBeenCalledTimes(1)
155+
156+
expect(responseCache.write).toHaveBeenCalledWith(transportName, [
157+
{
158+
params,
159+
response: expectedResponse,
160+
},
161+
])
162+
expect(responseCache.write).toHaveBeenCalledTimes(1)
163+
})
164+
})

0 commit comments

Comments
 (0)