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
196 changes: 195 additions & 1 deletion webroot/src/components/Users/UserRowEdit/UserRowEdit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,54 @@
import { expect } from 'chai';
import { mountShallow } from '@tests/helpers/setup';
import UserRowEdit from '@components/Users/UserRowEdit/UserRowEdit.vue';
import { StaffUser } from '@models/StaffUser/StaffUser.model';
import { Permission } from '@/app.config';
import { Compact, CompactType } from '@models/Compact/Compact.model';
import { MutationTypes } from '@store/user/user.mutations';
import {
StaffUser,
CompactPermission,
StatePermission
} from '@models/StaffUser/StaffUser.model';

const compactType = CompactType.ASLP;
const buildCompactPermission = (
compactOverrides: Partial<CompactPermission> = {},
stateOverrides: Array<Partial<StatePermission>> = []
): CompactPermission => ({
compact: new Compact({ type: compactType }),
isReadPrivate: false,
isReadSsn: false,
isAdmin: false,
states: stateOverrides.map((stateOverride) => ({
state: { abbrev: 'ky' } as any,
isReadPrivate: false,
isReadSsn: false,
isWrite: false,
isAdmin: false,
...stateOverride,
})),
...compactOverrides,
});
const setFormData = (wrapper, data: Record<string, unknown>) => {
wrapper.vm.formData = Object.keys(data).reduce((preppedData, key) => ({
...preppedData,
[key]: {
value: data[key],
isDisabled: false,
isSubmitInput: false,
},
}), {});
};
const storeSetup = (wrapper) => {
wrapper.vm.$store.commit(`user/${MutationTypes.STORE_UPDATE_CURRENT_COMPACT}`, new Compact({ type: compactType }));
wrapper.vm.$store.commit(`user/${MutationTypes.STORE_UPDATE_USER}`, new StaffUser({
permissions: [buildCompactPermission({
isReadPrivate: true,
isReadSsn: true,
isAdmin: true,
})],
}));
};

