mirror of
https://github.com/directus/directus.git
synced 2026-02-11 16:54:57 -05:00
* Fix key combinations being prevented in v-input * should normalize accented characters first * add tests for processValue and emitValue * export keyMap from use-shortcut to keep things DRY * try to add test for use-shortcut composable * move systemKeys to use-shortcut * add "capslock" & "enter" to systemKeys
237 lines
5.6 KiB
TypeScript
237 lines
5.6 KiB
TypeScript
import { Focus } from '@/__utils__/focus';
|
|
import { mount } from '@vue/test-utils';
|
|
import { GlobalMountOptions } from '@vue/test-utils/dist/types';
|
|
import { describe, expect, test } from 'vitest';
|
|
|
|
import VInput from './v-input.vue';
|
|
|
|
const global: GlobalMountOptions = {
|
|
stubs: ['v-icon'],
|
|
directives: {
|
|
focus: Focus,
|
|
},
|
|
};
|
|
|
|
test('Mount component', () => {
|
|
expect(VInput).toBeTruthy();
|
|
|
|
const wrapper = mount(VInput, {
|
|
global,
|
|
});
|
|
|
|
expect(wrapper.html()).toMatchSnapshot();
|
|
});
|
|
|
|
test('modelValue prop', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: 'my value',
|
|
},
|
|
global,
|
|
});
|
|
|
|
expect(wrapper.get('input').element.value).toBe('my value');
|
|
|
|
await wrapper.find('input').setValue('my value1');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['my value1']);
|
|
});
|
|
|
|
test('modelValue trim', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: ' please trim that beard ',
|
|
trim: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('blur');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['please trim that beard']);
|
|
});
|
|
|
|
test('modelValue dbSafe', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: 'this $hould be Dß save!!',
|
|
dbSafe: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['this_hould_be_D_save']);
|
|
});
|
|
|
|
describe('processValue', () => {
|
|
const commonTestScenarios = [
|
|
{
|
|
scenario: 'should allow slug safe characters',
|
|
event: { key: 'a' },
|
|
shouldDefaultPrevented: false,
|
|
},
|
|
{
|
|
scenario: 'should not allow non slug safe characters',
|
|
event: { key: '$' },
|
|
shouldDefaultPrevented: true,
|
|
},
|
|
{
|
|
scenario: 'should allow system keys',
|
|
event: { key: 'Control' }, // also tests whether "Control" is mapped to "meta"
|
|
shouldDefaultPrevented: false,
|
|
},
|
|
{
|
|
scenario: 'should allow arrow keys',
|
|
event: { key: 'ArrowUp' },
|
|
shouldDefaultPrevented: false,
|
|
},
|
|
];
|
|
|
|
test.each([
|
|
...commonTestScenarios,
|
|
{
|
|
scenario: 'should not allow trailing space after the slug separator',
|
|
event: { key: ' ' },
|
|
shouldDefaultPrevented: true,
|
|
},
|
|
])('slug input %scenario', async ({ event, shouldDefaultPrevented }) => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
// default slug separator to test the "should not allow trailing space after slug separator" scenario
|
|
modelValue: '-',
|
|
slug: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
const inputElement = wrapper.find('input').element;
|
|
// mock keyboard event
|
|
const keyboardEvent = new KeyboardEvent('keydown', event);
|
|
// manually attach the input element as the mocked event's target
|
|
Object.defineProperty(keyboardEvent, 'target', { value: inputElement });
|
|
|
|
wrapper.vm.processValue(keyboardEvent);
|
|
|
|
expect(keyboardEvent.defaultPrevented).toBe(shouldDefaultPrevented);
|
|
});
|
|
|
|
test.each([
|
|
...commonTestScenarios,
|
|
{
|
|
scenario: 'should allow system key combinations with number when entering the first character',
|
|
event: { key: '1', shiftKey: true },
|
|
shouldDefaultPrevented: false,
|
|
},
|
|
{
|
|
scenario: 'should not allow number when entering the first character',
|
|
event: { key: '1' },
|
|
shouldDefaultPrevented: true,
|
|
},
|
|
])('dbSafe input %scenario', async ({ event, shouldDefaultPrevented }) => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
dbSafe: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
const inputElement = wrapper.find('input').element;
|
|
// mock keyboard event
|
|
const keyboardEvent = new KeyboardEvent('keydown', event);
|
|
// manually attach the input element as the mocked event's target
|
|
Object.defineProperty(keyboardEvent, 'target', { value: inputElement });
|
|
|
|
wrapper.vm.processValue(keyboardEvent);
|
|
|
|
expect(keyboardEvent.defaultPrevented).toBe(shouldDefaultPrevented);
|
|
});
|
|
});
|
|
|
|
describe('emitValue', () => {
|
|
test('should emit null value when empty', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: '',
|
|
nullable: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([null]);
|
|
});
|
|
|
|
test('should emit number when type is number', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
type: 'number',
|
|
modelValue: '1',
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([1]);
|
|
});
|
|
|
|
test('should turn ending space into slug separator for slug input', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: 'test ',
|
|
slug: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['test-']);
|
|
});
|
|
|
|
test('should turn space into underscores for dbSafe input', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: 'a custom field',
|
|
dbSafe: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['a_custom_field']);
|
|
});
|
|
|
|
test('should prevent pasting of non db safe characters for dbSafe input', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: '$test_field',
|
|
dbSafe: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['test_field']);
|
|
});
|
|
|
|
test('should normalize accented characters for dbSafe input', async () => {
|
|
const wrapper = mount(VInput, {
|
|
props: {
|
|
modelValue: 'à_test_field',
|
|
dbSafe: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.find('input').trigger('input');
|
|
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['a_test_field']);
|
|
});
|
|
});
|