Merge branch 'develop' into feature/switch-dns

This commit is contained in:
FrankRua 2022-10-07 12:55:24 -04:00
commit c5254768c0
21 changed files with 998 additions and 267 deletions

View file

@ -26,7 +26,7 @@ resources:
type: github
name: Safelite/AzureDevOps
endpoint: Safelite
ref: refs/tags/t5.5.19
ref: refs/tags/t5.5.31
variables:
- group: Digital-Infrastructure
@ -173,5 +173,6 @@ stages:
cfDistributionId: $(cfDistributionId)
- template: templates/digital/auto-tag.yml@AzureDevOps
parameters:
dependsOn: prodBuildDeployment
userName: SafeliteAzureDevops
userEmail: githubazuredevops@safelite.com

View file

@ -0,0 +1 @@
test.todo("some test to be written in the future");

View file

@ -0,0 +1,459 @@
<template>
<div id="app">
<fieldset>
<legend class="d-flex justify-content-center">Date Picker</legend>
<div class="grid-container">
<!-- Do the days of the weeek need to be read? -->
<div class="grid-item"><span class="sr-only">Sunday</span>S</div>
<div class="grid-item"><span class="sr-only">Monday</span>M</div>
<div class="grid-item"><span class="sr-only">Tuesday</span>T</div>
<div class="grid-item"><span class="sr-only">Wednesday</span>W</div>
<div class="grid-item"><span class="sr-only">Thursday</span>T</div>
<div class="grid-item"><span class="sr-only">Friday</span>F</div>
<div class="grid-item"><span class="sr-only">Saturday</span>S</div>
<div class="grid-item radio-wrapper past-day">
<input type="radio" name="day-of-month" id="thirtypast" />
<label for="thirtypast"><span>30</span></label>
</div>
<div class="grid-item radio-wrapper past-day">
<input type="radio" name="day-of-month" id="thirtyonepast" />
<label for="thirtyonepast"><span>31</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day first-of-month">
<div v-if="isFirstDayOfMonth" class="current-month">OCT</div>
<input type="radio" name="day-of-month" id="one" />
<label for="one"><span class="sr-only">{{dayOfWeek}} {{pastMonth}} {{dayOfMonth}}</span><span>1</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="two" />
<label for="two"><span>2</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="three" />
<label for="three"><span>3</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day" :class="[isCurrentDay ? 'current-day' : '']">
<div v-if="isCurrentDayDot" class="current-day-dot"></div>
<input type="radio" name="day-of-month" id="four" />
<label for="four"><span>4</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="five" />
<label for="five"><span>5</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="six" />
<label for="six"><span>6</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="seven" />
<label for="seven"><span>7</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="eight" />
<label for="eight"><span>8</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="nine" />
<label for="nine"><span>9</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="ten" />
<label for="ten"><span>10</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="eleven" />
<label for="eleven"><span>11</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twelve" />
<label for="twelve"><span>12</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="thirteen" />
<label for="thirteen"><span>13</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="fourteen" />
<label for="fourteen"><span>17</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="fifteen" />
<label for="fifteen"><span>15</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="sixteen" />
<label for="sixteen"><span>16</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="seventeen" />
<label for="seventeen"><span>17</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="eighteen" />
<label for="eighteen"><span>18</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="nineteen" />
<label for="nineteen"><span>19</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twenty" />
<label for="twenty"><span>20</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentyone" />
<label for="twentyone"><span>21</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentytwo" />
<label for="twentytwo"><span>22</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentythree" />
<label for="twentythree"><span>23</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentyfour" />
<label for="twentyfour"><span>24</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentyfive" />
<label for="twentyfive"><span>25</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentysix" />
<label for="twentysix"><span>26</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentyseven" />
<label for="twentyseven"><span>27</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentyeight" />
<label for="twentyeight"><span>28</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="twentynine" />
<label for="twentynine"><span>29</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="thirty" />
<label for="thirty"><span>30</span></label>
</div>
<div class="grid-item radio-wrapper highlighted-day">
<input type="radio" name="day-of-month" id="thirtyone" />
<label for="thirtyone"><span>31</span></label>
</div>
<div class="grid-item radio-wrapper future-day">
<input type="radio" name="day-of-month" id="onefuture" />
<label for="onefuture"><span>1</span></label>
</div>
<div class="grid-item radio-wrapper future-day">
<input type="radio" name="day-of-month" id="twofuture" />
<label for="twofuture"><span>2</span></label>
</div>
</div>
</fieldset>
</div>
<form class="w-100 d-flex justify-content-center mt-5">
<input type="date">
</form>
</template>
<script>
export default {
name: "datePicker",
data() {
return {
dayOfWeek: "Tuesday",
dayOfMonth: "1st",
pastMonth: "October",
isFirstDayOfMonth: true,
isCurrentDay: true,
isCurrentDayDot: true,
};
},
};
</script>
<style lang="scss">
.container {
//max-width: 341px;
label {
display: initial; //Override Bootstrap default
}
#availableDates label:nth-child(14n):after {
content: "\a";
white-space: pre;
}
}
.grid-container {
margin: 0 auto;
max-width: 341px;
display: grid;
grid-gap: 4px;
grid-template-columns: auto auto auto auto auto auto auto;
justify-content: center;
align-items: center;
.grid-item {
text-align: center;
padding: 4px;
}
.radio-wrapper {
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
width: 46px;
height: 46px;
.current-day-dot {
position: absolute;
}
&.first-of-month {
.current-month {
position: absolute;
font-size: 9px;
top: 4px;
color: #1574a1;
}
}
&.highlighted-day {
input[type="radio"] {
position: absolute;
// opacity: 0;
height: 0.1px;
width: 0.1px;
+ label {
position: relative;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
color: #1574a1;
span {
z-index: 2;
}
&::before {
content: "";
position: absolute;
border-radius: 50%;
border: 1px solid #1574a1;
background-color: #e4f1f7;
color: #1574a1;
width: 40px;
height: 40px;
z-index: -1;
}
&::after {
content: "";
position: absolute;
border-radius: 50%;
width: 40px;
height: 40px;
}
}
&:checked {
+ label::after {
background: #1574a1;
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
color: #fff;
}
+ label span {
color: #fff;
}
}
&:focus {
+ label::before {
background-color: #1574a1;
}
+ label span {
color: #fff;
}
}
}
}
&.past-day {
input[type="radio"] {
position: absolute;
opacity: 0;
height: 0.1px;
width: 0.1px;
+ label {
position: relative;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
color: #8E9292;
span {
z-index: 2;
}
&::before {
content: "";
position: absolute;
border-radius: 50%;
border: 1px solid transparent;
background-color: transparent;
color: #1574a1;
width: 40px;
height: 40px;
z-index: -1;
}
&::after {
content: "";
position: absolute;
border-radius: 50%;
width: 40px;
height: 40px;
}
}
&:checked {
+ label::after {
background: #1574a1;
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
color: #fff;
}
+ label span {
color: #fff;
}
}
&:focus {
+ label::before {
background-color: transparent;
}
+ label span {
color: #1574a1;
}
}
&:active {
+ label::before {
background-color: #1574a1;
}
+ label span {
color: #fff;
}
}
}
}
&.future-day {
input[type="radio"] {
position: absolute;
opacity: 0;
height: 0.1px;
width: 0.1px;
+ label {
position: relative;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
color: #4D5151;
span {
z-index: 2;
}
&::before {
content: "";
position: absolute;
border-radius: 50%;
border: 1px solid transparent;
background-color: transparent;
color: #1574a1;
width: 40px;
height: 40px;
z-index: -1;
}
&::after {
content: "";
position: absolute;
border-radius: 50%;
width: 40px;
height: 40px;
}
}
}
}
&.current-day {
input[type="radio"] {
position: absolute;
// opacity: 0;
height: 0.1px;
width: 0.1px;
&:after {
content: "\A";
width:4px;
height:4px;
border-radius:50%;
background: #1574a1;
position: absolute;
top: 8px;
left: -1px;
z-index: 1;
}
&:checked {
+ label::after {
background: #1574a1;
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
color: #fff;
}
+ label span {
color: #fff;
}
&:after {
background: #fff;
}
}
}
span {
position: relative;
top: -.25rem;
}
}
}
}
</style>