describe('UserRowEdit component', async () => {
it('should mount the component', async () => {
Expand All @@ -21,4 +68,151 @@ describe('UserRowEdit component', async () => {
expect(wrapper.exists()).to.equal(true);
expect(wrapper.findComponent(UserRowEdit).exists()).to.equal(true);
});
it('should successfully preserve missing compact permissions', async () => {
const wrapper = await mountShallow(UserRowEdit, {
props: {
user: new StaffUser(),
},
});

storeSetup(wrapper);
setFormData(wrapper, {
compact: compactType,
compactPermission: Permission.NONE,
});

const preppedData = wrapper.vm.prepFormData();

expect(preppedData).to.deep.equal({
compact: compactType,
states: [],
});
});
it('should successfully remove compact permissions', async () => {
const wrapper = await mountShallow(UserRowEdit, {
props: {
user: new StaffUser({
permissions: [buildCompactPermission({
isReadPrivate: true,
isReadSsn: false,
isAdmin: true,
})],
}),
},
});

storeSetup(wrapper);
setFormData(wrapper, {
compact: compactType,
compactPermission: Permission.NONE,
});

const preppedData = wrapper.vm.prepFormData();

expect(preppedData).to.deep.equal({
compact: compactType,
isReadPrivate: false,
isAdmin: false,
states: [],
});
});
it('should successfully preserve missing state permissions', async () => {
const wrapper = await mountShallow(UserRowEdit, {
props: {
user: new StaffUser({
permissions: [buildCompactPermission({}, [
{ state: { abbrev: 'ky' }},
])],
}),
},
});

storeSetup(wrapper);
setFormData(wrapper, {
compact: compactType,
compactPermission: Permission.NONE,
'state-option-0': 'ky',
'state-permission-0': Permission.NONE,
});

const preppedData = wrapper.vm.prepFormData();

expect(preppedData).to.deep.equal({
compact: compactType,
states: [
{ abbrev: 'ky' },
],
});
});
it('should successfully remove state permissions', async () => {
const wrapper = await mountShallow(UserRowEdit, {
props: {
user: new StaffUser({
permissions: [buildCompactPermission({}, [
{
state: { abbrev: 'ky' } as any,
isReadPrivate: true,
isReadSsn: true,
isWrite: true,
isAdmin: true,
},
])],
}),
},
});

storeSetup(wrapper);
setFormData(wrapper, {
compact: compactType,
compactPermission: Permission.NONE,
'state-option-0': 'ky',
'state-permission-0': Permission.READ_PRIVATE,
});

const preppedData = wrapper.vm.prepFormData();

expect(preppedData).to.deep.equal({
compact: compactType,
states: [
{
abbrev: 'ky',
isReadPrivate: true,
isReadSsn: false,
isWrite: false,
isAdmin: false,
},
],
});
});
it('should successfully update state permissions', async () => {
const wrapper = await mountShallow(UserRowEdit, {
props: {
user: new StaffUser({
permissions: [buildCompactPermission()],
}),
},
});

storeSetup(wrapper);
setFormData(wrapper, {
compact: compactType,
compactPermission: Permission.NONE,
'state-option-0': 'ky',
'state-permission-0': Permission.WRITE,
});

const preppedData = wrapper.vm.prepFormData();

expect(preppedData).to.deep.equal({
compact: compactType,
states: [
{
abbrev: 'ky',
isReadPrivate: true,
isReadSsn: true,
isWrite: true,
},
],
});
});
});
34 changes: 20 additions & 14 deletions webroot/src/components/Users/UserRowEdit/UserRowEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,15 +537,18 @@ class UserRowEdit extends mixins(MixinForm) {

// Server endpoints may not be idempotent so the frontend needs to handle statefulness;
// e.g. if the user's server permisson is already false, we may get a server error if we try to send false again.
const existingCompactPermission = this.getCompactPermission(this.rowUserCompactPermission);
const existingCompactPermission: CompactPermission | null = this.rowUserCompactPermission;

if (existingCompactPermission !== Permission.READ_PRIVATE && !compactData.isReadPrivate) {
delete compactData.isReadPrivate;
}
if (existingCompactPermission !== Permission.ADMIN && !compactData.isAdmin) {
if (!existingCompactPermission?.isAdmin && !compactData.isAdmin) {
delete compactData.isAdmin;
}
// End: Handle compact statefulness
if (!existingCompactPermission?.isReadSsn && !compactData.isReadSsn) {
delete compactData.isReadSsn;
}
if (!existingCompactPermission?.isReadPrivate && !compactData.isReadPrivate) {
delete compactData.isReadPrivate;
}
// End: Handle compact permission statefulness

stateKeys.forEach((stateKey) => {
const keyNum = stateKey.split('-').pop();
Expand All @@ -558,19 +561,22 @@ class UserRowEdit extends mixins(MixinForm) {

// Server endpoints may not be idempotent so the frontend needs to handle statefulness;
// e.g. if the user's server permisson is already false, we may get a server error if we try to send false again.
const existingStatePermission = this.getStatePermission(this.userStatePermissions.find((permission) =>
permission.state?.abbrev === stateAbbrev) || null);
const existingStatePermission = existingCompactPermission?.states?.find((permission) =>
permission.state?.abbrev === stateAbbrev);

if (existingStatePermission !== Permission.READ_PRIVATE && !stateData.isReadPrivate) {
delete stateData.isReadPrivate;
if (!existingStatePermission?.isAdmin && !stateData.isAdmin) {
delete stateData.isAdmin;
}
if (existingStatePermission !== Permission.WRITE && !stateData.isWrite) {
if (!existingStatePermission?.isWrite && !stateData.isWrite) {
delete stateData.isWrite;
}
if (existingStatePermission !== Permission.ADMIN && !stateData.isAdmin) {
delete stateData.isAdmin;
if (!existingStatePermission?.isReadSsn && !stateData.isReadSsn) {
delete stateData.isReadSsn;
}
if (!existingStatePermission?.isReadPrivate && !stateData.isReadPrivate) {
delete stateData.isReadPrivate;
}
// End: Handle state statefulness
// End: Handle state permission statefulness

compactData.states.push(stateData);
});
Expand Down
Loading
Loading