Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions packages/davinci-client/src/lib/client.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,8 @@ export async function davinci<ActionType extends ActionTypes = ActionTypes>({
| FidoAuthenticationInputValue,
index?: number,
) {
try {
store.dispatch(nodeSlice.actions.update({ id, value, index }));
return null;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : String(err);
return {
type: 'internal_error',
error: { message: errorMessage, type: 'internal_error' },
};
}
store.dispatch(nodeSlice.actions.update({ id, value, index }));
return null;
};
},

Expand Down
146 changes: 141 additions & 5 deletions packages/davinci-client/src/lib/node.reducer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ describe('The node collector reducer', () => {
]);
});

it('should throw with no collectors', () => {
it('should add an UnknownCollector with error when no matching collector is found', () => {
const action = {
type: 'node/update',
payload: {
Expand Down Expand Up @@ -377,10 +377,13 @@ describe('The node collector reducer', () => {
},
},
];
expect(() => nodeCollectorReducer(state, action)).toThrowError('No collector found to update');
const result = nodeCollectorReducer(state, action);
const errorCollector = result.find((c) => c.id === 'submit-1');
expect(errorCollector?.error).toBe('No collector found to update');
expect(errorCollector?.category).toBe('UnknownCollector');
});

it('should throw with no Action Collector', () => {
it('should set error on ActionCollector when update is attempted', () => {
const action = {
type: 'node/update',
payload: {
Expand Down Expand Up @@ -420,8 +423,141 @@ describe('The node collector reducer', () => {
},
},
];
expect(() => nodeCollectorReducer(state, action)).toThrowError(
'ActionCollectors are read-only',
const result = nodeCollectorReducer(state, action);
const collector = result.find((c) => c.id === 'submit-1');
expect(collector?.error).toBe('ActionCollectors are read-only');
});

it('should set error on NoValueCollector when update is attempted', () => {
const state: QrCodeCollector[] = [
{
category: 'NoValueCollector',
error: null,
type: 'QrCodeCollector',
id: 'qr-0',
name: 'qr',
output: {
key: 'qr',
label: 'QR Code',
type: 'QR_CODE',
src: 'data:image/png;base64,abc',
},
},
];
const action = { type: 'node/update', payload: { id: 'qr-0', value: 'anything' } };
const result = nodeCollectorReducer(state, action);
expect(result.find((c) => c.id === 'qr-0')?.error).toBe(
'NoValueCollectors, like ReadOnlyCollectors, are read-only',
);
});

it('should set error on collector when value is undefined', () => {
const state: TextCollector[] = [
{
category: 'SingleValueCollector',
error: null,
type: 'TextCollector',
id: 'username-0',
name: 'username',
input: { key: 'username', value: '', type: 'TEXT' },
output: { key: 'username', label: 'Username', type: 'TEXT', value: '' },
},
];
const action = {
type: 'node/update',
payload: { id: 'username-0', value: undefined as unknown as string },
};
const result = nodeCollectorReducer(state, action);
expect(result.find((c) => c.id === 'username-0')?.error).toBe(
'Value argument cannot be undefined',
);
});

it('should clear error on collector when a valid value is provided after an error', () => {
const state: TextCollector[] = [
{
category: 'SingleValueCollector',
error: 'Value argument must be a string',
type: 'TextCollector',
id: 'username-0',
name: 'username',
input: { key: 'username', value: '', type: 'TEXT' },
output: { key: 'username', label: 'Username', type: 'TEXT', value: '' },
},
];
const action = { type: 'node/update', payload: { id: 'username-0', value: 'validString' } };
const result = nodeCollectorReducer(state, action);
const collector = result.find((c) => c.id === 'username-0') as TextCollector | undefined;
expect(collector?.error).toBeNull();
expect(collector?.input.value).toBe('validString');
});

it('should set error on SingleValueCollector when value is not a string', () => {
const state: TextCollector[] = [
{
category: 'SingleValueCollector',
error: null,
type: 'TextCollector',
id: 'username-0',
name: 'username',
input: { key: 'username', value: '', type: 'TEXT' },
output: { key: 'username', label: 'Username', type: 'TEXT', value: '' },
},
];
const action = {
type: 'node/update',
payload: { id: 'username-0', value: 42 as unknown as string },
};
const result = nodeCollectorReducer(state, action);
expect(result.find((c) => c.id === 'username-0')?.error).toBe(
'Value argument must be a string',
);
});

it('should set error on MultiValueCollector when value is an object', () => {
const state: MultiSelectCollector[] = [
{
category: 'MultiValueCollector',
error: null,
type: 'MultiSelectCollector',
id: 'multi-0',
name: 'multi',
input: { key: 'multi', value: [], type: 'MULTI_SELECT', validation: null },
output: {
key: 'multi',
label: 'Multi',
type: 'MULTI_SELECT',
value: [],
options: [{ label: 'A', value: 'a' }],
},
},
];
const action = {
type: 'node/update',
payload: { id: 'multi-0', value: { bad: true } as unknown as string },
};
const result = nodeCollectorReducer(state, action);
expect(result.find((c) => c.id === 'multi-0')?.error).toBe(
'MultiValueCollector does not accept an object',
);
});

it('should set error on PollingCollector when update is attempted', () => {
const state: PollingCollector[] = [
{
category: 'SingleValueAutoCollector',
error: null,
type: 'PollingCollector',
id: 'poll-0',
name: 'poll',
input: { key: 'poll', value: '', type: 'POLLING' },
output: { key: 'poll', type: 'POLLING', config: { pollInterval: 1000, pollRetries: 3 } },
},
];
const action = { type: 'node/update', payload: { id: 'poll-0', value: 'anything' } };
const result = nodeCollectorReducer(state, action);
expect(result.find((c) => c.id === 'poll-0')?.error).toBe(
'This collector type does not support value updates',
);
});

Expand Down
Loading
Loading