Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/cute-snails-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@forgerock/davinci-client': patch
---

error states should be cleared from state when a successful next or success node was processed
39 changes: 0 additions & 39 deletions .github/instructions/nx.instructions.md

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ concurrency:
jobs:
pr:
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 20
permissions:
pull-requests: write
contents: write
Expand Down
6 changes: 3 additions & 3 deletions packages/davinci-client/src/lib/collector.utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,15 +427,15 @@ describe('Object value collectors', () => {
title: 'Device 1',
id: '123123',
default: true,
value: 'device1-value',
description: 'device1-value',
},
{
type: 'device2',
iconSrc: 'icon2.png',
title: 'Device 2',
id: '345345',
default: false,
value: 'device2-value',
description: 'device2-value',
},
],
required: true,
Expand All @@ -444,7 +444,7 @@ describe('Object value collectors', () => {
const transformedDevices = mockField.options.map((device) => ({
label: device.title,
value: device.id,
content: device.value,
content: device.description,
type: device.type,
key: device.id,
default: device.default,
Expand Down
4 changes: 2 additions & 2 deletions packages/davinci-client/src/lib/collector.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,15 +374,15 @@ export function returnObjectCollector<
const unmappedDefault = field.options.find((device) => device.default);
defaultValue = {
type: unmappedDefault ? unmappedDefault.type : '',
value: unmappedDefault ? unmappedDefault.value : '',
value: unmappedDefault ? unmappedDefault.description : '',
id: unmappedDefault ? unmappedDefault.id : '',
};

// Map DaVinci spec to normalized SDK API
options = field.options.map((device) => ({
type: device.type,
label: device.title,
content: device.value,
content: device.description,
value: device.id,
key: device.id,
default: device.default,
Expand Down
2 changes: 1 addition & 1 deletion packages/davinci-client/src/lib/davinci.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export type DeviceAuthenticationField = {
title: string;
id: string;
default: boolean;
value: string;
description: string;
}[];
required: boolean;
};
Expand Down
87 changes: 87 additions & 0 deletions packages/davinci-client/src/lib/node.slice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,49 @@ describe('The node slice reducers', () => {
expect(nodeSlice.reducer(undefined, action)).toEqual(nodeNext0);
});

it('should clear error when we successfully process a node with a next', () => {
const actionError = {
type: 'node/error',
payload: {
data: error0a,
requestId: '1234',
httpStatus: 400,
},
};
const errorState = {
cache: {
key: '1234',
},
client: {
status: 'error' as const,
},
error: {
code: ' Invalid username and/or password',
collectors: [],
message: ' Invalid username and/or password',
internalHttpStatus: 400,
status: 'error',
type: 'davinci_error',
},
httpStatus: 400,
server: {
status: 'error',
},
status: 'error',
};
const errorStateReducer = nodeSlice.reducer(undefined, actionError);
expect(errorStateReducer).toEqual(errorState);

const action = {
type: 'node/next',
payload: {
data: next0,
requestId: '1234',
httpStatus: 200,
},
};
expect(nodeSlice.reducer(errorStateReducer, action)).toEqual(nodeNext0);
});
it('should handle success node after DaVinci flow', () => {
const action = {
type: 'node/success',
Expand All @@ -67,6 +110,50 @@ describe('The node slice reducers', () => {
expect(nodeSlice.reducer(undefined, action)).toEqual(nodeSuccess1);
});

it('should clear error when we successfully process a node', () => {
const action = {
type: 'node/error',
payload: {
data: error0a,
requestId: '1234',
httpStatus: 400,
},
};
const errorState = {
cache: {
key: '1234',
},
client: {
status: 'error' as const,
},
error: {
code: ' Invalid username and/or password',
collectors: [],
message: ' Invalid username and/or password',
internalHttpStatus: 400,
status: 'error',
type: 'davinci_error',
},
httpStatus: 400,
server: {
status: 'error',
},
status: 'error',
};
const errorStateReducer = nodeSlice.reducer(undefined, action);
expect(errorStateReducer).toEqual(errorState);

const actionSuccess = {
type: 'node/success',
payload: {
data: success1,
requestId: '1234',
httpStatus: 200,
},
};
expect(nodeSlice.reducer(errorStateReducer, actionSuccess)).toEqual(nodeSuccess1);
});

it('should handle error node', () => {
const action = {
type: 'node/error',
Expand Down
5 changes: 4 additions & 1 deletion packages/davinci-client/src/lib/node.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const initialNodeState = {
status: START_STATUS,
},
status: START_STATUS,
};
} satisfies StartNode;

type NodeStates = ErrorNode | FailureNode | ContinueNode | SuccessNode | StartNode;

Expand Down Expand Up @@ -204,6 +204,8 @@ export const nodeSlice = createSlice({
status: CONTINUE_STATUS,
};

newState.error = null;

newState.httpStatus = action.payload.httpStatus;

newState.server = {
Expand Down Expand Up @@ -257,6 +259,7 @@ export const nodeSlice = createSlice({
status: SUCCESS_STATUS,
};

newState.error = null;
newState.status = SUCCESS_STATUS;

return newState;
Expand Down
8 changes: 8 additions & 0 deletions packages/protect/src/lib/protect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ describe('protect (success tests)', () => {
});

describe('protect (error tests)', () => {
beforeAll(() => {
vi.doMock('./signals-sdk.js', () => {
throw new Error('Failed to load PingOne Signals SDK');
});
});
afterAll(() => {
vi.doUnmock('./signals-sdk.js');
});
it('should error on failed signals sdk load', async () => {
await expect(protect(config)).rejects.toThrowError('Failed to load PingOne Signals SDK');
});
Expand Down
Loading