-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: update handling for next element id (#4695)
* updates code to generate element ids
- Loading branch information
Showing
7 changed files
with
352 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,317 @@ | ||
/** | ||
* @jest-environment jsdom | ||
*/ | ||
import React from "react"; | ||
import { useTemplateStore, TemplateStoreProvider } from "../useTemplateStore"; | ||
import { renderHook, act } from "@testing-library/react"; | ||
import { FormElementTypes } from "@lib/types"; | ||
|
||
const createStore = () => { | ||
const wrapper = ({ children }: React.PropsWithChildren) => ( | ||
<TemplateStoreProvider isPublished={false}>{children}</TemplateStoreProvider> | ||
); | ||
|
||
const { result } = renderHook(() => useTemplateStore((s) => s), { wrapper }); | ||
|
||
act(() => { | ||
result.current.initialize(); | ||
}); | ||
|
||
return result; | ||
}; | ||
|
||
const defaultElements = [ | ||
{ | ||
id: 1, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 1 fr", | ||
titleFr: "question 1 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}, | ||
{ | ||
id: 2, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 2 en", | ||
titleFr: "question 2 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}, | ||
{ | ||
id: 3, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 3 en", | ||
titleFr: "question 3 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}, | ||
]; | ||
|
||
describe("generateElementId", () => { | ||
it("existing ids in order", async () => { | ||
const result = createStore(); | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
elements: defaultElements, layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
expect(result.current.form.elements[0].id).toBe(1); | ||
expect(result.current.form.elements[1].id).toBe(2); | ||
expect(result.current.form.elements[2].id).toBe(3); | ||
expect(result.current.form.lastGeneratedElementId).toBe(undefined); | ||
|
||
act(() => { | ||
result.current.add(1); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(4); | ||
|
||
act(() => { | ||
result.current.add(3); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(5); | ||
}); | ||
|
||
it("handles ids out of sequence", async () => { | ||
const result = createStore(); | ||
const element = { | ||
id: 19, // <-- This is out of sequence | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 19 en", | ||
titleFr: "question 19 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}; | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
// Add element with ID of 19 at the start | ||
elements: [element, ...defaultElements], layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
act(() => { | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(20); | ||
|
||
act(() => { | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(21); | ||
}); | ||
|
||
it("handles deleting an element", async () => { | ||
const result = createStore(); | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
// Add element with ID of 19 at the start | ||
elements: defaultElements, layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
act(() => { | ||
// This will add an element with ID of 4 | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(4); | ||
|
||
act(() => { | ||
// Remove an element | ||
result.current.remove(1); | ||
// Adding annother item should increment the lastGeneratedElementId by 1 | ||
// and not reuse the ID of the deleted element | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(5); | ||
}); | ||
|
||
it("handles 3 digit ids", async () => { | ||
const result = createStore(); | ||
|
||
const element = { | ||
id: 201, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 201 en", | ||
titleFr: "question 201 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}; | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
elements: [element], layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
act(() => { | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(202); | ||
|
||
}); | ||
|
||
it("handles 4 digit ids", async () => { | ||
const result = createStore(); | ||
|
||
const element = { | ||
id: 2022, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 2022 en", | ||
titleFr: "question 2022 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}; | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
elements: [element], layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
act(() => { | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(2023); | ||
|
||
}); | ||
|
||
it("handles starting a form from scratch", async () => { | ||
const result = createStore(); | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
elements: [], layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
act(() => { | ||
// This will add an element with ID of 4 | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(1); | ||
|
||
|
||
act(() => { | ||
result.current.add(0); | ||
result.current.add(0); | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(4); | ||
|
||
act(() => { | ||
result.current.remove(2); | ||
result.current.remove(3); | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(5); | ||
|
||
// Move items | ||
act(() => { | ||
result.current.moveDown(4); | ||
result.current.add(0); | ||
}); | ||
|
||
expect(result.current.form.lastGeneratedElementId).toBe(6); | ||
|
||
}); | ||
|
||
it("gets highest element id", async () => { | ||
const result = createStore(); | ||
|
||
const element = { | ||
id: 201, | ||
type: FormElementTypes.textField, | ||
properties: { | ||
titleEn: "question 201 en", | ||
titleFr: "question 201 fr", | ||
choices: [], | ||
validation: { required: false }, | ||
descriptionEn: "description en", | ||
descriptionFr: "descrption fr", | ||
}, | ||
}; | ||
|
||
result.current.form = { | ||
titleEn: "Title en", | ||
titleFr: "Title fr", | ||
elements: [ | ||
defaultElements[0], | ||
defaultElements[1], | ||
element, // <- Out of sequence and high id for testing purposes | ||
defaultElements[2], | ||
defaultElements[10] // <-- This is purposely undefined - to test check for element.id | ||
], | ||
layout: [] | ||
}; | ||
|
||
// Ensure we have a default form to work with | ||
expect(result.current.form.titleEn).toBe("Title en"); | ||
expect(result.current.form.titleFr).toBe("Title fr"); | ||
|
||
// Check that the highest element id is 201 | ||
expect(result.current.getHighestElementId()).toBe(201); | ||
|
||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,5 +38,6 @@ export const defaultForm = { | |
}, | ||
layout: [], | ||
elements: [], | ||
lastGeneratedElementId: 0, | ||
groups: {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.