Skip to content

Commit 979299a

Browse files
added more tests
1 parent dfa74a7 commit 979299a

2 files changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright (c) 2026-present, Okta, Inc. and/or its affiliates. All rights reserved.
3+
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4+
*
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
*
10+
* See the License for the specific language governing permissions and limitations under the License.
11+
*/
12+
13+
import { getStubFormBag, getStubTransactionWithNextStep } from 'src/mocks/utils/utils';
14+
15+
import { IDX_STEP } from '../../constants';
16+
import {
17+
DescriptionElement, LaunchAuthenticatorButtonElement, TitleElement, WidgetProps,
18+
} from '../../types';
19+
import { transformNfcPinLaunchAuthenticator } from './transformNfcPinLaunchAuthenticator';
20+
21+
describe('transformNfcPinLaunchAuthenticator', () => {
22+
const transaction = getStubTransactionWithNextStep();
23+
const formBag = getStubFormBag();
24+
const widgetProps = {} as WidgetProps;
25+
26+
beforeEach(() => {
27+
formBag.uischema.elements = [];
28+
transaction.context = {
29+
...transaction.context,
30+
app: { type: 'object', value: { label: '' } },
31+
};
32+
});
33+
34+
afterEach(() => {
35+
jest.restoreAllMocks();
36+
});
37+
38+
it('should create title, description, and launch button elements', () => {
39+
const result = transformNfcPinLaunchAuthenticator({
40+
transaction, formBag, widgetProps,
41+
});
42+
43+
expect(result.uischema.elements.length).toBe(3);
44+
expect((result.uischema.elements[0] as TitleElement).type).toBe('Title');
45+
expect((result.uischema.elements[1] as DescriptionElement).type).toBe('Description');
46+
expect((result.uischema.elements[2] as LaunchAuthenticatorButtonElement).type).toBe('LaunchAuthenticatorButton');
47+
});
48+
49+
it('should use primaryauth.title as the title', () => {
50+
const result = transformNfcPinLaunchAuthenticator({
51+
transaction, formBag, widgetProps,
52+
});
53+
54+
expect((result.uischema.elements[0] as TitleElement).options.content)
55+
.toBe('primaryauth.title');
56+
});
57+
58+
it('should use NFC-specific button label', () => {
59+
const result = transformNfcPinLaunchAuthenticator({
60+
transaction, formBag, widgetProps,
61+
});
62+
63+
const button = result.uischema.elements[2] as LaunchAuthenticatorButtonElement;
64+
expect(button.label).toBe('oie.nfc_pin.launch.button');
65+
expect(button.options.i18nKey).toBe('oie.nfc_pin.launch.button');
66+
});
67+
68+
it('should use launch-nfc-authenticator as the step', () => {
69+
const result = transformNfcPinLaunchAuthenticator({
70+
transaction, formBag, widgetProps,
71+
});
72+
73+
const button = result.uischema.elements[2] as LaunchAuthenticatorButtonElement;
74+
expect(button.options.step).toBe(IDX_STEP.LAUNCH_NFC_AUTHENTICATOR);
75+
});
76+
77+
it('should show app-specific description when app label is provided', () => {
78+
transaction.context.app = { type: 'object', value: { label: 'Okta Dashboard' } };
79+
80+
const result = transformNfcPinLaunchAuthenticator({
81+
transaction, formBag, widgetProps,
82+
});
83+
84+
expect((result.uischema.elements[1] as DescriptionElement).options.content)
85+
.toBe('oktaVerify.appDescription');
86+
});
87+
88+
it('should show generic description when no app label', () => {
89+
transaction.context.app = { type: 'object', value: { label: '' } };
90+
91+
const result = transformNfcPinLaunchAuthenticator({
92+
transaction, formBag, widgetProps,
93+
});
94+
95+
expect((result.uischema.elements[1] as DescriptionElement).options.content)
96+
.toBe('oktaVerify.description');
97+
});
98+
99+
it('should pass deviceChallengeUrl from authenticatorChallenge', () => {
100+
// @ts-expect-error authenticatorChallenge not typed on context
101+
transaction.context.authenticatorChallenge = {
102+
value: {
103+
href: 'com-okta-authenticator:/deviceChallenge?challengeRequest=mock-jwt',
104+
challengeMethod: 'CUSTOM_URI',
105+
},
106+
};
107+
108+
const result = transformNfcPinLaunchAuthenticator({
109+
transaction, formBag, widgetProps,
110+
});
111+
112+
const button = result.uischema.elements[2] as LaunchAuthenticatorButtonElement;
113+
expect(button.options.deviceChallengeUrl)
114+
.toBe('com-okta-authenticator:/deviceChallenge?challengeRequest=mock-jwt');
115+
expect(button.options.challengeMethod).toBe('CUSTOM_URI');
116+
});
117+
});
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Model } from '@okta/courage';
2+
import SignInWithNfcView from 'v2/view-builder/views/nfcPin/SignInWithNfcView';
3+
import AppState from 'v2/models/AppState';
4+
import Settings from 'models/Settings';
5+
import { FORMS } from 'v2/ion/RemediationConstants';
6+
import $sandbox from 'sandbox';
7+
8+
describe('v2/view-builder/views/nfcPin/SignInWithNfcView', function() {
9+
const testContext = {};
10+
const settings = new Settings({
11+
baseUrl: 'http://localhost:3000'
12+
});
13+
14+
beforeEach(function() {
15+
testContext.init = () => {
16+
const appState = new AppState({
17+
idx: {
18+
neededToProceed: [
19+
{ name: 'launch-nfc-authenticator' },
20+
],
21+
},
22+
remediations: [
23+
{ name: 'launch-nfc-authenticator' },
24+
],
25+
}, {});
26+
jest.spyOn(appState, 'trigger');
27+
jest.spyOn(appState, 'shouldShowSignOutLinkInCurrentForm').mockReturnValue(false);
28+
29+
testContext.view = new SignInWithNfcView({
30+
el: $sandbox,
31+
appState,
32+
settings,
33+
currentViewState: {},
34+
model: new Model(),
35+
});
36+
testContext.view.render();
37+
};
38+
});
39+
40+
afterEach(function() {
41+
$sandbox.empty();
42+
jest.resetAllMocks();
43+
});
44+
45+
it('renders the Sign in with NFC button', function() {
46+
testContext.init();
47+
expect(testContext.view.$('.sign-in-with-nfc-option').length).toBe(1);
48+
expect(testContext.view.$('.button').length).toBe(1);
49+
});
50+
51+
it('renders the NFC description', function() {
52+
testContext.init();
53+
expect(testContext.view.$('.signin-with-nfc-description').length).toBe(1);
54+
});
55+
56+
it('triggers launch-nfc-authenticator action when button is clicked', function() {
57+
testContext.init();
58+
testContext.view.$('.button').click();
59+
expect(testContext.view.options.appState.trigger).toHaveBeenCalledWith(
60+
'invokeAction',
61+
FORMS.LAUNCH_NFC_AUTHENTICATOR,
62+
expect.objectContaining({ rememberMe: undefined })
63+
);
64+
});
65+
66+
it('passes rememberMe value when button is clicked', function() {
67+
testContext.init();
68+
testContext.view.model.set('rememberMe', true);
69+
testContext.view.$('.button').click();
70+
expect(testContext.view.options.appState.trigger).toHaveBeenCalledWith(
71+
'invokeAction',
72+
FORMS.LAUNCH_NFC_AUTHENTICATOR,
73+
expect.objectContaining({ rememberMe: true })
74+
);
75+
});
76+
77+
it('sets identifier on settings when identifier is present', function() {
78+
testContext.init();
79+
testContext.view.model.set('identifier', 'testuser@example.com');
80+
testContext.view.$('.button').click();
81+
expect(settings.get('identifier')).toBe(encodeURIComponent('testuser@example.com'));
82+
});
83+
});

0 commit comments

Comments
 (0)