finished entry form tests
This commit is contained in:
@@ -77,29 +77,65 @@ describe('Entry Form tests', () => {
|
|||||||
expect(button.text()).toBe('Edit')
|
expect(button.text()).toBe('Edit')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('displays nothing when the form is valid and processed', () => {
|
it('displays nothing when the form is valid and processed', async () => {
|
||||||
const { name, text } = getSampleValues()
|
const { name, text } = getSampleValues()
|
||||||
const component = mount(EntryForm)
|
const component = mount(EntryForm)
|
||||||
const { nameField, textField } = getFormFields(component)
|
const { nameField, textField } = getFormFields(component)
|
||||||
const [button, errorSpan] = getAdditionalElements(component, 'button', 'span')
|
const [button] = getAdditionalElements(component, 'button')
|
||||||
|
|
||||||
|
await nameField.setValue(name)
|
||||||
|
await textField.setValue(text)
|
||||||
|
|
||||||
|
await button.trigger('click')
|
||||||
|
const errorSpans = component.findAll('[data-test="error-msg"]')
|
||||||
|
|
||||||
|
expect(errorSpans.length).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('displays that the name is missing when no name is entered', async () => {
|
||||||
|
const { text } = getSampleValues()
|
||||||
|
const component = mount(EntryForm)
|
||||||
|
const { textField } = getFormFields(component)
|
||||||
|
const [button] = getAdditionalElements(component, 'button')
|
||||||
|
|
||||||
nameField.element.value = name
|
|
||||||
textField.element.value = text
|
textField.element.value = text
|
||||||
|
|
||||||
button.trigger('click')
|
await button.trigger('click')
|
||||||
expect(errorSpan.text()).toBe('')
|
const errorSpans = component.findAll('[data-test="error-msg"]')
|
||||||
|
|
||||||
|
expect(errorSpans.length).toBe(1)
|
||||||
|
expect(errorSpans[0].text()).toBe('* name is required')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('displays that the name is missing when no name is entered', () => {
|
it('displays error that the name is not unique when there is another entry in the passed entries with the same name', async () => {
|
||||||
const { name } = getSampleValues()
|
const { text } = getSampleValues()
|
||||||
const component = mount(EntryForm)
|
const component = mount(EntryForm, {props: {entries: [<Entry>{name: 'something', text: 'something else'}]}})
|
||||||
const { nameField } = getFormFields(component)
|
const { textField, nameField } = getFormFields(component)
|
||||||
const [button, errorSpan] = getAdditionalElements(component, 'button', 'span')
|
const [button] = getAdditionalElements(component, 'button')
|
||||||
|
|
||||||
nameField.element.value = name
|
await textField.setValue(text)
|
||||||
|
await nameField.setValue('something')
|
||||||
|
|
||||||
button.trigger('click')
|
await button.trigger('click')
|
||||||
expect(errorSpan.text()).toBe('name is required')
|
const errorSpans = component.findAll('[data-test="error-msg"]')
|
||||||
|
|
||||||
|
expect(errorSpans.length).toBe(1)
|
||||||
|
expect(errorSpans[0].text()).toBe('* name must be unique')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('fires submit when there is no issue with the inputted data', async() => {
|
||||||
|
const { text } = getSampleValues()
|
||||||
|
const component = mount(EntryForm, {props: {entries: [<Entry>{name: 'something', text: 'something else'}]}})
|
||||||
|
const { textField, nameField } = getFormFields(component)
|
||||||
|
const [button] = getAdditionalElements(component, 'button')
|
||||||
|
|
||||||
|
await textField.setValue(text)
|
||||||
|
await nameField.setValue('something else')
|
||||||
|
|
||||||
|
await button.trigger('click')
|
||||||
|
const errorSpans = component.findAll('[data-test="error-msg"]')
|
||||||
|
|
||||||
|
expect(errorSpans.length).toBe(0)
|
||||||
|
expect(component.emitted('submit'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -13,17 +13,18 @@ const emit = defineEmits<{
|
|||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
action?: 'create' | 'edit'
|
action?: 'create' | 'edit'
|
||||||
inputEntry?: Entry | undefined
|
inputEntry?: Entry | undefined
|
||||||
|
entries?: Entry[]
|
||||||
}>(), {
|
}>(), {
|
||||||
action: 'create'
|
action: 'create',
|
||||||
})
|
})
|
||||||
|
|
||||||
const nameField = ref(props.inputEntry ? props.inputEntry.name : '')
|
const nameField = ref(props.inputEntry ? props.inputEntry.name : '')
|
||||||
const textField = ref(props.inputEntry ? props.inputEntry.text : '')
|
const textField = ref(props.inputEntry ? props.inputEntry.text : '')
|
||||||
const errorMessage: Ref<string | undefined> = ref(undefined)
|
const issues: Ref<Array<string>> = ref([])
|
||||||
|
|
||||||
const createEntrySchema = z.object({
|
const createEntrySchema = z.object({
|
||||||
name: z.string({required_error: 'name is required'}),
|
name: z.string().trim().min(1, { message: 'name is required' }),
|
||||||
text: z.string().optional()
|
text: z.string().trim().optional()
|
||||||
})
|
})
|
||||||
|
|
||||||
export type CreateEntrySchema = z.infer<typeof createEntrySchema>
|
export type CreateEntrySchema = z.infer<typeof createEntrySchema>
|
||||||
@@ -35,9 +36,19 @@ function submit() {
|
|||||||
text: textField.value
|
text: textField.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
const isUnique = props.entries === undefined
|
||||||
|
|| !props.entries.map(entry => entry.name).includes(result.data.name)
|
||||||
|
|
||||||
|
if (isUnique) {
|
||||||
emit('submit', result.data)
|
emit('submit', result.data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
issues.value = ['name must be unique']
|
||||||
} else {
|
} else {
|
||||||
|
issues.value = result.error.issues.map(issue => issue.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,14 +56,16 @@ function submit() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form class="flex gap-3 flex-col">
|
<div class="flex gap-3 flex-col">
|
||||||
<span>{{ errorMessage }}</span>
|
<div >
|
||||||
|
<span v-for="issue of issues" data-test="error-msg" class="text-red-800"> * {{ issue }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Input placeholder="Name" v-model:model-value="nameField" />
|
<Input placeholder="Name" v-model:model-value="nameField" />
|
||||||
<Textarea placeholder="Text" v-model:model-value="textField" />
|
<Textarea placeholder="Text" v-model:model-value="textField" />
|
||||||
<Button class="w-full" v-if="props.action === 'create'" @click="submit()">Create</Button>
|
<Button class="w-full" v-if="props.action === 'create'" @click="submit()">Create</Button>
|
||||||
<Button class="w-full" v-else @click="submit()">Edit</Button>
|
<Button class="w-full" v-else @click="submit()">Edit</Button>
|
||||||
</form>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
@@ -79,7 +79,7 @@ function openDetailWithName(name: string) {
|
|||||||
<DialogTitle> Create new Entry </DialogTitle>
|
<DialogTitle> Create new Entry </DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<EntryForm action="create" @submit="(val) => createEntry(val)"> </EntryForm>
|
<EntryForm action="create" @submit="(val) => createEntry(val)" :entries="entries"> </EntryForm>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@@ -90,7 +90,7 @@ function openDetailWithName(name: string) {
|
|||||||
<DrawerTitle>Create new Entry</DrawerTitle>
|
<DrawerTitle>Create new Entry</DrawerTitle>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<EntryForm action="create" @submit="(val) => createEntry(val)"> </EntryForm>
|
<EntryForm action="create" @submit="(val) => createEntry(val)" :entries="entries"> </EntryForm>
|
||||||
</div>
|
</div>
|
||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|||||||
Reference in New Issue
Block a user