Merge pull request #3245 from Safelite/feature/CASH-2952
Feature/cash 2952
This commit is contained in:
commit
4c504b54ac
6 changed files with 66 additions and 23 deletions
13
src/App.vue
13
src/App.vue
|
|
@ -87,9 +87,22 @@ window.onerror = (msg, url, line, col, error) => {
|
|||
return suppressErrorAlert;
|
||||
};
|
||||
|
||||
function isThirdPartyUnhandledRejection(reason) {
|
||||
const stack = reason instanceof Error ? reason.stack : "";
|
||||
if (typeof stack !== "string") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stack.includes("chrome-extension://") || stack.includes("quantummetric.com");
|
||||
}
|
||||
|
||||
// Log Promise rejections that are never handled (.catch / await try/catch), e.g. fire-and-forget async.
|
||||
window.addEventListener("unhandledrejection", (event) => {
|
||||
const reason = event.reason;
|
||||
if (isThirdPartyUnhandledRejection(reason)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = reason instanceof Error ? reason.message : String(reason);
|
||||
global.$logger.logError(`unhandledrejection: ${message}`, {
|
||||
stack: reason instanceof Error ? reason.stack : undefined,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,22 @@ const mockMixin = {
|
|||
const maska = jest.fn();
|
||||
|
||||
describe("textboxQuestion.vue", () => {
|
||||
it("Should coerce non-string modelValue to empty string for v-model.trim", async () => {
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
global: {
|
||||
directives: {
|
||||
maska: maska,
|
||||
},
|
||||
},
|
||||
propsData: {
|
||||
modelValue: null,
|
||||
},
|
||||
mixins: [mockMixin],
|
||||
});
|
||||
|
||||
expect(wrapper.vm.value).toBe("");
|
||||
});
|
||||
|
||||
it("Should render a text input", async () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
<input
|
||||
class="form-control"
|
||||
v-model.trim="value"
|
||||
v-maska="mask"
|
||||
v-maska="effectiveMask"
|
||||
:type="type"
|
||||
:ref="inputId"
|
||||
:id="inputId"
|
||||
|
|
@ -90,6 +90,19 @@ import loader from "@/ux-components/loader/loader.vue";
|
|||
import { ref } from "vue";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
function coerceTextboxValue(modelValue) {
|
||||
if (modelValue == null) {
|
||||
return "";
|
||||
}
|
||||
if (typeof modelValue === "number") {
|
||||
return String(modelValue);
|
||||
}
|
||||
if (typeof modelValue === "string") {
|
||||
return modelValue;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "textbox-question",
|
||||
props: {
|
||||
|
|
@ -145,18 +158,8 @@ export default {
|
|||
const inputId = !props.customInputId ? `input-${uuid}` : props.customInputId;
|
||||
|
||||
const propsClone = Object.assign({}, props);
|
||||
const modelValue = propsClone.modelValue;
|
||||
let initialValue;
|
||||
let isImageProcessing = ref(false);
|
||||
|
||||
switch (typeof modelValue) {
|
||||
case "number":
|
||||
initialValue = modelValue;
|
||||
break;
|
||||
default:
|
||||
initialValue = modelValue && modelValue.length > 0 ? modelValue : "";
|
||||
break;
|
||||
}
|
||||
const modelValue = coerceTextboxValue(propsClone.modelValue);
|
||||
const initialValue = modelValue;
|
||||
|
||||
const fieldOptions = {
|
||||
type: "text",
|
||||
|
|
@ -164,6 +167,8 @@ export default {
|
|||
initialValue: initialValue,
|
||||
};
|
||||
|
||||
let isImageProcessing = ref(false);
|
||||
|
||||
const { errorMessage, handleBlur, handleChange, meta, validate, errors } = useField(
|
||||
inputId,
|
||||
props.validationRules,
|
||||
|
|
@ -223,18 +228,25 @@ export default {
|
|||
},
|
||||
value: {
|
||||
get: function () {
|
||||
return this.modelValue;
|
||||
return coerceTextboxValue(this.modelValue);
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.$emit("update:modelValue", newValue);
|
||||
},
|
||||
},
|
||||
effectiveMask() {
|
||||
return this.mask ?? "";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$emit("textboxQuestionEvent.inputIdAssigned", this.inputId);
|
||||
},
|
||||
watch: {
|
||||
async value(newValue) {
|
||||
if (typeof this.handleChange !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await validate(newValue, this.validationRules); // do a test validation check, without triggering full validation
|
||||
if (result.valid) {
|
||||
this.handleChange(newValue); // trigger full validation on this field only
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
class="keys-message" />
|
||||
<mobileAddressQuestions
|
||||
ref="addressQuestions"
|
||||
v-model="this.addressQuestions"
|
||||
v-model="addressQuestions"
|
||||
captureApartmentNumberOrBusinessName="true"
|
||||
preserveCityAndStateOnReset="true"
|
||||
labelBold="true"
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
isZipCodeDisabled="true" />
|
||||
<vehicleProtectedQuestion
|
||||
ref="vehicleProtectedQuestion"
|
||||
v-model="this.isVehicleProtected"
|
||||
v-model="isVehicleProtected"
|
||||
cmsWidgetName="VehicleProtectedQuestionWidget"
|
||||
labelBold="true" />
|
||||
<textBlock
|
||||
|
|
@ -84,11 +84,11 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
addressQuestions: {
|
||||
streetAddress: this.getServiceAddressFromStore(),
|
||||
apartmentNumberOrBusinessName: this.getServiceAddress2FromStore(),
|
||||
city: this.getServiceCityFromStore(),
|
||||
state: this.getServiceStateFromStore(),
|
||||
zipCode: this.getServiceZipCodeFromStore(),
|
||||
streetAddress: String(this.getServiceAddressFromStore() ?? ""),
|
||||
apartmentNumberOrBusinessName: String(this.getServiceAddress2FromStore() ?? ""),
|
||||
city: String(this.getServiceCityFromStore() ?? ""),
|
||||
state: String(this.getServiceStateFromStore() ?? ""),
|
||||
zipCode: String(this.getServiceZipCodeFromStore() ?? ""),
|
||||
},
|
||||
isVehicleProtected: this.getIsVehicleProtectedFromStore(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ export default {
|
|||
name: "vehicle-protected-question",
|
||||
props: {
|
||||
modelValue: {
|
||||
isVehicleProtected: Boolean,
|
||||
type: Boolean,
|
||||
default: null,
|
||||
},
|
||||
cmsWidgetName: String,
|
||||
labelBold: {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ export default {
|
|||
name: "service-zip-question",
|
||||
props: {
|
||||
modelValue: {
|
||||
serviceZipCode: String,
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
cmsWidgetName: String,
|
||||
isRequired: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue