finished entry form tests

This commit is contained in:
2024-03-13 19:43:05 +01:00
parent 01d0260898
commit 9629cff64c
3 changed files with 72 additions and 23 deletions

View File

@@ -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'))
})
}) })

View File

@@ -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) {
emit('submit', result.data) const isUnique = props.entries === undefined
|| !props.entries.map(entry => entry.name).includes(result.data.name)
if (isUnique) {
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>

View File

@@ -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>