Skip to content

Commit

Permalink
Add frontend test around custom inputs.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-labbate committed Apr 5, 2024
1 parent 528b106 commit 22737ca
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 14 deletions.
28 changes: 14 additions & 14 deletions training-front-end/src/components/ValidatedDatepicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
const month = user_input.month;
const day = user_input.day;
if (year.length == 4 && month && day) {
const newDate = new Date(`${year}-${month}-${day}`);
const newDate = new Date(Date.UTC(year, month, day, '00', '00', '00'));
if (!isNaN(newDate)) {
emit('update:modelValue', newDate);
}
Expand All @@ -52,7 +52,7 @@
const newDate = new Date(newValue);
if (!isNaN(newDate)) {
user_input.day = newDate?.getDate()
user_input.month = newDate?.getMonth() + 1 //+1 to convert from 0 index array
user_input.month = newDate?.getMonth()
user_input.year = newDate?.getFullYear()
} else{
user_input.day = '';
Expand Down Expand Up @@ -110,40 +110,40 @@
<option value="">
- Select -
</option>
<option value="1">
<option value="0">
01 - January
</option>
<option value="2">
<option value="1">
02 - February
</option>
<option value="3">
<option value="2">
03 - March
</option>
<option value="4">
<option value="3">
04 - April
</option>
<option value="5">
<option value="4">
05 - May
</option>
<option value="6">
<option value="5">
06 - June
</option>
<option value="7">
<option value="6">
07 - July
</option>
<option value="8">
<option value="7">
08 - August
</option>
<option value="9">
<option value="8">
09 - September
</option>
<option value="10">
<option value="9">
10 - October
</option>
<option value="11">
<option value="10">
11 - November
</option>
<option value="12">
<option value="11">
12 - December
</option>
</select>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { describe, it, expect } from "vitest";
import { mount } from '@vue/test-utils';
import ValidatedDatepicker from '../ValidatedDatepicker.vue';

describe('ValidatedDatepicker', () => {
it('renders properly', async () => {
const wrapper = mount(ValidatedDatepicker, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
});

expect(wrapper.html()).toContain('Month');
expect(wrapper.html()).toContain('Day');
expect(wrapper.html()).toContain('Year');
});

it('displays errors when validator has errors', async () => {
const wrapper = mount(ValidatedDatepicker, {
props: {
modelValue: '',
validator: {
$error: true,
$errors: [{ $property: 'name', $message: 'Name is required' }]
},
name: 'testName',
label: 'Test Label'
}
});

expect(wrapper.find('.usa-error-message').text()).toBe('Name is required');
});

it('emits update:modelValue event on input', async () => {
const wrapper = mount(ValidatedDatepicker, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
});

const monthInput = wrapper.get('#testName-month');
const dayInput = wrapper.get('#testName-day');
const yearInput = wrapper.get('#testName-year');

await monthInput.setValue('1'); //zero index 1 = february
await dayInput.setValue('15');
await yearInput.setValue('2023');

expect(wrapper.emitted()).toHaveProperty('update:modelValue');
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([new Date('2023-02-15')]);
});

it('updates user_input when modelValue changes', async () => {
const wrapper = mount(ValidatedDatepicker, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
});

await wrapper.vm.$nextTick();

// Simulate user input
const monthInput = wrapper.get('#testName-month');
const dayInput = wrapper.get('#testName-day');
const yearInput = wrapper.get('#testName-year');

// Simulate modelValue change
await wrapper.setProps({
modelValue: new Date('2024-02-20')
});

await wrapper.vm.$nextTick();

// Ensure user_input is updated
expect(monthInput.element.value).toBe('1');
expect(dayInput.element.value).toBe('20');
expect(yearInput.element.value).toBe('2024');

// Simulate modelValue change to undefined
await wrapper.setProps({
modelValue: undefined
});

await wrapper.vm.$nextTick();

// Ensure user_input is cleared
expect(monthInput.element.value).toBe('');
expect(dayInput.element.value).toBe('');
expect(yearInput.element.value).toBe('');
});
});
60 changes: 60 additions & 0 deletions training-front-end/src/components/__tests__/ValidatedInput.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { describe, it, expect } from "vitest";
import { mount } from '@vue/test-utils';
import ValidatedInput from '../ValidatedInput.vue';

