Skip to content

Commit ec4d5b7

Browse files
committed
fix(davinci-client): event-name-and-formData
defaults event name to continue when we don't have an event name (p1 forms) and ensures we don't add undefined to the formData keys
1 parent 6cdc7b8 commit ec4d5b7

File tree

8 files changed

+248
-10
lines changed

8 files changed

+248
-10
lines changed

e2e/davinci-suites/src/form-fields.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,19 @@ test('should render form validation fields', async ({ page }) => {
7070

7171
await page.getByRole('textbox', { name: 'Email Address' }).fill('[email protected]');
7272
await expect(page.getByText('Not a valid email')).not.toBeVisible();
73+
74+
await page.getByRole('textbox', { name: 'Password' }).fill('1234');
75+
76+
const requestPromise = page.waitForRequest((request) => request.url().includes('/customForm'));
77+
await page.getByRole('button', { name: 'Submit' }).click();
78+
79+
const request = await requestPromise;
80+
81+
console.log(request.postDataJSON().parameters.data.formData);
82+
83+
expect(request.postDataJSON().parameters.data.formData).toEqual({
84+
'user.username': '',
85+
'user.email': '[email protected]',
86+
'user.password': '1234',
87+
});
7388
});

packages/davinci-client/src/lib/collector.utils.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,18 @@ export function returnSingleValueCollector<
153153
value: '',
154154
type: field.type,
155155
},
156-
output: {
157-
key: field.key,
158-
label: field.label,
159-
type: field.type,
160-
// No default or existing value is passed
161-
},
156+
output:
157+
field.key !== undefined
158+
? {
159+
key: field.key,
160+
label: field.label,
161+
type: field.type,
162+
// No default or existing value is passed
163+
}
164+
: {
165+
label: field.label,
166+
type: field.type,
167+
},
162168
} as InferSingleValueCollectorType<CollectorType>;
163169
} else if (collectorType === 'SingleSelectCollector') {
164170
/**

packages/davinci-client/src/lib/davinci.utils.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { next0 } from './mock-data/davinci.next.mock.js';
1313
import { DaVinciCacheEntry } from './davinci.types.js';
1414
import { error0a, error3 } from './mock-data/davinci.error.mock.js';
1515
import { success0 } from './mock-data/davinci.success.mock.js';
16+
import { nodeNext1 } from './mock-data/node.next.mock.js';
1617

1718
describe('transformSubmitRequest', () => {
1819
it('should transform node state to DaVinciRequest for next request', () => {
@@ -327,4 +328,23 @@ describe('handleResponse', () => {
327328
const [action] = dispatch.mock.calls[0];
328329
expect(action.type).toBe('node/failure');
329330
});
331+
it('should transformSubmitRequest', () => {
332+
const n = nodeNext1 as ContinueNode;
333+
const result = transformSubmitRequest(n);
334+
expect(result).toEqual({
335+
eventName: 'continue',
336+
id: 'elvr5pbwzn',
337+
interactionId: '03534806-abbc-4f43-a9b1-8bdba1a57765',
338+
parameters: {
339+
data: {
340+
actionKey: 'submit',
341+
formData: {
342+
'user.password': '',
343+
'user.username': '',
344+
},
345+
},
346+
eventType: 'submit',
347+
},
348+
});
349+
});
330350
});

packages/davinci-client/src/lib/davinci.utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ export function transformSubmitRequest(node: ContinueNode): DaVinciRequest {
4141
const formData = collectors?.reduce<{
4242
[key: string]: string | number | boolean | (string | number | boolean)[];
4343
}>((acc, collector) => {
44-
acc[collector.input.key] = collector.input.value;
44+
if (collector.input.key !== undefined) {
45+
acc[collector.input.key] = collector.input.value;
46+
}
4547
return acc;
4648
}, {});
4749

packages/davinci-client/src/lib/mock-data/davinci.next.mock.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,68 @@ export const next3 = {
178178
},
179179
},
180180
};
181+
182+
export const next4 = {
183+
interactionId: '03534806-abbc-4f43-a9b1-8bdba1a57765',
184+
companyId: '490b9f38-f20b-4afa-b02e-3cc1315e29ab',
185+
connectionId: '8209285e0d2f3fc76bfd23fd10d45e6f',
186+
connectorId: 'api',
187+
id: 'elvr5pbwzn',
188+
capabilityName: 'customForm',
189+
enablePolling: false,
190+
pollInterval: '2000',
191+
pollRetries: '60',
192+
pollChallengeStatus: true,
193+
form: {
194+
components: {
195+
fields: [
196+
{
197+
type: 'ERROR_DISPLAY',
198+
},
199+
{
200+
type: 'LABEL',
201+
content:
202+
'<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis.</p>',
203+
},
204+
{
205+
type: 'TEXT',
206+
key: 'user.username',
207+
label: 'Enter your Email Address',
208+
required: true,
209+
},
210+
{
211+
type: 'PASSWORD',
212+
key: 'user.password',
213+
label: 'Enter your Password',
214+
required: true,
215+
},
216+
{
217+
type: 'SUBMIT_BUTTON',
218+
label: 'Sign On',
219+
key: 'submit',
220+
},
221+
],
222+
},
223+
name: 'SDK - Sign On',
224+
description: 'This is an out-of-the-box sign on form that prompts for username and password.',
225+
category: 'CUSTOM_FORM',
226+
},
227+
enableMagicLinkAuthentication: true,
228+
nodeTitle: 'Sign On',
229+
nodeDescription: 'P1 Form - SignOn',
230+
envId: '490b9f38-f20b-4afa-b02e-3cc1315e29ab',
231+
formId: 'cc713951-1ff3-4c77-8b33-cf91690f0c07',
232+
isResponseCompatibleWithMobileAndWebSdks: true,
233+
_links: {
234+
next: {
235+
href: 'https://auth.pingone.com/490b9f38-f20b-4afa-b02e-3cc1315e29ab/davinci/connections/8209285e0d2f3fc76bfd23fd10d45e6f/capabilities/customForm',
236+
},
237+
self: {
238+
href: 'https://auth.pingone.com/490b9f38-f20b-4afa-b02e-3cc1315e29ab/davinci/policy/c233870943cbaa6ff1a021622d074842/start',
239+
},
240+
},
241+
interactionToken:
242+
'460b6e374ff40f453eb83e3cf3da33d289538371e293df51afde06dab7ae37963234bb7bac201160b53857e49bdf245367c719ad087efc6d95fa09df4ad3d1bb94b75e1c49d72bd948eddf3a8aff9ebcb4d7a8212741d8d41abb010dd75d26e4d246ef0cea0e2550dc6fbbe36a4492105b28c33f39325291a596cd1ad77cbf95',
243+
success: true,
244+
startUiSubFlow: true,
245+
};

packages/davinci-client/src/lib/mock-data/node.next.mock.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,121 @@ export const nodeNext0 = {
8585
status: 'continue',
8686
httpStatus: 200,
8787
};
88+
89+
export const nodeNext1 = {
90+
cache: {
91+
key: '1234',
92+
},
93+
client: {
94+
action: 'submit',
95+
collectors: [
96+
{
97+
category: 'SingleValueCollector',
98+
error: 'Key is not found in the field object. Label is not found in the field object. ',
99+
id: 'undefined-0',
100+
input: {
101+
key: undefined,
102+
type: 'ERROR_DISPLAY',
103+
value: '',
104+
},
105+
name: undefined,
106+
output: {
107+
key: undefined,
108+
label: undefined,
109+
type: 'ERROR_DISPLAY',
110+
value: '',
111+
},
112+
type: 'SingleValueCollector',
113+
},
114+
{
115+
category: 'NoValueCollector',
116+
error: null,
117+
id: 'LABEL-1',
118+
name: 'LABEL-1',
119+
output: {
120+
key: 'LABEL-1',
121+
label:
122+
'<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis.</p>',
123+
type: 'LABEL',
124+
},
125+
type: 'ReadOnlyCollector',
126+
},
127+
{
128+
category: 'ValidatedSingleValueCollector',
129+
error: null,
130+
id: 'user.username-2',
131+
input: {
132+
key: 'user.username',
133+
type: 'TEXT',
134+
validation: [
135+
{
136+
message: 'Value cannot be empty',
137+
rule: true,
138+
type: 'required',
139+
},
140+
],
141+
value: '',
142+
},
143+
name: 'user.username',
144+
output: {
145+
key: 'user.username',
146+
label: 'Enter your Email Address',
147+
type: 'TEXT',
148+
value: '',
149+
},
150+
type: 'TextCollector',
151+
},
152+
{
153+
category: 'SingleValueCollector',
154+
error: null,
155+
id: 'user.password-3',
156+
input: {
157+
key: 'user.password',
158+
type: 'PASSWORD',
159+
value: '',
160+
},
161+
name: 'user.password',
162+
output: {
163+
key: 'user.password',
164+
label: 'Enter your Password',
165+
type: 'PASSWORD',
166+
},
167+
type: 'PasswordCollector',
168+
},
169+
{
170+
category: 'ActionCollector',
171+
error: null,
172+
id: 'submit-4',
173+
name: 'submit',
174+
output: {
175+
key: 'submit',
176+
label: 'Sign On',
177+
type: 'SUBMIT_BUTTON',
178+
},
179+
type: 'SubmitCollector',
180+
},
181+
],
182+
description: 'This is an out-of-the-box sign on form that prompts for username and password.',
183+
name: 'SDK - Sign On',
184+
status: 'continue',
185+
},
186+
error: null,
187+
httpStatus: 200,
188+
server: {
189+
_links: {
190+
next: {
191+
href: 'https://auth.pingone.com/490b9f38-f20b-4afa-b02e-3cc1315e29ab/davinci/connections/8209285e0d2f3fc76bfd23fd10d45e6f/capabilities/customForm',
192+
},
193+
self: {
194+
href: 'https://auth.pingone.com/490b9f38-f20b-4afa-b02e-3cc1315e29ab/davinci/policy/c233870943cbaa6ff1a021622d074842/start',
195+
},
196+
},
197+
eventName: 'continue',
198+
id: 'elvr5pbwzn',
199+
interactionId: '03534806-abbc-4f43-a9b1-8bdba1a57765',
200+
interactionToken:
201+
'460b6e374ff40f453eb83e3cf3da33d289538371e293df51afde06dab7ae37963234bb7bac201160b53857e49bdf245367c719ad087efc6d95fa09df4ad3d1bb94b75e1c49d72bd948eddf3a8aff9ebcb4d7a8212741d8d41abb010dd75d26e4d246ef0cea0e2550dc6fbbe36a4492105b28c33f39325291a596cd1ad77cbf95',
202+
status: 'continue',
203+
},
204+
status: 'continue',
205+
};

packages/davinci-client/src/lib/node.slice.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import { describe, it, expect } from 'vitest';
88

99
import { nodeSlice } from './node.slice.js';
10-
import { next0 } from './mock-data/davinci.next.mock.js';
11-
import { nodeNext0 } from './mock-data/node.next.mock.js';
10+
import { next0, next4 } from './mock-data/davinci.next.mock.js';
11+
import { nodeNext0, nodeNext1 } from './mock-data/node.next.mock.js';
1212
import { success0, success1 } from './mock-data/davinci.success.mock.js';
1313
import { nodeSuccess0, nodeSuccess1 } from './mock-data/node.success.mock.js';
1414
import { error0a, error2b, error3 } from './mock-data/davinci.error.mock.js';
@@ -163,4 +163,16 @@ describe('The node slice reducers', () => {
163163
status: 'failure',
164164
});
165165
});
166+
it('should add continue to eventName when forms are used', () => {
167+
const action = {
168+
type: 'node/next',
169+
payload: {
170+
data: next4,
171+
requestId: '1234',
172+
httpStatus: 200,
173+
},
174+
};
175+
176+
expect(nodeSlice.reducer(undefined, action)).toEqual(nodeNext1);
177+
});
166178
});

packages/davinci-client/src/lib/node.slice.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ export const nodeSlice = createSlice({
210210
id: action.payload.data.id,
211211
interactionId: action.payload.data.interactionId,
212212
interactionToken: action.payload.data.interactionToken,
213-
eventName: action.payload.data.eventName,
213+
eventName: action.payload.data.eventName || 'continue',
214214
status: CONTINUE_STATUS,
215215
};
216216

0 commit comments

Comments
 (0)