View file

@ -3,13 +3,13 @@
<div class="modal fade modal-component" :id="this.cmsWidgetName" tabindex="-1" aria-labelledby="ModalComponentLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body px-4 py-5">
<div class="modal-body ps-4 pe-4 pt-5 pb-4">
<img :src="this.ModalImage" class="w-100 mb-4" alt="" />
<h5 class="mb-4" v-html="this.ModalHeadline"></h5>
<p class="fw-bold mb-2 subheader-text" v-html="this.ModalSubheadertext"></p>
<p class="mb-0" v-html="this.ModalBodyText"></p>
</div>
<div class="modal-footer">
<div class="modal-footer px-4 pt-4 pb-5">
<button class="btn btn-secondary w-100" data-bs-dismiss="modal" v-html="this.ModalCloseButtonText"></button>
</div>
</div>
@ -60,11 +60,19 @@ export default {
ul {
margin-bottom: 0;
}
p {
&:last-child {
margin-bottom: 0;
}
}
}
}
}
.modal-footer {
border-top: none;
button {
margin: 0;
}
}
}
}

View file

@ -72,7 +72,7 @@ export default {
this.currentQuestionNum = this.questions[0].questionSequence;
// scroll the next question into view
this.$nextTick(() => {
document.querySelector('.current-question').scrollIntoView({behavior: "smooth"});
document.querySelector('.current-question')?.scrollIntoView({behavior: "smooth"});
})
}
},

View file

@ -1 +1,60 @@
test.todo("some test to be written in the future");
import { shallowMount } from "@vue/test-utils";
import TextBlock from "./text-block";
describe("modal.vue", () => {
it("Should display 'Text' when 'Text' is defined in the CMS", async () => {
// Act
const wrapper = shallowMount(TextBlock, {
mixins: [mockMixin]
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent['Text']));
});
it("Should contain the typeStyle class as defined by the prop", async () => {
// Act
const wrapper = shallowMount(TextBlock, {
mixins: [mockMixin],
propsData: mockProps,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockProps['typeStyle']));
});
it("Should contain the justifyText class as defined by the prop", async () => {
// Act
const wrapper = shallowMount(TextBlock, {
mixins: [mockMixin],
propsData: mockProps,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockProps['justifyText']));
});
it("Should contain the fontWeight class as defined by the prop", async () => {
// Act
const wrapper = shallowMount(TextBlock, {
mixins: [mockMixin],
propsData: mockProps,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockProps['fontWeight']));
});
});
///////////////
// Constants //
///////////////
const mockMixin = {
methods: {
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
return mockCmsContent[cmsFieldName];
})
}
}
const mockProps = {
fontWeight: 'mockFontWeight',
typeStyle: 'mockTypeStyle',
justifyText: 'mockJustifyText'
}
const mockCmsContent = {
'Text': "Sample text here.",
}

