Skip to content

Commit

Permalink
Merge branch 'main' into fix/1121-breadcrumb-component-not-routing
Browse files Browse the repository at this point in the history
  • Loading branch information
J0taFerreira authored Feb 2, 2024
2 parents d6e5f97 + ccca81d commit 5d8086b
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 10 deletions.
25 changes: 16 additions & 9 deletions frontend/src/components/grantaccess/UserIdentityCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ const props = defineProps<{
<Card class="custom-card">
<template #header>
<Icon
id="checkmarkIcon"
icon="checkmark--filled"
:size="IconSize.small"
v-if="props.userIdentity.found"
/>
<Icon
id="errorIcon"
class="custom-carbon-icon-error--filled"
icon="error--filled"
:size="IconSize.small"
Expand All @@ -28,21 +30,26 @@ const props = defineProps<{
<template #content>
<div class="col" style="margin-left: 2rem">
<label class="row">Username</label>
<span class="row">{{ props.userIdentity.userId }}</span>
<span class="row" id="userId">{{
props.userIdentity.userId
}}</span>
</div>
<div class="col" v-if="props.userIdentity.found">
<label class="row">First Name</label>
<span class="row">{{ props.userIdentity.firstName }}</span>
<span class="row" id="firstName">{{
props.userIdentity.firstName
}}</span>
</div>
<div class="col" v-if="props.userIdentity.found">
<div class="col-2" v-if="props.userIdentity.found">
<label class="row">Last Name</label>
<span class="row">{{ props.userIdentity.lastName }}</span>
<span class="row" id="lastName">{{
props.userIdentity.lastName
}}</span>
</div>
<div
class="col-6 d-flex"
v-if="!props.userIdentity.found"
>
<span class="px-0 invalid"> User does not exist </span>
<div class="col-6 d-flex" v-if="!props.userIdentity.found">
<span class="px-0 invalid" id="userNotExist">
User does not exist
</span>
</div>
</template>
</Card>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/grantaccess/form/UserNameInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ watch(
resetVerifiedUserIdentity();
}
);
</script>

<template>
Expand Down Expand Up @@ -112,7 +113,11 @@ watch(
</div>
</Field>

<div class="col-md-5 px-0" v-if="verifiedUserIdentity">
<div
v-if="verifiedUserIdentity"
id="UserIdentityCard"
class="col-md-5 px-0"
>
<UserIdentityCard
:userIdentity="verifiedUserIdentity"
></UserIdentityCard>
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/tests/ForestClientCard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import {
TEST_SUCCESS_FOREST_CLIENT_NUMBER_3,
} from './common/ForestClientData';
import type { FamForestClient } from 'fam-app-acsctl-api';
import { fixJsdomCssErr } from '@/tests/common/fixJsdomCssErr';

fixJsdomCssErr()

const testActiveClient: FamForestClient[] = [
{
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/tests/ForestClientInput.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import {
} from './common/ForestClientData';
import { isLoading, setLoadingState } from '@/store/LoadingState';
import type { AxiosRequestHeaders, AxiosResponse } from 'axios';
import { fixJsdomCssErr } from '@/tests/common/fixJsdomCssErr';

fixJsdomCssErr()

const forestClientsApiSearchMock = (forestClientNumber: string): AxiosResponse => {
return {
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/tests/UserDomainSelect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { UserType } from 'fam-app-acsctl-api';
import type { VueWrapper } from '@vue/test-utils/dist/vueWrapper';
import type { DOMWrapper } from '@vue/test-utils/dist/domWrapper';
import UserDomainSelect from '@/components/grantaccess/form/UserDomainSelect.vue';
import { fixJsdomCssErr } from '@/tests/common/fixJsdomCssErr';

fixJsdomCssErr()

describe('UserDomainSelect', () => {
let wrapper: VueWrapper;
Expand Down
63 changes: 63 additions & 0 deletions frontend/src/tests/UserIdentityCard.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { it, describe, beforeEach, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import type { VueWrapper } from '@vue/test-utils/dist/vueWrapper';
import type { DOMWrapper } from '@vue/test-utils/dist/domWrapper';
import UserIdentityCard from '@/components/grantaccess/UserIdentityCard.vue';
import { fixJsdomCssErr } from '@/tests/common/fixJsdomCssErr';

fixJsdomCssErr();

describe('UserIdentityCard', () => {
let wrapper: VueWrapper;

const props = {
userIdentity: {
userId: 'userId',
found: true,
firstName: 'First Name',
lastName: 'Last Name',
},
};

const propsNotFound = {
userIdentity: {
userId: 'userId',
found: false,
},
};

beforeEach(async () => {
wrapper = mount(UserIdentityCard, { props });
});

it('Should show correct user info on card when receive identity in prop', () => {
expect(wrapper.find('.custom-card').element).toBeTruthy();
expect(wrapper.find('.custom-card').element.textContent).toContain(
'Verified user information'
);
expect(wrapper.find('#userId').element.textContent).toContain(
props.userIdentity.userId
);
expect(wrapper.find('#firstName').element.textContent).toContain(
props.userIdentity.firstName
);
expect(wrapper.find('#lastName').element.textContent).toContain(
props.userIdentity.lastName
);
expect(wrapper.find('#checkmarkIcon')).toBeTruthy();
});

it('Should show the user does not exist when receive not found in prop', async () => {
await wrapper.setProps(propsNotFound);
expect(wrapper.find('.custom-card').element.textContent).toContain(
'Verified user information'
);
expect(wrapper.find('#userId').element.textContent).toContain(
propsNotFound.userIdentity.userId
);
expect(wrapper.find('#userNotExist').element.textContent).toContain(
'User does not exist'
);
expect(wrapper.find('#errorIcon')).toBeTruthy();
});
});
234 changes: 234 additions & 0 deletions frontend/src/tests/UsernameInput.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import { it, describe, beforeEach, afterEach, expect, vi } from 'vitest';
import { flushPromises, mount } from '@vue/test-utils';
import { UserType } from 'fam-app-acsctl-api';
import { AppActlApiService } from '@/services/ApiServiceFactory';
import UserNameInput from '@/components/grantaccess/form/UserNameInput.vue';
import UserIdentityCard from '@/components/grantaccess/UserIdentityCard.vue';
import { setLoadingState } from '@/store/LoadingState';
import type { VueWrapper } from '@vue/test-utils/dist/vueWrapper';
import type { DOMWrapper } from '@vue/test-utils/dist/domWrapper';
import type { AxiosRequestHeaders, AxiosResponse } from 'axios';
import { fixJsdomCssErr } from '@/tests/common/fixJsdomCssErr';

fixJsdomCssErr();

const USERID = 'TestUser';
const FIRSTNAME = 'TestUserFirstName';
const LASTNAME = 'TestUserLastName';

const idimIdirSearchMock = (isUserFound: boolean): AxiosResponse => {
if (isUserFound) {
return {
data: {
firstName: FIRSTNAME,
found: true,
lastName: LASTNAME,
userId: USERID,
},
status: 200,
statusText: 'Ok',
headers: {},
config: {
headers: {} as AxiosRequestHeaders,
},
};
} else {
return {
data: {
found: false,
userId: USERID,
},
status: 200,
statusText: 'Ok',
headers: {},
config: {
headers: {} as AxiosRequestHeaders,
},
};
}
};

describe('UserNameInput', () => {
let wrapper: VueWrapper;

let usernameInputText: DOMWrapper<HTMLElement>;
let usernameInputTextEl: HTMLInputElement;
let verifyButton: DOMWrapper<HTMLElement>;
let verifyButtonEl: HTMLButtonElement;

const props = {
domain: UserType.I,
userId: '',
fieldId: 'userId',
};

const newProps = {
domain: UserType.B,
userId: USERID,
fieldId: 'testNewFiledId',
};

beforeEach(async () => {
wrapper = mount(UserNameInput, {
props,
});

usernameInputText = wrapper.find('#userIdInput');
usernameInputTextEl = usernameInputText.element as HTMLInputElement;
verifyButton = wrapper.find("[data-target-btn='verifyIdir']");
verifyButtonEl = verifyButton.element as HTMLButtonElement;
});

afterEach(() => {
vi.clearAllMocks();
wrapper.unmount();
});

it('Should change username input get correct value', async () => {
expect(usernameInputTextEl.value).toBe('');
await usernameInputText.setValue(USERID);
expect(usernameInputTextEl.value).toBe(USERID);
});

it('Should receive the correct props', async () => {
// default props
expect(wrapper.props()).toEqual(props);

await wrapper.setProps(newProps);
expect(wrapper.props()).toEqual(newProps);
expect(wrapper.props()).not.toEqual(props);
});

it('Should call emit change and setVerifyResult when input change', async () => {
// when username input value change, emit change with new value
await usernameInputText.setValue(USERID);
const emitChange = wrapper.emitted('change');
expect(emitChange).toBeTruthy();
expect(emitChange![0][0]).toEqual(USERID);
const emitSetVerifyResult = wrapper.emitted('setVerifyResult');
expect(emitSetVerifyResult).toBeTruthy();
// default prop domain is I, emit setVerifyResult with false
expect(emitSetVerifyResult![0][0]).toEqual(false);
});

it('Should enable verify btn when username is inputted', async () => {
// input is empty, button starts as disabled
expect(usernameInputTextEl.value).toBe('');
expect(verifyButtonEl.disabled).toBe(true);
expect(verifyButton.classes('p-disabled')).toBe(true);

// triggers username input change
await wrapper.setProps({ userId: USERID });
// verify button is enabled
expect(verifyButtonEl.disabled).toBe(false);
expect(verifyButton.classes('p-disabled')).toBe(false);
});

it('Should show loading on the verify btn while calling the api', async () => {
vi.spyOn(
AppActlApiService.idirBceidProxyApi,
'idirSearch'
).mockImplementation(async () => {
setLoadingState(true);
return idimIdirSearchMock(true);
});

// by default, the button text is "Verify"
expect(verifyButtonEl.textContent).toBe('Verify');

// triggers username input change to enable the verify button and click
await wrapper.setProps({ userId: USERID });
await verifyButton.trigger('click');
await flushPromises();
expect(verifyButtonEl.textContent).toContain('Loading');

// reset loading state variable
setLoadingState(false);
});

it('Should show the user identity card with correct info when user is found', async () => {
vi.spyOn(
AppActlApiService.idirBceidProxyApi,
'idirSearch'
).mockImplementation(async () => {
return idimIdirSearchMock(true);
});

// by default no identity card display
expect(wrapper.findComponent(UserIdentityCard).exists()).toBe(false);

// triggers username input change to enable the verify button and click
await wrapper.setProps({ userId: USERID });
await verifyButton.trigger('click');
await flushPromises();

// call emit setVerifyResult with true, when prop domain is I, mock api returns user found
// currently when domain is B, the verify button will be hidden
const emitSetVerifyResult = wrapper.emitted('setVerifyResult');
expect(emitSetVerifyResult).toBeTruthy();
expect(emitSetVerifyResult![0][0]).toEqual(true);

expect(wrapper.findComponent(UserIdentityCard).exists()).toBe(true);
const cardEl = wrapper.find('.custom-card').element as HTMLSpanElement;
// verify identity card title
expect(cardEl.textContent).toContain('Username');
expect(cardEl.textContent).toContain('First Name');
expect(cardEl.textContent).toContain('Last Name');
// verify identity card user info
expect(wrapper.find('#userId').element.textContent).toContain(USERID);
expect(wrapper.find('#firstName').element.textContent).toContain(
FIRSTNAME
);
expect(wrapper.find('#lastName').element.textContent).toContain(
LASTNAME
);
});

it('Should show not found on card when user is not found', async () => {
vi.spyOn(
AppActlApiService.idirBceidProxyApi,
'idirSearch'
).mockImplementation(async () => {
return idimIdirSearchMock(false);
});

// triggers username input change to enable the verify button and click
await wrapper.setProps({ userId: USERID });
await verifyButton.trigger('click');
await flushPromises();

// emit setVerifyResult will not be called, when prop domain is I, mock api returns user not found
const emitSetVerifyResult = wrapper.emitted('setVerifyResult');
expect(emitSetVerifyResult).not.toBeTruthy();

const cardEl = wrapper.find('.custom-card').element as HTMLSpanElement;
expect(cardEl.textContent).toContain('Username');
expect(wrapper.find('#userId').element.textContent).toContain(USERID);
expect(wrapper.find('#userNotExist').element.textContent).toContain(
'User does not exist'
);
});

it('Should remove card and emit different value when domain changes', async () => {
// show user identity card to prepare for the test
await wrapper.setProps({ userId: USERID });
await verifyButton.trigger('click');
await flushPromises();
const cardUsernameEl = wrapper.find('.custom-card')
.element as HTMLSpanElement;
expect(cardUsernameEl).toBeTruthy();

// change the domain to be B
await wrapper.setProps({ domain: UserType.B });
// for BCeID should emit true
const emitSetVerifyResult = wrapper.emitted('setVerifyResult');
expect(emitSetVerifyResult![0][0]).toEqual(true);
// UserIdentityCard not on page anymore
expect(wrapper.findAll('#UserIdentityCard')).toHaveLength(0);

// change the domain to be I
await wrapper.setProps({ domain: UserType.I });
// for IDIR should emit false
expect(emitSetVerifyResult![1][0]).toEqual(false);
});
});
Loading

0 comments on commit 5d8086b

Please sign in to comment.