Skip to content

Commit

Permalink
fix: automatic submits in authenticate component (#124)
Browse files Browse the repository at this point in the history
* fix: instant submits when no validator is set

* chore: add missing translation in demo component

* test: bump coverage

Co-authored-by: Arne Vandoorslaer <[email protected]>
  • Loading branch information
lem-onade and Arne Vandoorslaer authored Dec 22, 2021
1 parent f1830b7 commit c0a0f59
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 10 deletions.
9 changes: 8 additions & 1 deletion packages/dgt-components/demo/demo-authenticate.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css, html, unsafeCSS } from 'lit-element';
import { RxLitElement } from 'rx-lit';
import { Checkbox, Login, Theme } from '@digita-ai/dgt-theme';
import { Login, Theme } from '@digita-ai/dgt-theme';
import { SolidSDKService } from '@digita-ai/inrupt-solid-service';
import { AuthenticateComponent } from '../lib/components/authentication/authenticate.component';
import { hydrate } from '../lib/util/hydrate';
Expand All @@ -13,6 +13,7 @@ export class DemoAuthenticateComponent extends RxLitElement {
private trustedIssuers = [ 'https://inrupt.net/' ];
private translations = {
'common.webid-validation.invalid-uri': 'The URL of the entered WebID is invalid',
'common.webid-validation.no-issuer': 'The WebID does not contain valid OIDC issuer',
}
private translator: Translator = {
translate: (key: string) => this.translations[key],
Expand All @@ -35,7 +36,13 @@ export class DemoAuthenticateComponent extends RxLitElement {

constructor() {
super();
// the most basic authenticate compnonent
// customElements.define('auth-flow', hydrate(AuthenticateComponent)(this.solidService));

// an authenticate component with trusted issuers and validator
// customElements.define('auth-flow', hydrate(AuthenticateComponent)(this.solidService, this.trustedIssuers, this.webIdValidator));

// an authenticate component with only validator
customElements.define('auth-flow', hydrate(AuthenticateComponent)(this.solidService, undefined, this.webIdValidator));

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { createMachine, interpret, Interpreter, StateMachine } from 'xstate';
import { AuthenticateContext, AuthenticateEvent, authenticateMachine, AuthenticateState, AuthenticateStates, AuthenticateStateSchema, ClickedLoginEvent, WebIdEnteredEvent } from './authenticate.machine';

describe('AuthenticateMachine', () => {

let actor: Interpreter<AuthenticateContext, AuthenticateStateSchema, AuthenticateEvent, AuthenticateState>;
let machine: StateMachine<AuthenticateContext, AuthenticateStateSchema, AuthenticateEvent, AuthenticateState>;

const solidService = {
getSession: jest.fn(async () => { throw new Error(); }), // mock failing of session restore
getIssuers: jest.fn(async () => []),
} as any;

beforeEach(() => {

machine = createMachine(authenticateMachine(solidService)).withContext({});
actor = interpret(machine);

});

describe('CHECKING_ISSUERS', () => {

beforeEach(async () => {

// go to CHECKING_ISSUERS state
actor.onTransition((state) => {

if (state.matches(AuthenticateStates.AWAITING_WEBID)) {

// go to AWAITING_LOGIN state
actor.send(new WebIdEnteredEvent('https://example.com/profile/card#me'));

} else if (state.matches(AuthenticateStates.AWAITING_LOGIN)) {

// go to RETRIEVING_ISSUERS state
actor.send(new ClickedLoginEvent('https://example.com/profile/card#me'));

}

});

});

it('should transition to NO_TRUST when issuers is empty', async () => {

solidService.getIssuers = jest.fn(async () => []);

actor.onTransition((state) => {

if (state.matches(AuthenticateStates.NO_TRUST)) {

expect(state.context.issuers.length).toEqual(0);

}

});

actor.start();

});

it('should transition to AUTHENTICATING when single issuer', async () => {

solidService.getIssuers = jest.fn(async () => [ 'https://issuer.uri/' ]);

actor.onTransition((state) => {

if (state.matches(AuthenticateStates.AUTHENTICATING)) {

expect(state.context.issuers.length).toEqual(1);
expect(state.context.issuer).toEqual('https://issuer.uri/');

}

});

actor.start();

});

it('should transition to SELECTING_ISSUER when multiple issuers', async () => {

solidService.getIssuers = jest.fn(async () => [ 'https://issuer1.uri/', 'https://issuer2.uri/' ]);

actor.onTransition((state) => {

if (state.matches(AuthenticateStates.SELECTING_ISSUER)) {

expect(state.context.issuers.length).toBeGreaterThan(1);

}

});

actor.start();

});

});

});
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ MachineConfig<AuthenticateContext, AuthenticateStateSchema, AuthenticateEvent> =
target: AuthenticateStates.CHECKING_WEBID,
},
{
// otherwise, skip validation and go straight to retrieval of issuers
// otherwise, skip validation
actions: assign({ webId: (c, event) => event.webId }),
target: AuthenticateStates.RETRIEVING_ISSUERS,
target: AuthenticateStates.AWAITING_LOGIN,
},
],
[AuthenticateEvents.SELECTED_ISSUER]: {
Expand All @@ -188,7 +188,7 @@ MachineConfig<AuthenticateContext, AuthenticateStateSchema, AuthenticateEvent> =
},
},
invoke: {
src: (context) => context.webIdValidator(context.webId),
src: (context) => context.webIdValidator ? context.webIdValidator(context.webId) : Promise.resolve([]),
onDone: [
{
cond: (c, event: DoneInvokeEvent<string[]>) => event.data?.length > 0,
Expand All @@ -209,8 +209,10 @@ MachineConfig<AuthenticateContext, AuthenticateStateSchema, AuthenticateEvent> =
target: AuthenticateStates.RETRIEVING_ISSUERS,
},
[AuthenticateEvents.WEBID_ENTERED]: {
target: AuthenticateStates.CHECKING_WEBID,
// validate webId when validator is set
cond: (context) => context.webIdValidator !== undefined,
actions: assign({ webId: (c, event) => event.webId }),
target: AuthenticateStates.CHECKING_WEBID,
},
},

Expand Down
10 changes: 5 additions & 5 deletions packages/dgt-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@
],
"coverageThreshold": {
"global": {
"branches": 37.5,
"functions": 47.11,
"lines": 54.43,
"statements": 55.34
"branches": 38.11,
"functions": 50.88,
"lines": 55.6,
"statements": 56.39
}
},
"coveragePathIgnorePatterns": [
Expand All @@ -106,4 +106,4 @@
"<rootDir>/demo/"
]
}
}
}

0 comments on commit c0a0f59

Please sign in to comment.