View file

@ -7,6 +7,7 @@ const applicationConfig = {
COOKIE_PATH: "/",
CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod"
APPLICATION_NAME: "FixMyGlass",
APPLICATION_ABBREVIATION: "fmg",
SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass"
};

View file

@ -1,10 +1,14 @@
const endpoints = {
GetRouteInfo: {
url: "/content/api/v1/content/RouteInfo",
url: (applicationAbbreviation) => `/content/api/v1/content/${applicationAbbreviation}/RouteInfo`,
method: "POST",
},
GetHomepageInfo: {
url: "/content/api/v1/content/HomepageInfo",
url: (applicationAbbreviation) => `/content/api/v1/content/${applicationAbbreviation}/HomepageInfo`,
method: "GET",
},
GetPageData: {
url: (applicationAbbreviation, pageName) => `/content/api/v1/content/${applicationAbbreviation}/${pageName}`,
method: "GET",
},
GetVehicleYears: {
@ -31,10 +35,6 @@ const endpoints = {
url: "/parts/api/v1/parts/damage-options",
method: "GET",
},
GetPageData: {
url: "/content/api/v1/content",
method: "GET",
},
LookupVehicleByYmms: {
url: "/vehicle/api/v1/vehicle/Lookup",
method: "GET",

View file

@ -50,6 +50,7 @@ export async function navigateToHeritageFunnel(shouldSaveOrder = true) {
{
corid: store.getters.order.referralCorrelationId,
src: "concept-funnel",
conceptsqid: store.getters.applicationUser.savedSessionId
}
);
}

View file

@ -76,7 +76,6 @@ export default {
capabilityQuestionsData: store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS).partsOrQuestions,
selectedAnswers: {},
currentQuestionChainIndex: 0,
foundDuplicateQuestions: [],
};
},
computed: {
@ -97,7 +96,17 @@ export default {
}
},
mounted() {
this.loadInitialCapabilityQuestionsData();
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers;
this.capabilityQuestionsData = this.pageData.partsOrQuestions.filter(x => x.capabilityQuestions).map((glass, i) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.capabilityQuestions;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.key] = [];
// pass in: glass, i, alreadyAnsweredQuestions
return this.setupInitialData(glass, i, alreadyAnsweredQuestions);
});
},
methods: {
showThisQuestionChain(glass, i) {
@ -110,14 +119,13 @@ export default {
},
async forwardButtonAction() {
const capabilityQuestionsAnswersArray = this.capabilityQuestionsData.map((glass) => {
const selectedAnswerResult1 = glass.answerData.answerResult;
const selectedAnswerResult2 = glass.answerData.answerResult2;
const selectedAnswerResult2 = this.getCorrespondingAnswerResult2(glass.answerData.answerResult);
return {
glassLocation: glass.glassLocation,
glassName: glass.glassName,
result: glass.answerData.answerResult,
result1: selectedAnswerResult1,
result1: glass.answerData.answerResult,
result2: selectedAnswerResult2,
answeredQuestions: glass.answerData.answeredQuestions,
isSuppressedPart: glass.isSuppressedPart,
@ -147,7 +155,7 @@ export default {
// only runs when all questions in a question-chain have been answered
// when selectedAnswers updates, user has completed this part's question chain and has a final answer
// (does not get run for each invididual question's answer, only when
// all relevent questions for the current part have been answered)
// all relevant questions for the current part have been answered)
/*
answer example format:
@ -166,6 +174,7 @@ export default {
// collect a list of the answered questions' numbers, needed later below
const answeredQuestionIndexes = [];
const foundDuplicateQuestions = [];
// if user has answered a question differently than anything that was preloaded,
// we need to clear out any preloaded answers
@ -255,7 +264,6 @@ export default {
// restore original answerResult
if (thisAns.originalAnswerResult) {
thisAns.answerResult = thisAns.originalAnswerResult;
thisAns.answerResult1 = thisAns.originalAnswerResult;
thisAns.originalAnswerResult = null;
}
}
@ -270,7 +278,6 @@ export default {
thisAns.nextQuestionSequence = null;
thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult;
thisAns.answerResult = matchedAnswer.answerResult;
thisAns.answerResult1 = matchedAnswer.answerResult;
}
}
});
@ -280,12 +287,12 @@ export default {
thisAnsweredCapabilityQuestion.suppressQuestion = true;
const thisGlassPart = "glass" + gpIndex;
if (this.foundDuplicateQuestions[thisGlassPart]) {
if (!this.foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredCapabilityQuestion.questionSequence)) {
this.foundDuplicateQuestions[thisGlassPart].push(thisAnsweredCapabilityQuestion.questionSequence);
if (foundDuplicateQuestions[thisGlassPart]) {
if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredCapabilityQuestion.questionSequence)) {
foundDuplicateQuestions[thisGlassPart].push(thisAnsweredCapabilityQuestion.questionSequence);
}
} else {
this.foundDuplicateQuestions[thisGlassPart] = [thisAnsweredCapabilityQuestion.questionSequence];
foundDuplicateQuestions[thisGlassPart] = [thisAnsweredCapabilityQuestion.questionSequence];
}
// are there any questions left that are not suppressed?
@ -306,7 +313,6 @@ export default {
// set the answerData as 'already answered'
glass.answerData = {
answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult,
answerResult1: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult,
answeredQuestions: [answeredQuestionObj],
};
@ -332,12 +338,12 @@ export default {
// EX answeredQuestionIndexes: [1,5,11,13]
// EX this.foundDuplicateQuestions = {
// EX foundDuplicateQuestions = {
// "glassPart1": [1],
// "glassPart2": [7, 10]
// };
const thisPartsDupes = this.foundDuplicateQuestions["glass" + answer.glassIndex];
const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex];
const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : [];
const glassPartAnswered = this.capabilityQuestionsData[answer.glassIndex];
@ -383,14 +389,9 @@ export default {
});
filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a, b) => a.questionNum - b.questionNum);
const selectedAnswerResult1 = answer.answerResult;
const selectedAnswerResult2 = this.getCorrespondingAnswerResult2(selectedAnswerResult1);
// set final answer data for the current answered glass part
glassPartAnswered.answerData = {
answerResult: selectedAnswerResult1,
answerResult1: selectedAnswerResult1,
answerResult2: selectedAnswerResult2,
answerResult: answer.answerResult,
answeredQuestions: filteredCompleteAnsweredQuestions,
}
@ -412,73 +413,6 @@ export default {
.answers.find(answer => answer.answerResult == answerResult1)
.answerResult2;
},
loadInitialCapabilityQuestionsData() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers;
this.capabilityQuestionsData = this.pageData.partsOrQuestions.filter(x => x.capabilityQuestions).map((glass, i) => {
glass.key = glass.glassLocation + "-" + glass.glassName;
this.selectedAnswers[glass.key] = [];
if (!alreadyAnsweredQuestions) {
glass.answerData = null;
}
alreadyAnsweredQuestions?.forEach((savedPart) => {
if (!savedPart.glassLocation || !savedPart.glassName || !savedPart.answeredQuestions || !savedPart.result) {
return;
}
if (glass.glassLocation === savedPart.glassLocation && glass.glassName === savedPart.glassName) {
let answerString = "";
// matches; loop through answeredQuestions for matches
savedPart.answeredQuestions.forEach((aq) => {
if (!aq.questionNum || !aq.selectedAnswerText) {
return;
}
// determine which answer was previously chosen
const theAns = glass.capabilityQuestions[aq.questionNum - 1].answers.find((a) => {
return a.answerText.toUpperCase() === aq.selectedAnswerText.toUpperCase();
});
if (theAns.nextQuestionSequence) {
answerString = `${aq.questionNum}|nextQuestion|${theAns.nextQuestionSequence}|${theAns.answerText}`
} else {
answerString = `${aq.questionNum}|answer|${theAns.answerResult}|${theAns.answerText}`
}
// mark this partQuestion as answered (question-chain will read this)
glass.capabilityQuestions[aq.questionNum - 1].answerSelected = answerString;
// mark this partQuestion as duplicate if it is (question-chain will read this)
if (aq.suppressQuestion) {
glass.capabilityQuestions[aq.questionNum - 1].suppressQuestion = true;
}
});
// advance the currentQuestionChainIndex
this.currentQuestionChainIndex = i;
// add answerData to current glass
glass.answerData = {
answerResult: savedPart.result,
answerResult1: savedPart.result,
answerResult2: this.getCorrespondingAnswerResult2(savedPart.result),
answeredQuestions: savedPart.answeredQuestions
}
}
});
// Set up watch for each set of glass questions, which gets updated when all questions for a glass have been answered
this.$watch("selectedAnswers." + glass.key, (newValue) => {
if (newValue) {
this.handleAnswerUpdates(newValue);
}
}, { deep: true })
return glass;
});
},
},
components: {
funnelHeader,

View file

@ -94,7 +94,6 @@ export default {
moldingQuestionsData: store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS).partsOrQuestions,
selectedAnswers: {},
currentGlassIndex: 0,
foundDuplicateQuestions: [],
};
},
computed: {
@ -109,7 +108,17 @@ export default {
}
},
mounted() {
this.LoadInitialData();
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.moldingQuestionAnswers;
this.moldingQuestionsData = this.pageData.partsOrQuestions.filter(x => x.parts[0].childPartQuestions.length).map((glass, i) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.parts[0].childPartQuestions;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.key] = [];
// pass in: glass, i, alreadyAnsweredQuestions
return this.setupInitialData(glass, i, alreadyAnsweredQuestions);
});
},
methods: {
arePagePrerequisitesValid() {
@ -153,11 +162,11 @@ export default {
this.navigateForward(partsOrQuestions);
},
handleAnswerUpdates(key, answer) {
handleAnswerUpdates(answer) {
// only runs when all questions in a question-chain have been answered
// when selectedAnswers updates, user has completed this part's question chain and has a final answer
// (does not get run for each invididual question's answer, only when
// all relevent questions for the current part have been answered)
// all relevant questions for the current part have been answered)
/*
answer example format:
@ -176,6 +185,7 @@ export default {
// collect a list of the answered questions' numbers, needed later below
const answeredQuestionIndexes = [];
const foundDuplicateQuestions = [];
// if user has answered a question differently than anything that was preloaded,
// we need to clear out any preloaded answers
@ -288,12 +298,12 @@ export default {
thisAnsweredPartQuestion.suppressQuestion = true;
const thisGlassPart = "glass" + gpIndex;
if (this.foundDuplicateQuestions[thisGlassPart]) {
if (!this.foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredPartQuestion.questionSequence)) {
this.foundDuplicateQuestions[thisGlassPart].push(thisAnsweredPartQuestion.questionSequence);
if (foundDuplicateQuestions[thisGlassPart]) {
if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredPartQuestion.questionSequence)) {
foundDuplicateQuestions[thisGlassPart].push(thisAnsweredPartQuestion.questionSequence);
}
} else {
this.foundDuplicateQuestions[thisGlassPart] = [thisAnsweredPartQuestion.questionSequence];
foundDuplicateQuestions[thisGlassPart] = [thisAnsweredPartQuestion.questionSequence];
}
// are there any questions left that are not suppressed?
@ -341,12 +351,12 @@ export default {
// EX answeredQuestionIndexes: [1,5,11,13]
// EX this.foundDuplicateQuestions = {
// EX foundDuplicateQuestions = {
// "glassPart1": [1],
// "glassPart2": [7, 10]
// };
const thisPartsDupes = this.foundDuplicateQuestions["glass" + answer.glassIndex];
const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex];
const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : [];
const glassPartAnswered = this.moldingQuestionsData[answer.glassIndex];
@ -408,75 +418,6 @@ export default {
}
},
LoadInitialData() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.moldingQuestionAnswers;
this.moldingQuestionsData = this.pageData.partsOrQuestions.filter(x => x.parts[0].childPartQuestions.length).map((glass, i) => {
glass.key = glass.glassLocation + "-" + glass.glassName;
// NOTE: property "questions" can differ between layouts
glass.questions = glass.parts[0].childPartQuestions;
this.selectedAnswers[glass.key] = [];
if (!alreadyAnsweredQuestions) {
glass.answerData = null;
}
alreadyAnsweredQuestions?.forEach((savedPart) => {
if (!savedPart.glassLocation || !savedPart.glassName || !savedPart.answeredQuestions || !savedPart.partNum) {
return;
}
if (glass.glassLocation === savedPart.glassLocation && glass.glassName === savedPart.glassName) {
let answerString = "";
// matches; loop through answeredQuestions for matches
savedPart.answeredQuestions.forEach((aq) => {
if (!aq.questionNum || !aq.selectedAnswerText) {
return;
}
// determine which answer was previously chosen
const theAns = glass.questions[aq.questionNum-1].answers.find((a) => {
return a.answerText.toUpperCase() === aq.selectedAnswerText.toUpperCase();
});
if (theAns.nextQuestionSequence) {
answerString = `${aq.questionNum}|nextQuestion|${theAns.nextQuestionSequence}|${theAns.answerText}`
} else {
answerString = `${aq.questionNum}|answer|${theAns.answerResult}|${theAns.answerText}`
}
// mark this partQuestion as answered (question-chain will read this)
glass.questions[aq.questionNum-1].answerSelected = answerString;
// mark this partQuestion as duplicate if it is (question-chain will read this)
if (aq.suppressQuestion) {
glass.questions[aq.questionNum-1].suppressQuestion = true;
}
});
// advance the currentGlassIndex
this.currentGlassIndex = i;
// add answerData to current glass
glass.answerData = {
answerResult: savedPart.partNum,
answeredQuestions: savedPart.answeredQuestions
}
}
});
// Set up watch for each set of glass questions, which gets updated when all questions for a glass have been answered
this.$watch("selectedAnswers." + glass.key, (newValue) => {
if (newValue) {
this.handleAnswerUpdates(glass.key, newValue);
}
}, {deep: true})
return glass;
});
},
},
components: {
funnelHeader,

View file

@ -90,10 +90,9 @@ export default {
},
data() {
return {
partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions,
partsQuestionsData: [],
selectedAnswers: {},
currentGlassIndex: 0,
foundDuplicateQuestions: [],
};
},
computed: {
@ -109,7 +108,17 @@ export default {
},
mixins: [vehicleQuestionsMixin],
mounted() {
this.LoadInitialData();
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.partQuestionAnswers;
this.partsQuestionsData = this.pageData.partsOrQuestions.filter(x => x.partQuestions).map((glass, i) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.partQuestions;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.key] = [];
// pass in: glass, i, alreadyAnsweredQuestions
return this.setupInitialData(glass, i, alreadyAnsweredQuestions);
});
},
methods: {
arePagePrerequisitesValid() {
@ -149,11 +158,11 @@ export default {
this.navigateForward(glassNameAndPartsForStore);
},
handleAnswerUpdates(key, answer) {
handleAnswerUpdates(answer) {
// only runs when all questions in a question-chain have been answered
// when selectedAnswers updates, user has completed this part's question chain and has a final answer
// (does not get run for each invididual question's answer, only when
// all relevent questions for the current part have been answered)
// all relevant questions for the current part have been answered)
/*
answer example format:
@ -172,6 +181,7 @@ export default {
// collect a list of the answered questions' numbers, needed later below
const answeredQuestionIndexes = [];
const foundDuplicateQuestions = [];
// if user has answered a question differently than anything that was preloaded,
// we need to clear out any preloaded answers
@ -284,12 +294,12 @@ export default {
thisAnsweredQuestion.suppressQuestion = true;
const thisGlassPart = "glass" + gpIndex;
if (this.foundDuplicateQuestions[thisGlassPart]) {
if (!this.foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredQuestion.questionSequence)) {
this.foundDuplicateQuestions[thisGlassPart].push(thisAnsweredQuestion.questionSequence);
if (foundDuplicateQuestions[thisGlassPart]) {
if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredQuestion.questionSequence)) {
foundDuplicateQuestions[thisGlassPart].push(thisAnsweredQuestion.questionSequence);
}
} else {
this.foundDuplicateQuestions[thisGlassPart] = [thisAnsweredQuestion.questionSequence];
foundDuplicateQuestions[thisGlassPart] = [thisAnsweredQuestion.questionSequence];
}
// are there any questions left that are not suppressed?
@ -337,12 +347,12 @@ export default {
// EX answeredQuestionIndexes: [1,5,11,13]
// EX this.foundDuplicateQuestions = {
// EX foundDuplicateQuestions = {
// "glassPart1": [1],
// "glassPart2": [7, 10]
// };
const thisPartsDupes = this.foundDuplicateQuestions["glass" + answer.glassIndex];
const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex];
const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : [];
const glassPartAnswered = this.partsQuestionsData[answer.glassIndex];
@ -404,75 +414,6 @@ export default {
}
},
LoadInitialData() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.partQuestionAnswers;
this.partsQuestionsData = this.pageData.partsOrQuestions.filter(x => x.partQuestions).map((glass, i) => {
glass.key = glass.glassLocation + "-" + glass.glassName;
// NOTE: property "questions" can differ between layouts
glass.questions = glass.partQuestions;
this.selectedAnswers[glass.key] = [];
if (!alreadyAnsweredQuestions) {
glass.answerData = null;
}
alreadyAnsweredQuestions?.forEach((savedPart) => {
if (!savedPart.glassLocation || !savedPart.glassName || !savedPart.answeredQuestions || !savedPart.result) {
return;
}
if (glass.glassLocation === savedPart.glassLocation && glass.glassName === savedPart.glassName) {
let answerString = "";
// matches; loop through answeredQuestions for matches
savedPart.answeredQuestions.forEach((aq) => {
if (!aq.questionNum || !aq.selectedAnswerText) {
return;
}
// determine which answer was previously chosen
const theAns = glass.questions[aq.questionNum-1].answers.find((a) => {
return a.answerText.toUpperCase() === aq.selectedAnswerText.toUpperCase();
});
if (theAns.nextQuestionSequence) {
answerString = `${aq.questionNum}|nextQuestion|${theAns.nextQuestionSequence}|${theAns.answerText}`
} else {
answerString = `${aq.questionNum}|answer|${theAns.answerResult}|${theAns.answerText}`
}
// mark this question as answered (question-chain will read this)
glass.questions[aq.questionNum-1].answerSelected = answerString;
// mark this question as duplicate if it is (question-chain will read this)
if (aq.suppressQuestion) {
glass.questions[aq.questionNum-1].suppressQuestion = true;
}
});
// advance the currentGlassIndex
this.currentGlassIndex = i;
// add answerData to current glass
glass.answerData = {
answerResult: savedPart.result,
answeredQuestions: savedPart.answeredQuestions
}
}
});
// Set up watch for each set of glass questions, which gets updated when all questions for a glass have been answered
this.$watch("selectedAnswers." + glass.key, (newValue) => {
if (newValue) {
this.handleAnswerUpdates(glass.key, newValue);
}
}, {deep: true})
return glass;
});
},
},
components: {
funnelHeader,

View file

@ -0,0 +1,57 @@
import { shallowMount } from "@vue/test-utils";
import CashOrInsuranceQuestion from "./cash-or-insurance-question";
describe("cash-or-insurance-question.vue", () => {
it("Should emit a false boolean value when selectedValues is 'CashAnswer' (update:modelValue)", async () => {
//Arrange
const wrapper = shallowMount(CashOrInsuranceQuestion, {
propsData: mockProps,
mixins: [mockMixin]
});
//Act
wrapper.vm.selectedValues = "CashAnswer";
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([false]);
expect(typeof wrapper.emitted()["update:modelValue"][0][0]).toBe("boolean");
});
it("Should return 'CashAnswer' from selectedValues when modelValue is set to false", async () => {
//Arrange
const wrapper = shallowMount(CashOrInsuranceQuestion, {
propsData: mockProps,
mixins: [mockMixin]
});
//Act
wrapper.setProps({modelValue : false});
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.selectedValues).toBe("CashAnswer");
});
});
///////////////
// Constants //
///////////////
const mockMixin = {
methods: {
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
return mockCmsContent[cmsFieldName];
})
}
}
const mockProps = {
modelValue: true,
}
const mockCmsContent = {
'Text': "Sample text here.",
}

View file

@ -14,6 +14,9 @@
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
const cashAnswer = "CashAnswer";
const insuranceAnswer = "InsuranceAnswer";
export default ({
name: "cashOrInsuranceQuestion",
props: {
@ -23,17 +26,18 @@ export default ({
},
computed: {
answersFromCms(){
//console.log(JSON.parse(JSON.stringify(this.getCmsContent(this.cmsWidgetName, 'Answers'))));
return this.getCmsContent(this.cmsWidgetName, 'Answers');
},
selectedValues: {
get: function() {
// Convert to CMS answer name from bool
var cmsAnswerValue = this.modelValue ? "InsuranceAnswer" : "CashAnswer";
var cmsAnswerValue = this.modelValue ? insuranceAnswer : cashAnswer;
return cmsAnswerValue;
},
set: function(newValue) {
// Convert back to bool for parent component
this.$emit("update:modelValue", newValue === "InsuranceAnswer");
this.$emit("update:modelValue", newValue === insuranceAnswer);
}
},
},

View file

@ -133,19 +133,43 @@ export default {
// Call APIs
const cmsContent = await fetchCmsContentForPage(to.query.fmgPage);
// TODOS - modify as needed, just a rough sketch to place initializations
// get supporting lineitems
// get wiper and rain defense lineitems
// Settle promises and get results
// get price of supporting, rain defense & wipers, and parts
// Settle pricing promise and get results
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(cmsContent);
vm.isInsurance = vm.getDefaultIsInsuranceValue();
});
},
data(){
return {
isInsurance: false,
cashOrInsuranceThreshhold: 600,
pricingRequestResult: null,
isInsurance: null,
}
},
methods: {
arePagePrerequisitesValid() {
return store.getters.order.damage.isRepair || (store.getters.order.lineItems?.glassParts != null && store.getters.order.lineItems.glassParts.length > 0);
},
getDefaultIsInsuranceValue() {
var defaultIsInsuranceValue = this.$store.getters.order.payment.isInsurance;
if(defaultIsInsuranceValue != null) {
return defaultIsInsuranceValue;
} else {
return this.economyPackagePrice > this.cashOrInsuranceThreshhold;
}
}
},
computed: {
@ -155,6 +179,10 @@ export default {
answersFromCms() {
return ["Pay on my own", "Pay with insurance"];
},
economyPackagePrice() {
//TODO build out the pricing logic CSR-504
return 0;
},
selectedChipCountValues: {
get: function() {
return this.modelValue;

View file

@ -64,6 +64,68 @@ export default {
currentPageComesAfterPage(currentPage = this.$route.query.fmgPage, fmgPage) {
return this.comparePageIndices(currentPage, fmgPage) > 0;
},
setupInitialData(glass, i, alreadyAnsweredQuestions, vm) {
glass.key = glass.glassLocation + "-" + glass.glassName;
const self = vm ?? this;
// clear answerData if no questions are already answered
if (!alreadyAnsweredQuestions) { glass.answerData = null }
alreadyAnsweredQuestions?.forEach((answeredGlass) => {
// if answeredGlass lacks any of these properties then exit
if (!answeredGlass.glassLocation ||
!answeredGlass.glassName ||
!answeredGlass.answeredQuestions ||
!answeredGlass.result && !answeredGlass.partNum) { return }
// test if glass parts match
if (glass.glassLocation === answeredGlass.glassLocation && glass.glassName === answeredGlass.glassName) {
let answerString = "";
// loop through answeredQuestions for matches
answeredGlass.answeredQuestions.forEach((aq) => {
if (!aq.questionNum || !aq.selectedAnswerText) { return }
// determine which answer was previously chosen
const chosenAns = glass.questions[aq.questionNum-1].answers.find((a) => {
return a.answerText.toUpperCase() === aq.selectedAnswerText.toUpperCase();
});
// set the answerString to use for answerSelected
if (chosenAns.nextQuestionSequence) {
answerString = `${aq.questionNum}|nextQuestion|${chosenAns.nextQuestionSequence}|${chosenAns.answerText}`
} else {
answerString = `${aq.questionNum}|answer|${chosenAns.answerResult}|${chosenAns.answerText}`
}
// mark this question as answered (question-chain will read this)
glass.questions[aq.questionNum-1].answerSelected = answerString;
// mark this question as suppressed if needed (question-chain uses this)
if (aq.suppressQuestion) { glass.questions[aq.questionNum-1].suppressQuestion = true }
});
// advance the currentGlassIndex
self.currentGlassIndex = i;
const answerResult = (answeredGlass.partNum) ? answeredGlass.partNum : answeredGlass.result;
// the above logic for answerResult covers all 3 ___-questions page scenarios
// add answerData to current glass
glass.answerData = {
answerResult: answerResult,
answeredQuestions: answeredGlass.answeredQuestions
}
}
});
// Set up watch for each set of glass questions
// (updated when all questions for a glass have been answered in question-chain)
self.$watch("selectedAnswers." + glass.key, (newValue) => {
if (newValue) {
self.handleAnswerUpdates(newValue);
}
}, {deep: true})
return glass;
},
// Can't use `this` because navigateForward is also called from vin-pages-mixin
async navigateForward(partsOrQuestions, vm) {
const self = vm ?? this;

View file

@ -155,6 +155,126 @@ describe("vehicle-questions-mixin", () => {
});
});
describe("hasChildPartQuestions", () => {
test("has no child part questions => return false", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasChildPartQuestions = wrapper.vm.hasChildPartQuestions([
{
parts: [
{
childPartQuestions: []
}
]
}
])
// Assert
expect(hasChildPartQuestions).toBe(false);
});
test("has undefined child part questions => return false", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasChildPartQuestions = wrapper.vm.hasChildPartQuestions([])
// Assert
expect(hasChildPartQuestions).toBe(false);
});
test("has child part questions => return true", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasChildPartQuestions = wrapper.vm.hasChildPartQuestions([
{
parts: [
{
childPartQuestions: [
{
"questionSequence": 1,
"questionText": "Does the rubber seal around your windshield have a chrome strip running through it?",
"answers": [
{
"answerResult": "WKT D1106 C",
"answerText": "Yes",
"nextQuestionSequence": null
},
{
"answerResult": "WKT D1106 B",
"answerText": "No",
"nextQuestionSequence": null
}
]
}
]
}
]
}
])
// Assert
expect(hasChildPartQuestions).toBe(true);
});
});
describe("hasCapabilityQuestions", () => {
test("has no capability questions => return false", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasCapabilityQuestions = wrapper.vm.hasCapabilityQuestions([
{
parts: [
{
requiresCapabilityQuestions: false
}
]
}
])
// Assert
expect(hasCapabilityQuestions).toBe(false);
});
test("has undefined capability questions => return false", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasCapabilityQuestions = wrapper.vm.hasCapabilityQuestions([])
// Assert
expect(hasCapabilityQuestions).toBe(false);
});
test("has capability questions => return true", () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
const hasCapabilityQuestions = wrapper.vm.hasCapabilityQuestions([
{
parts: [
{
requiresCapabilityQuestions: true
}
]
}
])
// Assert
expect(hasCapabilityQuestions).toBe(true);
});
});
describe("currentPageComesBeforePage", () => {
const testCases = [[fmgPageValues.PART_QUESTIONS, fmgPageValues.VEHICLE_PARTS, true],
[fmgPageValues.VEHICLE_PARTS, fmgPageValues.VEHICLE_PARTS, false],
@ -195,6 +315,94 @@ describe("vehicle-questions-mixin", () => {
})
});
describe("setupInitialData", () => {
describe("should always", () => {
test("return glass with new key attribute", async () => {
// Arrange
const { wrapper } = setupMocks({});
const glass = {
"glassName": "Single",
"glassLocation": "Windshield",
};
const i = 0;
// Act
const returnedGlass = await wrapper.vm.setupInitialData(glass, i);
// Assert
expect(returnedGlass).toMatchObject({"key": "Windshield-Single"});
});
});
describe("if no alreadyAnsweredQuestions", () => {
test("should return glass with answerData of null", async () => {
// Arrange
const glass = {
"glassName": "Single",
"glassLocation": "Windshield"
};
const i = 0;
const { wrapper } = setupMocks({});
// Act
const returnedGlass = await wrapper.vm.setupInitialData(glass, i);
// Assert
expect(returnedGlass).toMatchObject({"answerData": null});
});
});
describe("if alreadyAnsweredQuestions", () => {
test("should return glass with answerResult within answerData", async () => {
// Arrange
const glass = {
"glassName": "Single",
"glassLocation": "Windshield",
"questions": [
{
"questionSequence": 1,
"questionText": "Does the rubber seal around your windshield have a chrome strip running through it?",
"answers": [
{
"answerResult": "WKT D1106 C",
"answerText": "Yes",
"nextQuestionSequence": null
},
{
"answerResult": "WKT D1106 B",
"answerText": "No",
"nextQuestionSequence": null
}
]
}
],
};
const i = 0;
const alreadyAnsweredQuestions = [
{
"glassLocation": "Windshield",
"glassName": "Single",
"partNum": "WKT D1106 C",
"answeredQuestions": [
{
"questionText": "Does the rubber seal around your windshield have a chrome strip running through it?",
"selectedAnswerText": "Yes",
"questionNum": 1
}
]
}
];
const { wrapper } = setupMocks({});
// Act
const returnedGlass = await wrapper.vm.setupInitialData(glass, i, alreadyAnsweredQuestions);
// Assert
expect(returnedGlass.answerData).toMatchObject({"answerResult": "WKT D1106 C"});
});
});
});
describe("navigateForward", () => {
describe("should go to parts-questions", () => {
test("single glass location has part question => go to parts-questions", async () => {
@ -1160,6 +1368,18 @@ describe("vehicle-questions-mixin", () => {
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_NO_QUESTIONS, {"query": {"fmgPage": fmgPageValues.QUOTE}})
})
test("current page is quote and there are capability questions => go to capability questions", () => {
// Arrange
const { wrapper } = setupMocks({ fmgPage: fmgPageValues.QUOTE });
wrapper.vm.hasCapabilityQuestions = jest.fn().mockReturnValue(true);
// Act
wrapper.vm.backButtonAction();
// Assert
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS, {"query": {"fmgPage": fmgPageValues.QUOTE}})
})
test("current page is quote and there are part questions and molding questions => go to molding questions", () => {
// Arrange
const { wrapper } = setupMocks({ fmgPage: fmgPageValues.QUOTE });
@ -1209,7 +1429,15 @@ function setupMocks({ fmgPage = fmgPageValues.VIN_LOOKUP }) {
const baseMixin = setupMocksForJsFiles({
actionList: [{
actionName: storeActions.GET_CAPABILITY_QUESTIONS,
data: [],
data: [
{
answers: [
{
answerResult1: "testing"
}
]
}
],
}]
});

View file

@ -23,6 +23,7 @@ import { applicationConfig } from "../constants/application-config";
// Components
import quote from "@/layouts/quote/quote.vue";
import datePicker from "@/common-components/date-picker/date-picker.vue";
const routes = [
{
@ -30,6 +31,11 @@ const routes = [
name: "quote",
component: quote,
},
{
path: "/date-picker", // This is a temporary route for testing.
name: "date-picker",
component: datePicker,
},
{
path: "/",
name: "root",

View file

@ -538,7 +538,7 @@ export const actions = {
getRouteInfo(context, { pageName }) {
return globalMethods.callHttpClient({
method: endpoints.GetRouteInfo.method,
endpoint: endpoints.GetRouteInfo.url,
endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION),
payload: {
pageName: pageName,
},
@ -547,13 +547,13 @@ export const actions = {
getHomepageName(context) {
return globalMethods.callHttpClient({
method: endpoints.GetHomepageInfo.method,
endpoint: endpoints.GetHomepageInfo.url,
endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION),
});
},
getPageData(context, { pageName }) {
return globalMethods.callHttpClient({
method: endpoints.GetPageData.method,
endpoint: `${endpoints.GetPageData.url}/${pageName}`,
endpoint: endpoints.GetPageData.url(applicationConfig.APPLICATION_ABBREVIATION, pageName),
payload: {},
});
},

View file

@ -194,7 +194,7 @@ describe("list-button-horizontal.vue", () => {
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean, buttonId: undefined, checkValue: undefined}]);
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean, buttonId: undefined, checkValue: false}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {

View file

@ -85,7 +85,7 @@ export default {
: this.selectedValues[0] == this.value;
}
else {
this.checkValue = this.selectedValues;
this.checkValue = this.selectedValues === this.value;
}
},
methods: {