Merge pull request #1025 from Safelite/feature/CSR-1214-release
Post Tech Review changes for CSR-1214
This commit is contained in:
commit
6519745d9d
4 changed files with 365 additions and 172 deletions
|
|
@ -198,139 +198,6 @@ describe("textboxQuestion.vue", () => {
|
||||||
expect(wrapper.vm.handleChange).toHaveBeenCalled;
|
expect(wrapper.vm.handleChange).toHaveBeenCalled;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should call this.handleChange when image is submitted with valid value.", async () => {
|
|
||||||
// Arrange
|
|
||||||
const inputId = "test";
|
|
||||||
const responseValue = "testResponse";
|
|
||||||
|
|
||||||
const storeMixin = {
|
|
||||||
methods: {
|
|
||||||
dispatchStoreAction: jest.fn().mockImplementation(() => {
|
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
resolve({
|
|
||||||
data: [responseValue],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallowMount(textboxQuestion, {
|
|
||||||
global: {
|
|
||||||
directives: {
|
|
||||||
maska: maska,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
modelValue: "",
|
|
||||||
includeCameraIcon: true,
|
|
||||||
inputId: inputId,
|
|
||||||
},
|
|
||||||
mixins: [mockMixin, storeMixin],
|
|
||||||
attachTo: document.body,
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
|
||||||
|
|
||||||
await imageUploadField.trigger("change");
|
|
||||||
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleChange).toHaveBeenCalled();
|
|
||||||
expect(wrapper.emitted()).toHaveProperty("update:modelValue");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should emit image-lookup-error when image is submitted with invalid value", async () => {
|
|
||||||
// Arrange
|
|
||||||
const inputId = "test";
|
|
||||||
|
|
||||||
const storeMixin = {
|
|
||||||
methods: {
|
|
||||||
dispatchStoreAction: jest.fn().mockImplementation(() => {
|
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
resolve({
|
|
||||||
data: [],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallowMount(textboxQuestion, {
|
|
||||||
global: {
|
|
||||||
directives: {
|
|
||||||
maska: maska,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
modelValue: "",
|
|
||||||
includeCameraIcon: true,
|
|
||||||
inputId: inputId,
|
|
||||||
},
|
|
||||||
mixins: [mockMixin, storeMixin],
|
|
||||||
attachTo: document.body,
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
|
||||||
|
|
||||||
await imageUploadField.trigger("change");
|
|
||||||
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.handleChange).not.toHaveBeenCalled();
|
|
||||||
expect(wrapper.emitted()).toHaveProperty("imageLookupError");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should emit image-lookup-error when image endpoint responds with an error", async () => {
|
|
||||||
// Arrange
|
|
||||||
const inputId = "test";
|
|
||||||
|
|
||||||
const storeMixin = {
|
|
||||||
methods: {
|
|
||||||
dispatchStoreAction: jest.fn().mockImplementation(() => {
|
|
||||||
return new Promise((resolve, reject) => reject());
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallowMount(textboxQuestion, {
|
|
||||||
global: {
|
|
||||||
directives: {
|
|
||||||
maska: maska,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
modelValue: "",
|
|
||||||
includeCameraIcon: true,
|
|
||||||
inputId: inputId,
|
|
||||||
},
|
|
||||||
mixins: [mockMixin, storeMixin],
|
|
||||||
attachTo: document.body,
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
|
||||||
|
|
||||||
await imageUploadField.trigger("change");
|
|
||||||
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.handleChange).not.toHaveBeenCalled();
|
|
||||||
expect(wrapper.emitted()).toHaveProperty("imageLookupError");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should not display camera or spinner icon when disabled", () => {
|
it("Should not display camera or spinner icon when disabled", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const inputId = "test";
|
const inputId = "test";
|
||||||
|
|
@ -343,7 +210,7 @@ describe("textboxQuestion.vue", () => {
|
||||||
},
|
},
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: "",
|
modelValue: "",
|
||||||
includeCameraIcon: true,
|
includeImageQuestion: true,
|
||||||
inputId: inputId,
|
inputId: inputId,
|
||||||
isDisabled: true,
|
isDisabled: true,
|
||||||
},
|
},
|
||||||
|
|
@ -359,4 +226,220 @@ describe("textboxQuestion.vue", () => {
|
||||||
expect(cameraIcon.exists()).toBe(false);
|
expect(cameraIcon.exists()).toBe(false);
|
||||||
expect(loadingIcon.exists()).toBe(false);
|
expect(loadingIcon.exists()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Image Uploading", () => {
|
||||||
|
it("Should call this.handleChange & emit update when fully valid image is submitted.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const inputId = "test";
|
||||||
|
const responseValue = "testResponse";
|
||||||
|
|
||||||
|
const imageHandler = jest.fn().mockImplementation(
|
||||||
|
() =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
resolve({
|
||||||
|
data: [responseValue],
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
modelValue: "",
|
||||||
|
"onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }),
|
||||||
|
includeImageQuestion: true,
|
||||||
|
inputId: inputId,
|
||||||
|
imageQuestionSubmitHandler: imageHandler,
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
attachTo: document.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
||||||
|
wrapper.vm.isImageValid = jest.fn().mockImplementation(() => true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
||||||
|
|
||||||
|
await imageUploadField.trigger("change");
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
expect(wrapper.vm.imageQuestionSubmitHandler).toHaveBeenCalled();
|
||||||
|
expect(wrapper.vm.handleChange).toHaveBeenCalled();
|
||||||
|
expect(wrapper.emitted()).toHaveProperty("update:modelValue");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not call handler and emit image-lookup-error when image is invalid.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const inputId = "test";
|
||||||
|
const responseValue = "testResponse";
|
||||||
|
|
||||||
|
const imageHandler = jest.fn().mockImplementation(
|
||||||
|
() =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
resolve({
|
||||||
|
data: [responseValue],
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
modelValue: "",
|
||||||
|
"onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }),
|
||||||
|
includeImageQuestion: true,
|
||||||
|
inputId: inputId,
|
||||||
|
imageQuestionSubmitHandler: imageHandler,
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
attachTo: document.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
||||||
|
wrapper.vm.isImageValid = jest.fn().mockImplementation(() => false);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
||||||
|
|
||||||
|
await imageUploadField.trigger("change");
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.imageQuestionSubmitHandler).not.toHaveBeenCalled();
|
||||||
|
expect(wrapper.vm.handleChange).not.toHaveBeenCalled();
|
||||||
|
expect(wrapper.emitted()).toHaveProperty("imageValidityError");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should emit image-lookup-error when image lookup responds with an error.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const inputId = "test";
|
||||||
|
|
||||||
|
const imageHandler = jest.fn().mockImplementation(
|
||||||
|
() =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
reject({});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
modelValue: "",
|
||||||
|
"onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }),
|
||||||
|
includeImageQuestion: true,
|
||||||
|
inputId: inputId,
|
||||||
|
imageQuestionSubmitHandler: imageHandler,
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
attachTo: document.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.handleChange = jest.fn().mockImplementation(() => {});
|
||||||
|
wrapper.vm.isImageValid = jest.fn().mockImplementation(() => true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const imageUploadField = wrapper.find('[data-test="image-upload"]');
|
||||||
|
|
||||||
|
await imageUploadField.trigger("change");
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.imageQuestionSubmitHandler).toHaveBeenCalled();
|
||||||
|
expect(wrapper.vm.handleChange).not.toHaveBeenCalled();
|
||||||
|
expect(wrapper.emitted()).toHaveProperty("imageLookupError");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Image Validation", () => {
|
||||||
|
it("Should return true if a valid image is tested.", () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
inputId: "input ID",
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = {
|
||||||
|
size: 100 * 1028,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.isImageValid(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return false if null image is tested.", () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
inputId: "input ID",
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.isImageValid(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return false if oversized image is tested.", () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(textboxQuestion, {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska: maska,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
propsData: {
|
||||||
|
inputId: "input ID",
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = {
|
||||||
|
size: 10000000 * 1028,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.isImageValid(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
class="input-wrapper"
|
class="input-wrapper"
|
||||||
:class="[
|
:class="[
|
||||||
includeSearchIcon ? 'has-search-icon' : '',
|
includeSearchIcon ? 'has-search-icon' : '',
|
||||||
includeCameraIcon ? 'has-camera-icon' : '',
|
includeImageQuestion ? 'has-camera-icon' : '',
|
||||||
]">
|
]">
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
|
@ -36,20 +36,22 @@
|
||||||
:maxlength="maxLength ? maxLength : '999'"
|
:maxlength="maxLength ? maxLength : '999'"
|
||||||
@focus="$emit('focus', $event.target.value)" />
|
@focus="$emit('focus', $event.target.value)" />
|
||||||
<button v-if="includeSearchIcon" type="submit" aria-label="Search button" />
|
<button v-if="includeSearchIcon" type="submit" aria-label="Search button" />
|
||||||
<template v-if="!isDisabled">
|
<template v-if="includeImageQuestion">
|
||||||
<label class="camera-icon-input" v-show="includeCameraIcon && !isLoading">
|
<template v-if="!isDisabled">
|
||||||
<input
|
<label class="camera-icon-input" v-show="!isImageProcessing">
|
||||||
type="file"
|
<input
|
||||||
id="vin-input"
|
type="file"
|
||||||
accept="image/jpeg,image/png"
|
id="vin-input"
|
||||||
aria-label="Camera icon/button"
|
accept="image/jpeg,image/png"
|
||||||
data-test="image-upload"
|
aria-label="Camera icon/button"
|
||||||
@change="submitImage" />
|
data-test="image-upload"
|
||||||
</label>
|
@change="imageChanged" />
|
||||||
<loader
|
</label>
|
||||||
v-show="includeCameraIcon && isLoading"
|
<loader
|
||||||
loaderColor="blue"
|
v-show="isImageProcessing"
|
||||||
class="loading-icon"></loader>
|
loaderColor="blue"
|
||||||
|
class="loading-icon"></loader>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="errorMessage" class="row my-2 form-test-error">
|
<div v-show="errorMessage" class="row my-2 form-test-error">
|
||||||
|
|
@ -92,13 +94,14 @@ export default {
|
||||||
questionAlignment: String, // Left or center. Left is default.
|
questionAlignment: String, // Left or center. Left is default.
|
||||||
cornerStyle: String, // Rounded or square. Square is default.
|
cornerStyle: String, // Rounded or square. Square is default.
|
||||||
includeSearchIcon: Boolean,
|
includeSearchIcon: Boolean,
|
||||||
includeCameraIcon: Boolean,
|
includeImageQuestion: Boolean,
|
||||||
|
imageQuestionSubmitHandler: Function,
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const propsClone = Object.assign({}, props);
|
const propsClone = Object.assign({}, props);
|
||||||
const modelValue = propsClone.modelValue;
|
const modelValue = propsClone.modelValue;
|
||||||
let initialValue;
|
let initialValue;
|
||||||
let isLoading = ref(false);
|
let isImageProcessing = ref(false);
|
||||||
|
|
||||||
switch (typeof modelValue) {
|
switch (typeof modelValue) {
|
||||||
case "number":
|
case "number":
|
||||||
|
|
@ -128,30 +131,35 @@ export default {
|
||||||
validate,
|
validate,
|
||||||
meta,
|
meta,
|
||||||
errors,
|
errors,
|
||||||
isLoading,
|
isImageProcessing,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async submitImage(e) {
|
async imageChanged(e) {
|
||||||
this.isLoading = true;
|
let file = e.target.files[0];
|
||||||
await this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_IMAGE, e.target.files[0])
|
|
||||||
.then(async (response) => {
|
|
||||||
if (response.data.length > 0) {
|
|
||||||
this.value = response.data[0];
|
|
||||||
|
|
||||||
// Wait for DOM to update before firing change event to handle validation.
|
if (!this.isImageValid(file)) {
|
||||||
await this.$nextTick();
|
this.$emit("imageValidityError");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById(this.inputId).dispatchEvent(new Event("change"));
|
this.isImageProcessing = true;
|
||||||
} else {
|
|
||||||
this.$emit("imageLookupError");
|
try {
|
||||||
}
|
this.value = await this.imageQuestionSubmitHandler(file);
|
||||||
})
|
|
||||||
.catch((error) => {
|
await this.$nextTick();
|
||||||
this.$emit("imageLookupError");
|
|
||||||
});
|
document.getElementById(this.inputId).dispatchEvent(new Event("change"));
|
||||||
this.isLoading = false;
|
} catch (error) {
|
||||||
e.target.value = null;
|
this.$emit("imageLookupError");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isImageProcessing = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
isImageValid(imageFile) {
|
||||||
|
return imageFile && imageFile.size < this.maxFileSize;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -190,6 +198,12 @@ export default {
|
||||||
return questionText;
|
return questionText;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
maxFileSize() {
|
||||||
|
let kiloBytes = 5140;
|
||||||
|
|
||||||
|
return kiloBytes * 1028;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
async value(newValue) {
|
async value(newValue) {
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,84 @@ describe("vin-lookup.vue", () => {
|
||||||
expect(wrapper.findAllComponents({ name: "alert" }).length).toBe(1);
|
expect(wrapper.findAllComponents({ name: "alert" }).length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getVinFromImage", () => {
|
||||||
|
test("GetVinFromImage resolves with first valid VIN when any vins are returned.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const responseValue = "testResponse";
|
||||||
|
const lookup = jest.fn().mockImplementation(() => {
|
||||||
|
return new Promise((resolve, reject) => resolve([responseValue]));
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = {};
|
||||||
|
|
||||||
|
const storeMixin = {
|
||||||
|
methods: {
|
||||||
|
dispatchStoreAction: lookup,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mixins: [storeMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const response = await wrapper.vm.getVinFromImage(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(lookup).toHaveBeenCalled();
|
||||||
|
expect(response).toEqual(responseValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GetVinFromImage rejects if no vins are returned.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const lookup = jest.fn().mockImplementation(() => {
|
||||||
|
return new Promise((resolve, reject) => resolve([]));
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = {};
|
||||||
|
|
||||||
|
const storeMixin = {
|
||||||
|
methods: {
|
||||||
|
dispatchStoreAction: lookup,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mixins: [storeMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const promise = wrapper.vm.getVinFromImage(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await expect(promise).rejects.toEqual("No VINs detected.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GetVinFromImage rejects if an error occurs.", async () => {
|
||||||
|
const lookup = jest.fn().mockImplementation(() => {
|
||||||
|
return new Promise((resolve, reject) => reject());
|
||||||
|
});
|
||||||
|
|
||||||
|
const image = {};
|
||||||
|
|
||||||
|
const storeMixin = {
|
||||||
|
methods: {
|
||||||
|
dispatchStoreAction: lookup,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mixins: [storeMixin],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const promise = wrapper.vm.getVinFromImage(image);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await expect(promise).rejects.toEqual("An error occurred during the lookup.");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({ customMountOptions }) {
|
function setupMocks({ customMountOptions }) {
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,13 @@
|
||||||
validationRules="vin-required|vin-format"
|
validationRules="vin-required|vin-format"
|
||||||
:isDisabled="vinPopulatedOnPageLoad"
|
:isDisabled="vinPopulatedOnPageLoad"
|
||||||
maxLength="17"
|
maxLength="17"
|
||||||
includeCameraIcon
|
|
||||||
:mask="vinMask"
|
:mask="vinMask"
|
||||||
|
includeImageQuestion
|
||||||
|
:imageQuestionSubmitHandler="getVinFromImage"
|
||||||
@image-lookup-error="displayVinScanAlert"
|
@image-lookup-error="displayVinScanAlert"
|
||||||
data-test="vin-lookup-field" />
|
@image-validity-error="displayVinScanAlert"
|
||||||
|
data-test="vin-lookup-field"
|
||||||
|
ref="vinLookupQuestion" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -395,6 +398,21 @@ export default {
|
||||||
displayVinScanAlert() {
|
displayVinScanAlert() {
|
||||||
this.displayVinScanFailedAlert = true;
|
this.displayVinScanFailedAlert = true;
|
||||||
},
|
},
|
||||||
|
getVinFromImage(image) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_IMAGE, image)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
resolve(response.data[0]);
|
||||||
|
} else {
|
||||||
|
reject("No VINs detected.");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject("An error occurred during the lookup.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
resetAlerts() {
|
resetAlerts() {
|
||||||
this.displayMatchedDifferentVehicleAlert = false;
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue