Skip to content

Commit ccb1bb7

Browse files
Merge pull request #95 from smartcontractkit/ggoh/DPA-1306/allow-manual-input-chain-config
[DPA-1306]: fix(chain-config): allow manual input
2 parents ca7e4da + c79a9ae commit ccb1bb7

File tree

4 files changed

+274
-136
lines changed

4 files changed

+274
-136
lines changed

.changeset/strong-ads-jump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@smartcontractkit/operator-ui': minor
3+
---
4+
5+
#updated chain config: allow chain id and account address to be manually provided when no selections are available

src/components/Form/ChainConfigurationForm.test.tsx

Lines changed: 198 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,32 @@ import { ChainTypes } from './ChainTypes'
99
const { getByRole, findByTestId } = screen
1010

1111
describe('ChainConfigurationForm', () => {
12-
it('validates top level input', async () => {
12+
it('validates top level input (with chains available)', async () => {
1313
const handleSubmit = jest.fn()
1414
const initialValues = emptyFormValues()
15+
initialValues.chainType = ChainTypes.EVM
1516

16-
render(
17+
const { container } = render(
1718
<ChainConfigurationForm
1819
initialValues={initialValues}
1920
onSubmit={handleSubmit}
20-
accountsEVM={[]}
21-
chains={[]}
21+
accountsEVM={[
22+
{
23+
address: '0x1111',
24+
chain: {
25+
id: '1111',
26+
},
27+
createdAt: '2021-10-06T00:00:00Z',
28+
isDisabled: false,
29+
},
30+
]}
31+
chains={[
32+
{
33+
id: '1111',
34+
enabled: true,
35+
network: ChainTypes.EVM,
36+
},
37+
]}
2238
p2pKeys={[]}
2339
ocrKeys={[]}
2440
ocr2Keys={[]}
@@ -31,11 +47,43 @@ describe('ChainConfigurationForm', () => {
3147
expect(await findByTestId('chainID-helper-text')).toHaveTextContent(
3248
'Required',
3349
)
50+
51+
await selectChainIdOnUI(container, '1111')
52+
53+
userEvent.click(getByRole('button', { name: /submit/i }))
54+
3455
expect(await findByTestId('accountAddr-helper-text')).toHaveTextContent(
3556
'Required',
3657
)
3758
})
3859

60+
it('validates top level input (with chains NOT available)', async () => {
61+
const handleSubmit = jest.fn()
62+
const initialValues = emptyFormValues()
63+
64+
render(
65+
<ChainConfigurationForm
66+
initialValues={initialValues}
67+
onSubmit={handleSubmit}
68+
accountsEVM={[]}
69+
chains={[]}
70+
p2pKeys={[]}
71+
ocrKeys={[]}
72+
ocr2Keys={[]}
73+
showSubmit
74+
/>,
75+
)
76+
77+
userEvent.click(getByRole('button', { name: /submit/i }))
78+
79+
expect(await findByTestId('chainID-helper-manual-text')).toHaveTextContent(
80+
'Required',
81+
)
82+
expect(
83+
await findByTestId('accountAddr-helper-manual-text'),
84+
).toHaveTextContent('Required')
85+
})
86+
3987
it('validates OCR input', async () => {
4088
const handleSubmit = jest.fn()
4189
const initialValues = emptyFormValues()
@@ -116,7 +164,7 @@ describe('ChainConfigurationForm', () => {
116164
).not.toHaveTextContent('Required')
117165
})
118166

119-
test('should able to create APTOS chain config', async () => {
167+
test('should able to create APTOS chain config (with selection)', async () => {
120168
const handleSubmit = jest.fn()
121169
const initialValues = emptyFormValues()
122170
initialValues.chainType = ChainTypes.EVM
@@ -132,15 +180,7 @@ describe('ChainConfigurationForm', () => {
132180
userEvent.click(getByRole('option', { name: 'APTOS' }))
133181
await screen.findByRole('button', { name: 'APTOS' })
134182

135-
// no easy way to use react testing framework to do what i want,
136-
// had to resort to using #id and querySelector
137-
// formik does not seem to work well with react testing framework
138-
const chainId = container.querySelector('#select-chainID')
139-
expect(chainId).toBeInTheDocument()
140-
// workaround ts lint warning - unable to use chainId!
141-
chainId && userEvent.click(chainId)
142-
userEvent.click(getByRole('option', { name: '2222' }))
143-
await screen.findByRole('button', { name: '2222' })
183+
await selectChainIdOnUI(container, '2222')
144184

145185
const address = container.querySelector('#select-accountAddr')
146186
expect(address).toBeInTheDocument()
@@ -178,68 +218,118 @@ describe('ChainConfigurationForm', () => {
178218
expect(handleSubmit).toHaveBeenCalledTimes(1)
179219
})
180220
})
181-
})
182221

183-
test('should able to create Solana chain config', async () => {
184-
const handleSubmit = jest.fn()
185-
const initialValues = emptyFormValues()
186-
initialValues.chainType = ChainTypes.EVM
187-
initialValues.adminAddr = '0x1234567'
222+
test('should able to create APTOS chain config (with manual input)', async () => {
223+
const handleSubmit = jest.fn()
224+
const initialValues = emptyFormValues()
225+
initialValues.chainType = ChainTypes.EVM
188226

189-
const { container } = renderChainConfigurationForm(
190-
initialValues,
191-
handleSubmit,
192-
)
227+
renderChainConfigurationForm(initialValues, handleSubmit, [], {
228+
aptosKeys: {
229+
results: [],
230+
},
231+
solanaKeys: {
232+
results: [],
233+
},
234+
})
235+
236+
const chainType = getByRole('button', { name: 'EVM' })
237+
userEvent.click(chainType)
238+
userEvent.click(getByRole('option', { name: 'APTOS' }))
239+
await screen.findByRole('button', { name: 'APTOS' })
240+
241+
const chainIdTextBox = getByRole('textbox', { name: /chain id \*/i })
242+
userEvent.type(chainIdTextBox, '2222')
243+
244+
const accountAddrTextBox = getByRole('textbox', {
245+
name: /account address \*/i,
246+
})
247+
userEvent.type(accountAddrTextBox, '0x123')
248+
249+
await userEvent.click(getByRole('button', { name: /submit/i }))
250+
251+
await waitFor(() => {
252+
expect(handleSubmit).toHaveBeenCalledWith({
253+
accountAddr: '0x123',
254+
accountAddrPubKey: '',
255+
adminAddr: '',
256+
chainID: '2222',
257+
chainType: 'APTOS',
258+
fluxMonitorEnabled: false,
259+
ocr1Enabled: false,
260+
ocr1IsBootstrap: false,
261+
ocr1KeyBundleID: '',
262+
ocr1Multiaddr: '',
263+
ocr1P2PPeerID: '',
264+
ocr2CommitPluginEnabled: false,
265+
ocr2Enabled: false,
266+
ocr2ExecutePluginEnabled: false,
267+
ocr2ForwarderAddress: '',
268+
ocr2IsBootstrap: false,
269+
ocr2KeyBundleID: '',
270+
ocr2MedianPluginEnabled: false,
271+
ocr2MercuryPluginEnabled: false,
272+
ocr2Multiaddr: '',
273+
ocr2P2PPeerID: '',
274+
ocr2RebalancerPluginEnabled: false,
275+
})
276+
expect(handleSubmit).toHaveBeenCalledTimes(1)
277+
})
278+
})
279+
280+
test('should able to create Solana chain config', async () => {
281+
const handleSubmit = jest.fn()
282+
const initialValues = emptyFormValues()
283+
initialValues.chainType = ChainTypes.EVM
284+
initialValues.adminAddr = '0x1234567'
193285

194-
const chainType = getByRole('button', { name: 'EVM' })
195-
userEvent.click(chainType)
196-
userEvent.click(getByRole('option', { name: 'SOLANA' }))
197-
await screen.findByRole('button', { name: 'SOLANA' })
198-
199-
// no easy way to use react testing framework to do what i want,
200-
// had to resort to using #id and querySelector
201-
// formik does not seem to work well with react testing framework
202-
const chainId = container.querySelector('#select-chainID')
203-
expect(chainId).toBeInTheDocument()
204-
// workaround ts lint warning - unable to use chainId!
205-
chainId && userEvent.click(chainId)
206-
userEvent.click(getByRole('option', { name: '3333' }))
207-
await screen.findByRole('button', { name: '3333' })
208-
209-
const address = container.querySelector('#select-accountAddr')
210-
expect(address).toBeInTheDocument()
211-
address && userEvent.click(address)
212-
userEvent.click(getByRole('option', { name: 'solana_xxxx' }))
213-
await screen.findByRole('button', { name: 'solana_xxxx' })
214-
215-
await userEvent.click(getByRole('button', { name: /submit/i }))
216-
217-
await waitFor(() => {
218-
expect(handleSubmit).toHaveBeenCalledWith({
219-
accountAddr: 'solana_xxxx',
220-
accountAddrPubKey: '',
221-
adminAddr: '0x1234567',
222-
chainID: '3333',
223-
chainType: 'SOLANA',
224-
fluxMonitorEnabled: false,
225-
ocr1Enabled: false,
226-
ocr1IsBootstrap: false,
227-
ocr1KeyBundleID: '',
228-
ocr1Multiaddr: '',
229-
ocr1P2PPeerID: '',
230-
ocr2CommitPluginEnabled: false,
231-
ocr2Enabled: false,
232-
ocr2ExecutePluginEnabled: false,
233-
ocr2ForwarderAddress: '',
234-
ocr2IsBootstrap: false,
235-
ocr2KeyBundleID: '',
236-
ocr2MedianPluginEnabled: false,
237-
ocr2MercuryPluginEnabled: false,
238-
ocr2Multiaddr: '',
239-
ocr2P2PPeerID: '',
240-
ocr2RebalancerPluginEnabled: false,
286+
const { container } = renderChainConfigurationForm(
287+
initialValues,
288+
handleSubmit,
289+
)
290+
291+
const chainType = getByRole('button', { name: 'EVM' })
292+
userEvent.click(chainType)
293+
userEvent.click(getByRole('option', { name: 'SOLANA' }))
294+
await screen.findByRole('button', { name: 'SOLANA' })
295+
296+
await selectChainIdOnUI(container, '3333')
297+
298+
const address = container.querySelector('#select-accountAddr')
299+
expect(address).toBeInTheDocument()
300+
address && userEvent.click(address)
301+
userEvent.click(getByRole('option', { name: 'solana_xxxx' }))
302+
await screen.findByRole('button', { name: 'solana_xxxx' })
303+
304+
await userEvent.click(getByRole('button', { name: /submit/i }))
305+
306+
await waitFor(() => {
307+
expect(handleSubmit).toHaveBeenCalledWith({
308+
accountAddr: 'solana_xxxx',
309+
accountAddrPubKey: '',
310+
adminAddr: '0x1234567',
311+
chainID: '3333',
312+
chainType: 'SOLANA',
313+
fluxMonitorEnabled: false,
314+
ocr1Enabled: false,
315+
ocr1IsBootstrap: false,
316+
ocr1KeyBundleID: '',
317+
ocr1Multiaddr: '',
318+
ocr1P2PPeerID: '',
319+
ocr2CommitPluginEnabled: false,
320+
ocr2Enabled: false,
321+
ocr2ExecutePluginEnabled: false,
322+
ocr2ForwarderAddress: '',
323+
ocr2IsBootstrap: false,
324+
ocr2KeyBundleID: '',
325+
ocr2MedianPluginEnabled: false,
326+
ocr2MercuryPluginEnabled: false,
327+
ocr2Multiaddr: '',
328+
ocr2P2PPeerID: '',
329+
ocr2RebalancerPluginEnabled: false,
330+
})
331+
expect(handleSubmit).toHaveBeenCalledTimes(1)
241332
})
242-
expect(handleSubmit).toHaveBeenCalledTimes(1)
243333
})
244334
})
245335

@@ -273,6 +363,31 @@ function emptyFormValues(): FormValues {
273363
function renderChainConfigurationForm(
274364
initialValues: FormValues,
275365
onSubmit: (x: FormValues) => void,
366+
chains: ChainsPayload_ResultsFields[] | undefined = [
367+
{
368+
id: '1111',
369+
enabled: true,
370+
network: 'evm',
371+
},
372+
{
373+
id: '2222',
374+
enabled: true,
375+
network: 'aptos',
376+
},
377+
{
378+
id: '3333',
379+
enabled: true,
380+
network: 'solana',
381+
},
382+
],
383+
accountsNonEvm: FetchNonEvmKeys | undefined = {
384+
aptosKeys: {
385+
results: [{ account: '0x123', id: '2222' }],
386+
},
387+
solanaKeys: {
388+
results: [{ id: 'solana_xxxx' }],
389+
},
390+
},
276391
) {
277392
return render(
278393
<ChainConfigurationForm
@@ -288,35 +403,21 @@ function renderChainConfigurationForm(
288403
isDisabled: false,
289404
},
290405
]}
291-
accountsNonEvm={{
292-
aptosKeys: {
293-
results: [{ account: '0x123', id: '2222' }],
294-
},
295-
solanaKeys: {
296-
results: [{ id: 'solana_xxxx' }],
297-
},
298-
}}
299-
chains={[
300-
{
301-
id: '1111',
302-
enabled: true,
303-
network: 'evm',
304-
},
305-
{
306-
id: '2222',
307-
enabled: true,
308-
network: 'aptos',
309-
},
310-
{
311-
id: '3333',
312-
enabled: true,
313-
network: 'solana',
314-
},
315-
]}
406+
accountsNonEvm={accountsNonEvm}
407+
chains={chains}
316408
p2pKeys={[]}
317409
ocrKeys={[]}
318410
ocr2Keys={[]}
319411
showSubmit
320412
/>,
321413
)
322414
}
415+
416+
async function selectChainIdOnUI(container: HTMLElement, chainId: string) {
417+
const chainIdSelect = container.querySelector('#select-chainID')
418+
expect(chainIdSelect).toBeInTheDocument()
419+
// workaround ts lint warning - require check for null
420+
chainIdSelect && userEvent.click(chainIdSelect)
421+
userEvent.click(getByRole('option', { name: chainId }))
422+
await screen.findByRole('button', { name: chainId })
423+
}

0 commit comments

Comments
 (0)