Add missing js unit test got TagListInput component

This commit is contained in:
Gaetan Craig-Riou
2025-10-13 13:59:53 +11:00
parent 145764a921
commit 34abca5ff1

View File

@@ -3,12 +3,45 @@
*/
import { Application } from "stimulus";
import { screen } from "@testing-library/dom";
import tag_list_input_controller from "tag_list_input_component/tag_list_input_controller";
// Mock jest to return an autocomplete list
global.fetch = jest.fn(() => {
const html = `
<li
data-testid="item"
class="suggestion-item"
data-autocomplete-label="tag-1"
data-autocomplete-value="tag-1"
role="option"
id="stimulus-autocomplete-option-4"
>
tag-1 has 1 rule
</li>
<li
data-testid="item"
class="suggestion-item"
data-autocomplete-label="rule-2"
data-autocomplete-value="rule-2"
role="option"
id="stimulus-autocomplete-option-5"
>
rule-2 has 2 rules
</li>`;
return Promise.resolve({
ok: true,
text: () => Promise.resolve(html),
});
});
describe("TagListInputController", () => {
beforeAll(() => {
const application = Application.start();
application.register("tag-list-input", tag_list_input_controller);
jest.useFakeTimers();
});
beforeEach(() => {
@@ -73,12 +106,12 @@ describe("TagListInputController", () => {
name="variant_add_tag"
id="variant_add_tag"
placeholder="Add a tag"
data-action="keydown.enter->tag-list-input#keyboardAddTag keyup->tag-list-input#filterInput blur->tag-list-input#onBlur focus->tag-list-input#onInputChange"
data-action="keydown.enter->tag-list-input#keyboardAddTag keyup->tag-list-input#filterInput focus->tag-list-input#onInputChange blur->tag-list-input#onBlur"
data-tag-list-input-target="input"
style="display: block;"
>
</div>
<ul class="suggestion-list" data-tag-list-input-target="results" hidden></ul>
<ul data-testid="suggestion-list" class="suggestion-list" data-tag-list-input-target="results" hidden></ul>
</div>
</div>`;
});
@@ -315,4 +348,130 @@ describe("TagListInputController", () => {
expect(variant_add_tag.classList).not.toContain("tag-error");
});
});
describe("onBlur", () => {
it("adds the tag", () => {
variant_add_tag.value = "newer_tag";
variant_add_tag.dispatchEvent(new FocusEvent("blur"));
expect(variant_tag_list.value).toBe("tag-1,tag-2,tag-3,newer_tag");
});
describe("with autocomplete results", () => {
beforeEach(() => {
document.body.innerHTML = `
<div
data-controller="tag-list-input"
data-action="autocomplete.change->tag-list-input#addTag"
data-tag-list-input-url-value="/admin/tag_rules/variant_tag_rules?enterprise_id=3"
>
<input
value="tag-1,tag-2,tag-3"
data-tag-list-input-target="tagList"
type="hidden"
name="variant_tag_list"
id="variant_tag_list"
>
<div class="tags-input">
<div class="tags">
<ul class="tag-list" data-tag-list-input-target="list">
<template data-tag-list-input-target="template">
<li class="tag-item">
<div class="tag-template">
<span></span>
<a
class="remove-button"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
</template>
<li class="tag-item">
<div class="tag-template">
<span>tag-1</span>
<a
class="remove-button"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
<li class="tag-item">
<div class="tag-template">
<span>tag-2</span>
<a
class="remove-button"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
<li class="tag-item">
<div class="tag-template">
<span>tag-3</span>
<a
class="remove-button"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
</ul>
<input
type="text"
name="variant_add_tag"
id="variant_add_tag"
placeholder="Add a tag"
data-action="keydown.enter->tag-list-input#keyboardAddTag keyup->tag-list-input#filterInput blur->tag-list-input#onBlur focus->tag-list-input#onInputChange"
data-tag-list-input-target="input"
style="display: block;"
>
</div>
<ul class="suggestion-list" data-tag-list-input-target="results">
<li
class="suggestion-item"
data-autocomplete-label="rule-1"
data-autocomplete-value="rule-1"
role="option"
id="stimulus-autocomplete-option-4"
>
rule-1 has 1 rule
</li>
<li
class="suggestion-item"
data-autocomplete-label="rule-2"
data-autocomplete-value="rule-2"
role="option"
id="stimulus-autocomplete-option-5"
>
rule-2 has 2 rules
</li>
</ul>
</div>
</div>`;
});
it("doesn't add the tag", () => {
variant_add_tag.value = "newer_tag";
variant_add_tag.dispatchEvent(new FocusEvent("blur"));
expect(variant_tag_list.value).toBe("tag-1,tag-2,tag-3");
});
});
});
describe("replaceResults", () => {
beforeEach(() => {
fetch.mockClear();
});
it("filters out existing tags in the autocomplete dropdown", async () => {
variant_add_tag.dispatchEvent(new FocusEvent("focus"));
// onInputChange uses a debounce function implemented using setTimeout
jest.runAllTimers();
// findAll* will wait for all promises to be finished before returning a result, this ensure
// the dom has been updated with the autocomplete data
const items = await screen.findAllByTestId("item");
expect(items.length).toBe(1);
expect(items[0].textContent.trim()).toBe("rule-2 has 2 rules");
});
});
});