Skip to content

Commit

Permalink
Implemented unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
LukaBRa committed Feb 8, 2024
1 parent cbf417a commit 6b86897
Show file tree
Hide file tree
Showing 19 changed files with 42,443 additions and 18,945 deletions.
19 changes: 19 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
testEnvironment: "jsdom",
transform: {
"^.+\\.vue$": "@vue/vue3-jest",
"^.+\\js$": "babel-jest",
},
moduleFileExtensions: ["vue", "js"],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
coveragePathIgnorePatterns: ["/node_modules/", "/tests/"],
coverageReporters: ["text", "json-summary"],
// Fix in order for vue-test-utils to work with Jest 29
// https://test-utils.vuejs.org/migration/#test-runners-upgrade-notes
testEnvironmentOptions: {
customExportConditions: ["node", "node-addons"],
},
}
60,710 changes: 41,795 additions & 18,915 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 16 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@
"name": "epam-vue-task-3",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"test:unit": "vitest",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"build-only": "vite build",
"build-storybook": "storybook build",
"dev": "vite",
"format": "prettier --write src/",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
"type-check": "vue-tsc --build --force"
},
"dependencies": {
"axios": "^1.6.7",
"pinia": "^2.1.7",
"vue": "^3.3.11"
},
"devDependencies": {
"@babel/preset-env": "^7.23.9",
"@pinia/testing": "^0.1.3",
"@rushstack/eslint-patch": "^1.3.3",
"@storybook/addon-essentials": "^7.6.10",
"@storybook/addon-interactions": "^7.6.10",
Expand All @@ -34,22 +35,29 @@
"@types/node": "^18.19.3",
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/cli-plugin-unit-jest": "~5.0.0",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/test-utils": "^2.4.3",
"@vue/test-utils": "^2.4.4",
"@vue/tsconfig": "^0.5.0",
"@vue/vue3-jest": "^27.0.0",
"babel-jest": "^27.5.1",
"cypress": "^13.6.4",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
"jest": "^27.5.1",
"jest-environment-jsdom": "^29.7.0",
"jsdom": "^23.0.1",
"npm-run-all2": "^6.1.1",
"prettier": "^3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook": "^7.6.10",
"ts-jest": "^27.1.5",
"typescript": "~5.3.0",
"vite": "^5.0.12",
"vitest": "^1.0.4",
"vue-tsc": "^1.8.25"
}
},
"type": "module"
}
4 changes: 2 additions & 2 deletions src/components/ActionBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const handleSearch = () => {
<template>

<div class="search-bar">
<input data-cy="search-input" @keyup.enter="handleSearch" v-model="inputSearchText" type="text">
<Button data-cy="search-button" @click="handleSearch" title="SEARCH" type="primary" />
<input id="search-input" data-cy="search-input" @keyup.enter="handleSearch" v-model="inputSearchText" type="text">
<Button id="search-button" data-cy="search-button" @click="handleSearch" title="SEARCH" type="primary" />
</div>

</template>
Expand Down
6 changes: 3 additions & 3 deletions src/components/Banner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ const filterStore = useFilterButtonsStore();

<section class="search-section container">

<h1 data-cy="banner-title">FIND YOUR MOVIE</h1>
<h1 id="banner-title" data-cy="banner-title">FIND YOUR MOVIE</h1>

<ActionBar />
<ActionBar id="banner-action-bar"/>

<Filter filterTitle="SEARCH BY" :filter-buttons="filterStore.searchFilterButtons"/>
<Filter id="banner-filter" filterTitle="SEARCH BY" :filter-buttons="filterStore.searchFilterButtons"/>

</section>

Expand Down
2 changes: 1 addition & 1 deletion src/components/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const buttonStyle = {

<template>

<button data-cy="button" :class="buttonStyle">{{ title }}</button>
<button id="button" data-cy="button" :class="buttonStyle">{{ title }}</button>

</template>

Expand Down
4 changes: 2 additions & 2 deletions src/components/Filter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const buttonToggled = (args: ButtonToggleArgs) => {
<template>

<div class="filter-container">
<p data-cy="filter-title">{{ filterTitle }}</p>
<p id="filter-title" data-cy="filter-title">{{ filterTitle }}</p>

<div class="filter-buttons">
<FilterButton data-cy="filter-button" v-for="button in filterButtons"
<FilterButton data-test="filter-button" data-cy="filter-button" v-for="button in filterButtons"
:type="button.type"
:title="button.title"
:active="button.active"
Expand Down
2 changes: 1 addition & 1 deletion src/components/FilterButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const buttonClass = computed(() => ({

<template>

<button data-cy="filter-button" @click="$emit('toggleFilterButton', {type, title})" :class="buttonClass">{{ title }}</button>
<button id="button" data-cy="filter-button" @click="$emit('toggleFilterButton', {type, title})" :class="buttonClass">{{ title }}</button>

</template>

Expand Down
8 changes: 4 additions & 4 deletions src/components/MovieCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ const releaseDate = computed(() => {

<div class="movie-card">

<img data-cy="card-img" @click="$emit('selectMovie', movie.id)" v-lazyload="movie.posterurl" :alt="movie.title">
<img id="card-image" data-cy="card-img" @click="$emit('selectMovie', movie.id)" v-lazyload="movie.posterurl" :alt="movie.title">

<div class="movie-info">

<div class="movie-title">
<h3 data-cy="card-title">{{ movie.title }}</h3>
<p>{{ formatGenres(movie.genres) }}</p>
<h3 id="card-title" data-cy="card-title">{{ movie.title }}</h3>
<p id="card-genres">{{ formatGenres(movie.genres) }}</p>
</div>

<div data-cy="card-release-date" class="movie-release-date">
<div id="card-release-date" data-cy="card-release-date" class="movie-release-date">
{{ releaseDate }}
</div>

Expand Down
14 changes: 7 additions & 7 deletions src/components/MovieDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const movieDuration = computed(() => {

<div class="container movie-header-section">
<WebsiteTitle />
<button data-cy="close-movie-page-btn" @click="$emit('closeMoviePage')" class="search-button"><span class="material-icons search-icon">search</span></button>
<button id="close-movie-page-button" data-cy="close-movie-page-btn" @click="$emit('closeMoviePage')" class="search-button"><span class="material-icons search-icon">search</span></button>
</div>

<section class="container">
Expand All @@ -32,15 +32,15 @@ const movieDuration = computed(() => {

<div class="movie-overview-details">
<div class="movie-title">
<h1 data-cy="movie-title">{{ movie.title }}</h1>
<p data-cy="movie-rating" class="movie-rating">{{ movie.imdbRating }}</p>
<h1 id="movie-title" data-cy="movie-title">{{ movie.title }}</h1>
<p id="movie-rating" data-cy="movie-rating" class="movie-rating">{{ movie.imdbRating }}</p>
</div>
<p class="movie-genres">{{ formatGenres(movie.genres) }}</p>
<p id="movie-genres" class="movie-genres">{{ formatGenres(movie.genres) }}</p>
<div class="movie-duration-release">
<p data-cy="movie-release-date">{{ new Date(movie.releaseDate).getFullYear() }}</p>
<p data-cy="movie-duration">{{ movieDuration }}</p>
<p id="movie-release-date" data-cy="movie-release-date">{{ new Date(movie.releaseDate).getFullYear() }}</p>
<p id="movie-duration" data-cy="movie-duration">{{ movieDuration }}</p>
</div>
<p data-cy="movie-description" class="movie-description">{{ movie.storyline }}</p>
<p id="movie-description" data-cy="movie-description" class="movie-description">{{ movie.storyline }}</p>
</div>
</div>

Expand Down
4 changes: 2 additions & 2 deletions src/components/MovieList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const selectMovie = (id: number) => {
<section class="container-fluid bg-darkgray padding-movie-list">

<div class="container">
<div v-if="moviesStore.moviesCount > 0" class="movie-list">
<div id="movies" v-if="moviesStore.moviesCount > 0" class="movie-list">
<MovieCard data-cy="movie-card" v-for="movie in moviesStore.movies" :key="movie.id" :movie="movie" @selectMovie="selectMovie"/>
</div>
<h1 v-else>No films found</h1>
<h1 id="no-movies" v-else>No films found</h1>
</div>

</section>
Expand Down
42 changes: 42 additions & 0 deletions src/components/tests/unit/ActionBar.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ActionBar from "../../ActionBar.vue";
import { flushPromises, mount } from "@vue/test-utils";
import { test, expect, describe, beforeEach, vi } from "vitest";
import { createPinia, defineStore, setActivePinia } from "pinia";
import { createTestingPinia } from "@pinia/testing";
import useMoviesStore from "@/store/moviesStore";
import useFilterButtonsStore from "@/store/filterButtonsStore";

const wrapper = mount(ActionBar, {
global: {
plugins: [
createTestingPinia({
stubActions: false,
createSpy: vi.fn,
})
]
}
});

test("Component should mount", () => {

expect(wrapper).toBeTruthy();
});

test("Component should search for The Lord of the Rings movies", async () => {

const movieStore = useMoviesStore();
await wrapper.find('#search-input').setValue("The Lord of the Rings");
await wrapper.find('#search-button').trigger("click");

expect(wrapper.find('#search-input').element.value).toBe("The Lord of the Rings");
expect(movieStore.movies).toHaveLength(3);
});

test("Component should search for Pulp Fiction", async () => {

const moviesStore = useMoviesStore();
await wrapper.find("#search-input").setValue("Pulp Fiction");
await wrapper.find("#search-button").trigger("click");

expect(moviesStore.movies).toHaveLength(1);
});
28 changes: 28 additions & 0 deletions src/components/tests/unit/Banner.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { mount } from "@vue/test-utils";
import Banner from "../../Banner.vue";
import { test, expect, vi } from "vitest";
import { createTestingPinia } from "@pinia/testing";

const wrapper = mount(Banner, {
global: {
plugins: [
createTestingPinia({
stubActions: false,
createSpy: vi.fn,
})
]
}
});

test("Component should mount", () => {
expect(wrapper).toBeTruthy();
});

test("Banner should contain title FIND YOUR MOVIE", () => {
expect(wrapper.find('#banner-title').text()).toBe("FIND YOUR MOVIE");
});

test("Component should contain action bar and filter", () => {
expect(wrapper.find("#banner-action-bar").exists()).toBeTruthy();
expect(wrapper.find("#banner-filter").exists()).toBeTruthy();
});
44 changes: 44 additions & 0 deletions src/components/tests/unit/Button.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { mount } from "@vue/test-utils";
import Button from "../../Button.vue";
import { test, expect } from "vitest";


test("renders a button", () => {
const wrapper = mount(Button);

expect(wrapper.get('button').text()).toBe("");
});

test("button should have title SEARCH", () => {
const wrapper = mount(Button, {
props: {
title: "SEARCH",
}
});

expect(wrapper.get("#button").text()).toBe("SEARCH");
});

test("button should have title SORT and class 'button-primary' ", () => {
const wrapper = mount(Button, {
props: {
title: "SORT",
type: "primary"
}
});

expect(wrapper.get("#button").text()).toBe("SORT");
expect(wrapper.get("#button").classes()).toContain("button-primary");
});

test("button should have title SORT and shouldn't have class 'button-primary'", () => {
const wrapper = mount(Button, {
props: {
title: "SORT",
type: "secondary"
}
});

expect(wrapper.get("#button").text()).toBe("SORT");
expect(wrapper.get("#button").classes).not.toContain("button-primary");
});
Loading

0 comments on commit 6b86897

Please sign in to comment.