describe('ValidatedInput', () => {
it('renders properly', () => {
const wrapper = mount(ValidatedInput, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
})

expect(wrapper.find('.usa-form-group').exists()).toBe(true)
expect(wrapper.find('.usa-label').text()).toBe('Test Label (*Required)')
expect(wrapper.find('input').exists()).toBe(true)
})

it('displays errors when validator has errors', async () => {
const wrapper = mount(ValidatedInput, {
props: {
modelValue: '',
validator: {
$error: true,
$errors: [{ $property: 'name', $message: 'Name is required' }]
},
name: 'testName',
label: 'Test Label'
}
})

expect(wrapper.find('.usa-input--error').exists()).toBe(true)
expect(wrapper.find('.usa-error-message').text()).toBe('Name is required')
})

it('emits update:modelValue event on input', async () => {
const wrapper = mount(ValidatedInput, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
})

const textarea = wrapper.find('input')
await textarea.setValue('new value')

expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['new value'])
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, it, expect } from "vitest";
import { mount } from '@vue/test-utils';
import ValidatedSelect from '../ValidatedSelect.vue';

describe('ValidatedSelect', () => {
it('renders properly', () => {
const wrapper = mount(ValidatedSelect, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label',
options: [
{ id: 1, name: 'Option 1' },
{ id: 2, name: 'Option 2' },
{ id: 3, name: 'Option 3' }
]
}
})

expect(wrapper.find('.usa-form-group').exists()).toBe(true)
expect(wrapper.find('.usa-label').text()).toBe('Test Label (*Required)')
expect(wrapper.findAll('option').length).toBe(4) // 3 options + default option
})

it('displays errors when validator has errors', async () => {
const wrapper = mount(ValidatedSelect, {
props: {
modelValue: '',
validator: {
$error: true,
$errors: [{ $property: 'name', $message: 'Name is required' }]
},
name: 'testName',
label: 'Test Label',
options: [
{ id: 1, name: 'Option 1' },
{ id: 2, name: 'Option 2' },
{ id: 3, name: 'Option 3' }
]
}
})

expect(wrapper.find('.usa-form-group--error').exists()).toBe(true)
expect(wrapper.find('.usa-error-message').text()).toBe('Name is required')
})

it('emits update:modelValue event on input', async () => {
const wrapper = mount(ValidatedSelect, {
props: {
modelValue: '',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label',
options: [
{ id: 1, name: 'Option 1' },
{ id: 2, name: 'Option 2' },
{ id: 3, name: 'Option 3' }
]
}
})

const select = wrapper.find('select')
await select.setValue('1')

expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['1'])
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { describe, it, expect } from "vitest";
import { mount } from "@vue/test-utils";
import ValidatedTextArea from "../ValidatedTextArea.vue";

describe('ValidatedTextArea', () => {
it('renders properly', () => {
const wrapper = mount(ValidatedTextArea, {
props: {
modelValue: 'initial value',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
})

expect(wrapper.find('.usa-form-group').exists()).toBe(true)
expect(wrapper.find('.usa-label').text()).toBe('Test Label (*Required)')
expect(wrapper.find('textarea').exists()).toBe(true)
})

it('displays errors when validator has errors', async () => {
const wrapper = mount(ValidatedTextArea, {
props: {
modelValue: 'initial value',
validator: {
$error: true,
$errors: [{ $property: 'name', $message: 'Name is required' }]
},
name: 'testName',
label: 'Test Label'
}
})

expect(wrapper.find('.usa-input--error').exists()).toBe(true)
expect(wrapper.find('.usa-error-message').text()).toBe('Name is required')
})

it('emits update:modelValue event on input', async () => {
const wrapper = mount(ValidatedTextArea, {
props: {
modelValue: 'initial value',
validator: {
$error: false,
$errors: []
},
name: 'testName',
label: 'Test Label'
}
})

const textarea = wrapper.find('textarea')
await textarea.setValue('new value')

expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['new value'])
})
})
1 change: 1 addition & 0 deletions training-front-end/vitest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default defineConfig({
base: process.env.BASEURL,
plugins: [vue()],
test: {
globalSetup: './vitest.global-setup.ts',
environment: 'jsdom'
},
envPrefix: "PUBLIC_"
Expand Down
3 changes: 3 additions & 0 deletions training-front-end/vitest.global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const setup = () => {
process.env.TZ = 'UTC'
}

0 comments on commit 22737ca

Please sign in to comment.