Merge pull request #12 from sundowndev/release/v2
Version 2 Remove useless getters in questions store Create a dedicated page and component for score screen Create Quiz component for home page Fix some type declarations Move CSS style to the global scope Testing Score screen component Testing Score screen view Testing Quiz component Testing Home viewrefactor/jest-config
commit
a17622aa1f
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Hetic VS. EEMI</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but this website doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow:
|
|
@ -24,4 +24,19 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB |
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div id="quizz_input">
|
||||
<h2 id="question_text">{{ currentQuestion.text }}</h2>
|
||||
<p>
|
||||
Plus Éemien ou Héticien ?
|
||||
<span class="progress">({{ index + 1 }}/{{ questions.length }})</span>
|
||||
</p>
|
||||
|
||||
<span>
|
||||
<button v-for="(choice) in schools" :key="choice.id" class="choice-btn" @click="answer(choice.id)">{{ choice.name }}</button>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { mapState, mapGetters, mapMutations } from 'vuex';
|
||||
import router from '../router';
|
||||
import IQuestion from '../models/question';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'Quiz',
|
||||
computed: {
|
||||
...mapState('questions', [
|
||||
'questions',
|
||||
'index',
|
||||
'score',
|
||||
]),
|
||||
...mapGetters('questions', [
|
||||
'currentQuestion',
|
||||
'checkAnswer',
|
||||
'isLastQuestion',
|
||||
]),
|
||||
...mapState('schools', ['schools']),
|
||||
},
|
||||
methods: {
|
||||
answer(answer: number): void {
|
||||
const index: number = this.index;
|
||||
const questions: IQuestion[] = this.questions;
|
||||
|
||||
if (this.checkAnswer({ answer })) {
|
||||
this.$store.dispatch('questions/increaseScore');
|
||||
}
|
||||
|
||||
if (!this.isLastQuestion) {
|
||||
this.$store.dispatch('questions/increaseIndex');
|
||||
} else {
|
||||
router.push({ name: 'scoreScreen' });
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,18 +1,23 @@
|
|||
<template>
|
||||
<div id="score_screen">
|
||||
<h2>Score: {{ score }}/{{ questions.length }}</h2>
|
||||
<h2>Score: {{ score }}/{{ count }}</h2>
|
||||
<h3>{{ text() }}</h3>
|
||||
<button class="replay-btn" @click="reset">Recommencer</button>
|
||||
<button class="replay-btn" @click="resetGame">Recommencer</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { mapState, mapGetters, mapMutations } from 'vuex';
|
||||
import router from '../router';
|
||||
|
||||
interface IMessage {
|
||||
min: number;
|
||||
msg: string;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'ScoreScreen',
|
||||
data() {
|
||||
data(): { messages: IMessage[] } {
|
||||
return {
|
||||
messages: [
|
||||
{ min: 0, msg: 'T\'as pas lu les questions avoues.' },
|
||||
|
@ -23,37 +28,22 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
props: {
|
||||
reset: Function,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('questions', ['questions', 'score']),
|
||||
score: Number,
|
||||
count: Number,
|
||||
},
|
||||
methods: {
|
||||
text() {
|
||||
text(): string {
|
||||
const text = this.messages.filter((msg) => this.score >= msg.min);
|
||||
|
||||
return text[0] !== undefined ? text[0].msg : '';
|
||||
},
|
||||
resetGame(): void {
|
||||
this.$store.dispatch('questions/resetState');
|
||||
router.push({ name: 'home' });
|
||||
},
|
||||
},
|
||||
created() {
|
||||
created(): void {
|
||||
this.messages.sort((a, b) => b.min - a.min);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Vue from 'vue';
|
||||
import Router from 'vue-router';
|
||||
import Home from './views/Home.vue';
|
||||
import ScoreScreen from './views/ScoreScreen.vue';
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
|
@ -13,5 +14,14 @@ export default new Router({
|
|||
name: 'home',
|
||||
component: Home,
|
||||
},
|
||||
{
|
||||
path: '/end',
|
||||
name: 'scoreScreen',
|
||||
component: ScoreScreen,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
redirect: { name: 'home' },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -21,15 +21,6 @@ IStoreQuestions,
|
|||
questions: [],
|
||||
},
|
||||
getters: {
|
||||
index(state): number {
|
||||
return state.index;
|
||||
},
|
||||
score(state): number {
|
||||
return state.score;
|
||||
},
|
||||
questions(state): IQuestion[] {
|
||||
return state.questions;
|
||||
},
|
||||
currentQuestion(state): IQuestion | {} {
|
||||
return state.questions.length ? state.questions[state.index] : {};
|
||||
},
|
||||
|
|
|
@ -13,11 +13,7 @@ const schools: Module<IStoreSchools, any> = {
|
|||
state: {
|
||||
schools: [],
|
||||
},
|
||||
getters: {
|
||||
schools(state): ISchool[] {
|
||||
return state.schools;
|
||||
},
|
||||
},
|
||||
getters: {},
|
||||
mutations: {
|
||||
setSchools(state, payload): ISchool[] {
|
||||
return (state.schools = payload);
|
||||
|
|
|
@ -1,68 +1,17 @@
|
|||
<template>
|
||||
<div class="home">
|
||||
<div id="quizz_input" v-show="!finished">
|
||||
<h2 id="question_text">{{ currentQuestion.text }}</h2>
|
||||
<p>
|
||||
Plus Éemien ou Héticien ?
|
||||
<span class="progress">({{ index + 1 }}/{{ questions.length }})</span>
|
||||
</p>
|
||||
|
||||
<span v-for="(choice) in schools" :key="choice.id">
|
||||
<button class="choice-btn" @click="answer(choice.id)">{{ choice.name }}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<ScoreScreen v-show="finished" :reset="resetGame" />
|
||||
<Quiz />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import IQuestion from '../models/question';
|
||||
import { mapState, mapGetters, mapMutations } from 'vuex';
|
||||
import ScoreScreen from '../components/ScoreScreen.vue';
|
||||
import Quiz from '../components/Quiz.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'home',
|
||||
data() {
|
||||
return {
|
||||
finished: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('schools', ['schools']),
|
||||
...mapGetters('questions', [
|
||||
'questions',
|
||||
'index',
|
||||
'score',
|
||||
'currentQuestion',
|
||||
'checkAnswer',
|
||||
'isLastQuestion',
|
||||
]),
|
||||
},
|
||||
methods: {
|
||||
answer(answer: number): void {
|
||||
const index: number = this.index;
|
||||
const questions: IQuestion[] = this.questions;
|
||||
|
||||
if (this.checkAnswer({ answer })) {
|
||||
this.$store.dispatch('questions/increaseScore');
|
||||
}
|
||||
|
||||
if (!this.isLastQuestion) {
|
||||
this.$store.dispatch('questions/increaseIndex');
|
||||
} else {
|
||||
this.finished = true;
|
||||
}
|
||||
},
|
||||
resetGame(): void {
|
||||
this.finished = false;
|
||||
this.$store.dispatch('questions/resetState');
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ScoreScreen,
|
||||
},
|
||||
components: { Quiz },
|
||||
async created() {
|
||||
await this.$store.dispatch('questions/fetchQuestions');
|
||||
await this.$store.dispatch('schools/fetchSchools');
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<ScoreScreen :score="score" :count="questions.length" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import IQuestion from '../models/question';
|
||||
import { mapState, mapGetters, mapMutations } from 'vuex';
|
||||
import ScoreScreen from '../components/ScoreScreen.vue';
|
||||
import router from '../router';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'home',
|
||||
components: {
|
||||
ScoreScreen,
|
||||
},
|
||||
computed: {
|
||||
...mapState('questions', ['questions', 'index', 'score']),
|
||||
},
|
||||
created(): void {
|
||||
if (this.index === 0) {
|
||||
router.push({ name: 'home' });
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,90 +1,132 @@
|
|||
describe("Home page", () => {
|
||||
it("should have content displayed", () => {
|
||||
cy.server({ status: 200 });
|
||||
cy.route("/schools", {
|
||||
describe('Home page', () => {
|
||||
describe('content', () => {
|
||||
it('should display quizz component', () => {
|
||||
cy.get('#quizz_input').should('be.visible');
|
||||
});
|
||||
|
||||
it('should display title', () => {
|
||||
cy.get('h1#title').should('be.visible');
|
||||
cy.contains('h1#title', 'HETIC vs EEMI');
|
||||
});
|
||||
|
||||
it('should display progress', () => {
|
||||
cy.get('span.progress').should('be.visible');
|
||||
cy.contains('span.progress', '1/2');
|
||||
});
|
||||
|
||||
it('should display choice text', () => {
|
||||
cy.get('p').should('be.visible');
|
||||
cy.contains('p', 'Plus Éemien ou Héticien ?');
|
||||
});
|
||||
|
||||
it('should display question', () => {
|
||||
cy.server();
|
||||
cy.route('/questions', {
|
||||
questions: [{ text: 'test_cypress', answer: 2 }],
|
||||
});
|
||||
|
||||
cy.get('h2#question_text').should('be.visible');
|
||||
cy.contains('h2#question_text', 'test_cypress');
|
||||
});
|
||||
|
||||
it('should display schools', () => {
|
||||
cy.server();
|
||||
cy.route('/schools', {
|
||||
schools: [
|
||||
{ id: 1, name: 'school1' },
|
||||
{ id: 2, name: 'school2' },
|
||||
{ id: 3, name: 'school3' },
|
||||
],
|
||||
});
|
||||
|
||||
cy.get('.choice-btn').should('be.visible');
|
||||
cy.get('.choice-btn').should('have.length', 2);
|
||||
cy.get('.choice-btn')
|
||||
.first()
|
||||
.should('have.text', 'school1');
|
||||
});
|
||||
});
|
||||
|
||||
it('should finish game with score 0', () => {
|
||||
cy.server();
|
||||
cy.route('/schools', {
|
||||
schools: [
|
||||
{ id: 1, name: "school1" },
|
||||
{ id: 2, name: "school2" },
|
||||
{ id: 3, name: "school3" }
|
||||
]
|
||||
{ id: 1, name: 'school1' },
|
||||
{ id: 2, name: 'school2' },
|
||||
],
|
||||
});
|
||||
cy.route("/questions", {
|
||||
questions: [{ text: "test_cypress", answer: 2 }]
|
||||
cy.route('/questions', {
|
||||
questions: [
|
||||
{ text: 'test_cypress', answer: 2 },
|
||||
{ text: 'test_cypress', answer: 2 },
|
||||
],
|
||||
});
|
||||
|
||||
cy.visit("/");
|
||||
cy.visit('/');
|
||||
|
||||
// Elements are visible
|
||||
cy.get("h1#title").should("be.visible");
|
||||
cy.get("h2#question_text").should("be.visible");
|
||||
cy.get("span.progress").should("be.visible");
|
||||
cy.get("p").should("be.visible");
|
||||
cy.get(".choice-btn").should("be.visible");
|
||||
cy.get("#quizz_input").should("be.visible");
|
||||
cy.get("#score_screen").should("not.be.visible");
|
||||
cy.contains('#question_text', 'test_cypress');
|
||||
|
||||
// Elements contain right content
|
||||
cy.contains("#title", "HETIC vs EEMI");
|
||||
cy.get("h2#question_text").should("not.be.empty");
|
||||
cy.contains("p", "Plus Éemien ou Héticien ?");
|
||||
cy.get(".choice-btn").should("have.length", 3);
|
||||
cy.get(".choice-btn")
|
||||
.first()
|
||||
.should("have.text", "school1");
|
||||
});
|
||||
|
||||
it("should finish game with score 0", () => {
|
||||
cy.server({ status: 200 });
|
||||
cy.route("/schools", {
|
||||
schools: [{ id: 1, name: "school1" }, { id: 2, name: "school2" }]
|
||||
});
|
||||
cy.route("/questions", {
|
||||
questions: [{ text: "test_cypress", answer: 2 }]
|
||||
});
|
||||
|
||||
cy.visit("/");
|
||||
|
||||
cy.contains("#question_text", "test_cypress");
|
||||
|
||||
cy.get(".choice-btn")
|
||||
cy.get('.choice-btn')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.contains("Score: 0/1");
|
||||
cy.get('.choice-btn')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.pathname).to.eq('/end');
|
||||
});
|
||||
|
||||
cy.contains('Score: 0/2');
|
||||
cy.contains("T'as pas lu les questions avoues.");
|
||||
cy.contains("Recommencer");
|
||||
cy.contains('Recommencer');
|
||||
|
||||
cy.get("#quizz_input").should("not.be.visible"); // Quizz is hidden
|
||||
cy.get("#score_screen").should("be.visible"); // Score screen is displayed
|
||||
cy.get('#quizz_input').should('not.be.visible'); // Quizz is hidden
|
||||
cy.get('#score_screen').should('be.visible'); // Score screen is displayed
|
||||
});
|
||||
|
||||
it("should finish game with score 1 and retry", () => {
|
||||
cy.server({ status: 200 });
|
||||
cy.route("/schools", {
|
||||
schools: [{ id: 1, name: "school1" }, { id: 2, name: "school2" }]
|
||||
it('should finish game with score 1 and retry', () => {
|
||||
cy.server();
|
||||
cy.route('/schools', {
|
||||
schools: [
|
||||
{ id: 1, name: 'school1' },
|
||||
{ id: 2, name: 'school2' },
|
||||
],
|
||||
});
|
||||
cy.route("/questions", {
|
||||
questions: [{ text: "test_cypress", answer: 1 }]
|
||||
cy.route('/questions', {
|
||||
questions: [
|
||||
{ text: 'test_cypress', answer: 1 },
|
||||
{ text: 'test_cypress', answer: 1 },
|
||||
],
|
||||
});
|
||||
|
||||
cy.visit("/");
|
||||
cy.visit('/');
|
||||
|
||||
cy.contains("#question_text", "test_cypress");
|
||||
cy.contains('#question_text', 'test_cypress');
|
||||
|
||||
cy.get(".choice-btn")
|
||||
cy.get('.choice-btn')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.contains("Score: 1/1");
|
||||
cy.get('.choice-btn')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.pathname).to.eq('/end');
|
||||
});
|
||||
|
||||
cy.contains('Score: 2/2');
|
||||
cy.contains("Bon bah c'est pas tip top tout ça.");
|
||||
cy.contains("Recommencer");
|
||||
cy.contains('Recommencer');
|
||||
|
||||
cy.get("#quizz_input").should("not.be.visible"); // Quizz is hidden
|
||||
cy.get("#score_screen").should("be.visible"); // Score screen is displayed
|
||||
cy.get('#quizz_input').should('not.be.visible'); // Quizz is hidden
|
||||
cy.get('#score_screen').should('be.visible'); // Score screen is displayed
|
||||
|
||||
cy.get(".replay-btn").click();
|
||||
cy.get('.replay-btn').click();
|
||||
|
||||
cy.get("#quizz_input").should("be.visible"); // Quizz is visible
|
||||
cy.get("#score_screen").should("not.be.visible"); // Score screen is hidden
|
||||
cy.get('#quizz_input').should('be.visible'); // Quizz is visible
|
||||
cy.get('#score_screen').should('not.be.visible'); // Score screen is hidden
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import Quiz from '../../../src/components/Quiz.vue';
|
||||
import router from '@/router';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
localVue.use(Vuex);
|
||||
|
||||
const checkAnswerMock = jest.fn();
|
||||
|
||||
let isLastQuestionMock = false;
|
||||
let $store: any;
|
||||
let wrapper: any;
|
||||
|
||||
describe('Component - Quiz', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
|
||||
$store = new Vuex.Store({
|
||||
modules: {
|
||||
questions: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
index: 0,
|
||||
score: 0,
|
||||
questions: [{ answer: 1, text: 'test' }],
|
||||
},
|
||||
getters: {
|
||||
currentQuestion: () => ({
|
||||
text: 'currentQuestion',
|
||||
}),
|
||||
checkAnswer: () => checkAnswerMock,
|
||||
isLastQuestion: () => isLastQuestionMock,
|
||||
},
|
||||
},
|
||||
schools: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
schools: [{ id: 1, name: 'school1' }],
|
||||
},
|
||||
getters: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
wrapper = shallowMount(Quiz, {
|
||||
mocks: { $store },
|
||||
});
|
||||
});
|
||||
|
||||
it('should display question', () => {
|
||||
expect(wrapper.find('#question_text').text()).toBe('currentQuestion');
|
||||
});
|
||||
|
||||
it('should display question', () => {
|
||||
expect(wrapper.find('span.progress').text()).toBe('(1/1)');
|
||||
});
|
||||
|
||||
it('should only increase index', () => {
|
||||
const dispatchMock = spyOn($store, 'dispatch');
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
checkAnswerMock.mockImplementation(() => false);
|
||||
isLastQuestionMock = false;
|
||||
|
||||
wrapper
|
||||
.findAll('.choice-btn')
|
||||
.at(0)
|
||||
.trigger('click');
|
||||
|
||||
expect(checkAnswerMock).toBeCalledTimes(1);
|
||||
expect(checkAnswerMock).toBeCalledWith({ answer: 1 });
|
||||
|
||||
expect(dispatchMock).toBeCalledTimes(1);
|
||||
expect(dispatchMock).toBeCalledWith('questions/increaseIndex');
|
||||
|
||||
expect(routerMock).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should increase score and index', () => {
|
||||
const dispatchMock = spyOn($store, 'dispatch');
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
checkAnswerMock.mockImplementation(() => true);
|
||||
isLastQuestionMock = false;
|
||||
|
||||
wrapper
|
||||
.findAll('.choice-btn')
|
||||
.at(0)
|
||||
.trigger('click');
|
||||
|
||||
expect(checkAnswerMock).toBeCalledTimes(1);
|
||||
expect(checkAnswerMock).toBeCalledWith({ answer: 1 });
|
||||
|
||||
expect(dispatchMock).toBeCalledTimes(2);
|
||||
expect(dispatchMock).nthCalledWith(1, 'questions/increaseScore');
|
||||
expect(dispatchMock).nthCalledWith(2, 'questions/increaseIndex');
|
||||
|
||||
expect(routerMock).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should to score screen', () => {
|
||||
const dispatchMock = spyOn($store, 'dispatch');
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
checkAnswerMock.mockImplementation(() => false);
|
||||
isLastQuestionMock = true;
|
||||
|
||||
wrapper
|
||||
.findAll('.choice-btn')
|
||||
.at(0)
|
||||
.trigger('click');
|
||||
|
||||
expect(checkAnswerMock).toBeCalledTimes(1);
|
||||
expect(checkAnswerMock).toBeCalledWith({ answer: 1 });
|
||||
|
||||
expect(dispatchMock).toBeCalledTimes(0);
|
||||
|
||||
expect(routerMock).toBeCalledTimes(1);
|
||||
expect(routerMock).toBeCalledWith({ name: 'scoreScreen' });
|
||||
});
|
||||
});
|
|
@ -0,0 +1,55 @@
|
|||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import ScoreScreen from '../../../src/components/ScoreScreen.vue';
|
||||
import router from '@/router';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
localVue.use(Vuex);
|
||||
|
||||
let $store: any;
|
||||
|
||||
let wrapper: any;
|
||||
|
||||
describe('Component - ScoreScreen', () => {
|
||||
beforeEach(() => {
|
||||
$store = new Vuex.Store({
|
||||
modules: {
|
||||
questions: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
index: 0,
|
||||
score: 0,
|
||||
questions: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
wrapper = shallowMount(ScoreScreen, {
|
||||
mocks: { $store },
|
||||
propsData: {
|
||||
score: 2,
|
||||
count: 5,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should display message based on score', () => {
|
||||
expect(wrapper.find('h3').text()).toBe(
|
||||
'Bon bah c\'est pas tip top tout ça.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should call reset state function', () => {
|
||||
const dispatchMock = spyOn($store, 'dispatch');
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
wrapper.find('button.replay-btn').trigger('click');
|
||||
|
||||
expect(dispatchMock).toBeCalledTimes(1);
|
||||
expect(dispatchMock).toBeCalledWith('questions/resetState');
|
||||
|
||||
expect(routerMock).toBeCalledTimes(1);
|
||||
expect(routerMock).toBeCalledWith({ name: 'home' });
|
||||
});
|
||||
});
|
|
@ -21,36 +21,6 @@ describe('Store - Questions', () => {
|
|||
});
|
||||
|
||||
describe('Getters', () => {
|
||||
describe('#index', () => {
|
||||
it('should get index', () => {
|
||||
state.index = 5;
|
||||
|
||||
const index = getters.index(state, null, null, null);
|
||||
|
||||
expect(index).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#score', () => {
|
||||
it('should get score', () => {
|
||||
state.score = 5;
|
||||
|
||||
const score = getters.score(state, null, null, null);
|
||||
|
||||
expect(score).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#questions', () => {
|
||||
it('should get questions', () => {
|
||||
state.questions = [{ text: 'test', answer: 1 }];
|
||||
|
||||
const data = getters.questions(state, null, null, null);
|
||||
|
||||
expect(data).toStrictEqual(state.questions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#currentQuestion', () => {
|
||||
it('should get current question', () => {
|
||||
state.index = 1;
|
||||
|
@ -77,7 +47,12 @@ describe('Store - Questions', () => {
|
|||
it('should check answer and get true', () => {
|
||||
state.questions = [{ text: 'test', answer: 1 }];
|
||||
|
||||
const isCorrect = getters.checkAnswer(state, null, null, null)({
|
||||
const isCorrect = getters.checkAnswer(
|
||||
state,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
)({
|
||||
answer: 1,
|
||||
});
|
||||
|
||||
|
@ -87,7 +62,12 @@ describe('Store - Questions', () => {
|
|||
it('should check answer and get false', () => {
|
||||
state.questions = [{ text: 'test', answer: 2 }];
|
||||
|
||||
const isCorrect = getters.checkAnswer(state, null, null, null)({
|
||||
const isCorrect = getters.checkAnswer(
|
||||
state,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
)({
|
||||
answer: 1,
|
||||
});
|
||||
|
||||
|
|
|
@ -16,19 +16,6 @@ describe('Store - Questions', () => {
|
|||
};
|
||||
});
|
||||
|
||||
describe('Getters', () => {
|
||||
describe('#schools', () => {
|
||||
it('should get schools', () => {
|
||||
state.schools = [{ id: '1', name: 'test' }, { id: '2', name: 'test2' }];
|
||||
|
||||
const data = getters.schools(state, null, null, null);
|
||||
|
||||
expect(data).toStrictEqual(state.schools);
|
||||
expect(data.length).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Mutations', () => {
|
||||
describe('#setSchools', () => {
|
||||
it('should set schools state', () => {
|
||||
|
|
|
@ -4,7 +4,7 @@ import Home from '../../../src/views/Home.vue';
|
|||
import axios from 'axios';
|
||||
import config from '@/config';
|
||||
import questions from '@/store/modules/questions';
|
||||
import schools from '@/store/modules/questions';
|
||||
import schools from '@/store/modules/schools';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
|
@ -18,17 +18,13 @@ const $store = new Vuex.Store({
|
|||
});
|
||||
const axiosMock = jest
|
||||
.spyOn(axios, 'get')
|
||||
.mockResolvedValue({ data: { questions: [] } } as any);
|
||||
const wrapper = shallowMount(Home, { mocks: { $store } });
|
||||
.mockResolvedValueOnce({ data: { questions: [] } } as any)
|
||||
.mockResolvedValueOnce({ data: { schools: [] } } as any);
|
||||
|
||||
describe.skip('Views - Home', () => {
|
||||
it('should ', () => {
|
||||
const storeDispatchMock = spyOn($store, 'dispatch');
|
||||
shallowMount(Home, { mocks: { $store } });
|
||||
|
||||
// wrapper.find('.todoList__removeDone').trigger('click');
|
||||
// expect(storeDispatchMock).toBeCalledTimes(2);
|
||||
// expect(storeDispatchMock).toHaveBeenNthCalledWith(1, 'fetchQuestions');
|
||||
// expect(storeDispatchMock).toHaveBeenNthCalledWith(2, 'fetchSchools');
|
||||
describe('Views - Home', () => {
|
||||
it('should fetch questions and shools', () => {
|
||||
expect(axiosMock).toBeCalledTimes(2);
|
||||
expect(axiosMock).toHaveBeenNthCalledWith(1, `${config.apiUrl}/questions`);
|
||||
expect(axiosMock).toHaveBeenNthCalledWith(2, `${config.apiUrl}/schools`);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import ScoreScreen from '../../../src/views/ScoreScreen.vue';
|
||||
import router from '@/router';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
localVue.use(Vuex);
|
||||
|
||||
let wrapper: any;
|
||||
|
||||
const mountIt = (index = 0, score = 0, questions = []) => {
|
||||
wrapper = shallowMount(ScoreScreen, {
|
||||
mocks: {
|
||||
$store: new Vuex.Store({
|
||||
modules: {
|
||||
questions: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
index,
|
||||
score,
|
||||
questions,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
describe('Views - ScoreScreen', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should redirect to home on index 0', () => {
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
mountIt();
|
||||
|
||||
expect(routerMock).toBeCalledTimes(1);
|
||||
expect(routerMock).toBeCalledWith({ name: 'home' });
|
||||
});
|
||||
|
||||
it('should not redirect to home', () => {
|
||||
mountIt(1);
|
||||
|
||||
const routerMock = spyOn(router, 'push');
|
||||
|
||||
expect(routerMock).toBeCalledTimes(0);
|
||||
});
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "HETICvsEEMI",
|
||||
"name": "hetic-vs-eemi",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "HETICvsEEMI",
|
||||
"name": "hetic-vs-eemi",
|
||||
"version": "1.0.0",
|
||||
"description": "Plus Eemien ou Héticien ? Le jeu qui ne fait pas rire les élèves.",
|
||||
"main": "index.js",
|
||||
|
@ -16,8 +16,6 @@
|
|||
"type": "git",
|
||||
"url": "git+https://github.com/sundowndev/HETICvsEEMI.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sundowndev/HETICvsEEMI/issues"
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
"name": "server",
|
||||
"private": false,
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"compression": "^1.7.4",
|
||||
|
@ -10,11 +9,7 @@
|
|||
"express": "^4.17.1",
|
||||
"morgan": "^1.9.1"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue