Skip to content

Commit

Permalink
Merge branch 'support/client2' into chore/upgrade-types-node
Browse files Browse the repository at this point in the history
  • Loading branch information
mamartinezmejia authored Oct 1, 2024
2 parents ac2d204 + 78c0a8e commit a0eb9f5
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 12 deletions.
22 changes: 12 additions & 10 deletions frontend/src/components/forms/DateInputComponent/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,17 @@ const emitValueChange = (newValue: string): void => {
emit("update:model-value", newValue);
const someEmpty = isAnyPartEmpty();
emit("empty", someEmpty);
let possiblyValid = false;
if (!someEmpty && focusedPart.value !== null) {
const otherParts = getPartsExcept(focusedPart.value);
const allOtherAreValid = otherParts.every((part) => validation[part]);
if (allOtherAreValid) {
possiblyValid = true;
if (focusedPart.value !== null) {
let possiblyValid = false;
if (!someEmpty) {
const otherParts = getPartsExcept(focusedPart.value);
const allOtherAreValid = otherParts.every((part) => validation[part]);
if (allOtherAreValid) {
possiblyValid = true;
}
}
emit("possibly-valid", possiblyValid);
}
emit("possibly-valid", possiblyValid);
};
// Watch for changes on the input
Expand Down Expand Up @@ -325,8 +327,8 @@ const partValidators = computed(() => ({
// Update validation status on setup
validation[DatePart.year] = selectedYear.value && validatePart(DatePart.year);
validation[DatePart.month] = selectedYear.value && validatePart(DatePart.month);
validation[DatePart.day] = selectedYear.value && validatePart(DatePart.day);
validation[DatePart.month] = selectedMonth.value && validatePart(DatePart.month);
validation[DatePart.day] = selectedDay.value && validatePart(DatePart.day);
if (areAllPartsValid()) {
validationFullDate.value = validateFullDate(selectedValue.value);
Expand All @@ -347,10 +349,10 @@ const onBlurPart = (datePart: DatePart) => (partNewValue: string) => {
validation[DatePart.day] = validatePart(DatePart.day);
}
selectedValue.value = buildFullDate();
if (areAllPartsValid()) {
validateFullDate(selectedValue.value);
}
isUserEvent.value = true;
};
const onBlurYear = onBlurPart(DatePart.year);
Expand Down
141 changes: 139 additions & 2 deletions frontend/tests/unittests/components/forms/DateInputComponent.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, it, expect, afterEach } from "vitest";
import { describe, it, expect, afterEach, beforeEach } from "vitest";
import { DOMWrapper, mount, VueWrapper } from "@vue/test-utils";
import DateInputComponent from "@/components/forms/DateInputComponent/index.vue";
import { isMinimumYearsAgo } from "@/helpers/validators/GlobalValidators";
import { isDateInThePast, isMinimumYearsAgo } from "@/helpers/validators/GlobalValidators";

describe("Date Input Component", () => {
let globalWrapper: VueWrapper;
Expand Down Expand Up @@ -177,4 +177,141 @@ describe("Date Input Component", () => {
expect(wrapper.emitted("empty")).toBeTruthy();
expect(wrapper.emitted("empty")![0][0]).toBe(true);
});

it("emits possibly-valid true when focused part is not empty and the two other parts are valid", async () => {
const wrapper = mount(DateInputComponent, {
props: {
id,
title: "My date",
modelValue: "2000-12-", // missing the Day part
validations: [],
enabled: true,
},
directives: {
masked: () => {},
},
attachTo: document.body,
});
globalWrapper = wrapper;

const inputWrapper = wrapper.find<HTMLInputElement>(`#${id}Day`);
await setInputValue(inputWrapper, "1");

expect(wrapper.emitted("possibly-valid")).toBeTruthy();
expect(wrapper.emitted("possibly-valid")![0][0]).toBe(true);
});

it("emits possibly-valid false when the focused part gets cleared", async () => {
const wrapper = mount(DateInputComponent, {
props: {
id,
title: "My date",
modelValue: "2000-12-25",
validations: [],
enabled: true,
},
directives: {
masked: () => {},
},
attachTo: document.body,
});
globalWrapper = wrapper;

const inputWrapper = wrapper.find<HTMLInputElement>(`#${id}Day`);
await setInputValue(inputWrapper, ""); // clears the Day part

expect(wrapper.emitted("possibly-valid")).toBeTruthy();
expect(wrapper.emitted("possibly-valid")![0][0]).toBe(false);
});

describe.each([
{
partName: "Year",
partIndex: 0,
expectedLength: 4,
validBeginning: "20019",
invalidBeginning: "21019",
},
{
partName: "Month",
partIndex: 1,
expectedLength: 2,
validBeginning: "120",
invalidBeginning: "130",
},
{
partName: "Day",
partIndex: 2,
expectedLength: 2,
validBeginning: "250",
invalidBeginning: "400",
},
])("when a value that doesn't fit the $partName part is pasted on it", (scenario) => {
const baseValue = "2000-11-24";
const test = async (valid: boolean) => {
const inputWrapper = globalWrapper.find<HTMLInputElement>(`#${id}${scenario.partName}`);
await inputWrapper.trigger("blur");

const baseParts = baseValue.split("-");
const { validBeginning, invalidBeginning } = scenario;
const newPartValue = valid ? validBeginning : invalidBeginning;

// first expected number of digits only
baseParts[scenario.partIndex] = newPartValue.slice(0, scenario.expectedLength);

const expectedModelValue = baseParts.join("-");

expect(globalWrapper.emitted("update:model-value")).toBeTruthy();
const lastUpdateEvent = globalWrapper.emitted("update:model-value").slice(-1)[0];

expect(lastUpdateEvent[0]).toEqual(expectedModelValue);

expect(globalWrapper.emitted("error")).toBeTruthy();
const lastErrorEvent = globalWrapper.emitted("error").slice(-1)[0];

if (valid) {
expect(lastErrorEvent[0]).toBeFalsy();
} else {
expect(lastErrorEvent[0]).toBeTruthy();
expect(lastErrorEvent[0]).toEqual(expect.any(String));
}
};
beforeEach(() => {
const baseParts = baseValue.split("-");
baseParts[scenario.partIndex] = ""; // clear the part to be tested
const modelValue = baseParts.join("-");
const wrapper = mount(DateInputComponent, {
props: {
id,
title: "My date",
modelValue,
validations: [isDateInThePast("sample error message")],
enabled: true,
},
directives: {
masked: () => {},
},
attachTo: document.body,
});
globalWrapper = wrapper;
});
describe(`but the first ${scenario.expectedLength} digits are valid`, () => {
beforeEach(async () => {
const inputWrapper = globalWrapper.find<HTMLInputElement>(`#${id}${scenario.partName}`);
await setInputValue(inputWrapper, scenario.validBeginning);
});
it("updates the modelValue properly and emits error falsy (valid) after blurring", async () => {
test(true);
});
});
describe(`and the first ${scenario.expectedLength} digits are invalid`, () => {
beforeEach(async () => {
const inputWrapper = globalWrapper.find<HTMLInputElement>(`#${id}${scenario.partName}`);
await setInputValue(inputWrapper, scenario.invalidBeginning);
});
it("updates the modelValue properly and emits error truthy (invalid) after blurring", async () => {
test(false);
});
});
});
});

0 comments on commit a0eb9f5

Please sign in to comment.