-
- {{ videoTitle }}
+
+
+
+
+
+ {{ chapterInfoTitle }}
+
-
-
- {{ loadingText }}
-
-
-
-
+
+
+
+
-
+
+
+ {{ nameLabel }}
+
+ {{ chapter.name }}
+
+
+
+
+
+
+ {{ seasonLabel }}
+
+ {{ chapter.season }}
+
+
+
+
+
+
+ {{ durationLabel }}
+
+ {{ chapter.parsed_duration }}
+
+
+
+
+
+
+ {{ releaseDateLabel }}
+
+ {{ chapter.parsed_release_date }}
+
+
+
+
+
+
+
+
+
+
+ {{ summaryLabel }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ loadingText }}
+
+
+
+
+
+
+
+
+
+ {{ unavailableText }}
+
+
+
+ {{ shareText }}
+
+
+
+
+
+
+
+
+
+
-
- {{ unavailableText }}
-
-
+
@@ -148,7 +181,22 @@ export default {
});
}
- return this.$store.dispatch('chapters/getBySlug', { slug: this.$route.params.slug })
+ this.$store.commit('configs/setCurrentTitle', this.$t('VIEWS.SEASONS.DETAIL.CHAPTERS.DETAIL.TITLE', { slug: '' }));
+
+ return Promise.all([
+ this.$store.dispatch('seo-configs/getSeoConfigBySlug', {
+ slug: this.$route.params.slug,
+ }),
+ this.$store.dispatch('chapters/getBySlug', {
+ slug: this.$route.params.slug,
+ }),
+ ])
+ .then(() => {
+ this.$store.commit('configs/setCurrentTitle', this.$t('VIEWS.SEASONS.DETAIL.CHAPTERS.DETAIL.TITLE', {
+ slug: this.chapter.natural_id,
+ name: this.chapter.name,
+ }));
+ })
.finally(() => {
if (this.loadingInstance) this.loadingInstance.close();
});
@@ -165,19 +213,24 @@ export default {
videoTitle: this.$t('VIEWS.SEASONS.DETAIL.CHAPTERS.DETAIL.VIDEO.TITLE'),
loadingText: this.$t('COMMON.LOADING'),
unavailableText: this.$t('COMMON.UNAVAILABLE'),
+ shareText: this.$t('COMMON.SOCIAL_SHARING.SHARE'),
};
},
computed: {
...mapState('chapters', {
chapter: 'current',
}),
+ ...mapState('configs', {
+ title: 'currentTitle',
+ }),
+ ...mapState('seo-configs', {
+ seoConfig: 'currentSeoConfig',
+ }),
},
- created() {
- if (process.browser) {
- // eslint-disable-next-line nuxt/no-globals-in-created
- window.addEventListener('resize', this.handleResize);
- this.handleResize();
- }
+ mounted() {
+ // eslint-disable-next-line nuxt/no-globals-in-created
+ window.addEventListener('resize', this.handleResize);
+ this.handleResize();
},
beforeDestroy() {
if (this.loadingInstance) this.loadingInstance.close();
@@ -196,6 +249,85 @@ export default {
return this.loadingInstance && this.loadingInstance.visible;
},
},
+ head() {
+ const obj = {
+ meta: [],
+ link: [],
+ };
+
+ const { seoConfig } = this;
+
+ if (seoConfig.title) obj.title = seoConfig.title;
+ // Standard metas
+ if (seoConfig.description) {
+ obj.meta.push({
+ hid: 'description',
+ name: 'description',
+ content: seoConfig.description,
+ });
+ }
+ if (seoConfig.canonical_url) {
+ obj.link.push({
+ rel: 'canonical',
+ href: seoConfig.canonical_url,
+ });
+ }
+
+ // Open Graph metas
+ if (seoConfig.og_title) {
+ obj.meta.push({
+ hid: 'og:title',
+ property: 'og:title',
+ content: seoConfig.og_title,
+ });
+ }
+ if (seoConfig.og_type) {
+ obj.meta.push({
+ hid: 'og:type',
+ property: 'og:type',
+ content: seoConfig.og_type,
+ });
+ }
+ if (seoConfig.og_image) {
+ obj.meta.push({
+ hid: 'og:image',
+ property: 'og:image',
+ content: seoConfig.og_image,
+ });
+ }
+ if (seoConfig.og_url) {
+ obj.meta.push({
+ hid: 'og:url',
+ property: 'og:url',
+ content: seoConfig.og_url,
+ });
+ }
+ if (seoConfig.og_description) {
+ obj.meta.push({
+ hid: 'og:description',
+ property: 'og:description',
+ content: seoConfig.og_description,
+ });
+ }
+
+ // Twitter metas
+ if (seoConfig.twitter_site) {
+ obj.meta.push({
+ hid: 'twitter:site',
+ name: 'twitter:site',
+ content: seoConfig.twitter_site,
+ });
+ }
+ if (seoConfig.twitter_card) {
+ obj.meta.push({
+ hid: 'twitter:card',
+ name: 'twitter:card',
+ content: seoConfig.twitter_card,
+ });
+ }
+
+ return obj;
+ },
};
diff --git a/pages/seasons/index.vue b/pages/seasons/index.vue
index 0879a18..772e6b4 100644
--- a/pages/seasons/index.vue
+++ b/pages/seasons/index.vue
@@ -1,21 +1,54 @@
-
-
+ {{ title }}
+
+
+
-
-
-
+
+
+
+
+
+ {{ shareText }}
+
+
+
+
+
+
+
+
+
+
+
+
@@ -44,28 +77,42 @@ export default {
});
}
- return this.$store.dispatch('chapters/getAll', { season: this.$route.params.season_number })
+ this.$store.commit('configs/setCurrentTitle', this.$t('VIEWS.SEASONS.DETAIL.TITLE', { number: this.$route.params.season_number }));
+
+ return Promise.all([
+ this.$store.dispatch('seo-configs/getSeoConfigBySlug', {
+ slug: `season-${this.$route.params.season_number}-chapters`,
+ }),
+ this.$store.dispatch('chapters/getAll', {
+ season: this.$route.params.season_number,
+ }),
+ ])
.finally(() => {
if (this.loadingInstance) this.loadingInstance.close();
});
},
data() {
return {
- gutter: 50,
+ gutter: utils.VIEWS.SEASONS.GUTTER.DEFAULT,
detailButtonText: this.$t('VIEWS.SEASONS.SEE_DETAIL.TEXT'),
+ shareText: this.$t('COMMON.SOCIAL_SHARING.SHARE'),
};
},
computed: {
...mapState('chapters', {
chapters: 'all',
}),
+ ...mapState('configs', {
+ title: 'currentTitle',
+ }),
+ ...mapState('seo-configs', {
+ seoConfig: 'currentSeoConfig',
+ }),
},
- created() {
- if (process.browser) {
- // eslint-disable-next-line nuxt/no-globals-in-created
- window.addEventListener('resize', this.handleResize);
- this.handleResize();
- }
+ mounted() {
+ // eslint-disable-next-line nuxt/no-globals-in-created
+ window.addEventListener('resize', this.handleResize);
+ this.handleResize();
},
beforeDestroy() {
if (this.loadingInstance) this.loadingInstance.close();
@@ -75,12 +122,91 @@ export default {
methods: {
handleResize() {
if (utils.isMobile()) {
- this.gutter = utils.VIEWS.CHARACTERS.GUTTER.MOBILE;
+ this.gutter = utils.VIEWS.SEASONS.GUTTER.MOBILE;
} else {
- this.gutter = utils.VIEWS.CHARACTERS.GUTTER.DEFAULT;
+ this.gutter = utils.VIEWS.SEASONS.GUTTER.DEFAULT;
}
},
},
+ head() {
+ const obj = {
+ meta: [],
+ link: [],
+ };
+
+ const { seoConfig } = this;
+
+ if (seoConfig.title) obj.title = seoConfig.title;
+ // Standard metas
+ if (seoConfig.description) {
+ obj.meta.push({
+ hid: 'description',
+ name: 'description',
+ content: seoConfig.description,
+ });
+ }
+ if (seoConfig.canonical_url) {
+ obj.link.push({
+ rel: 'canonical',
+ href: seoConfig.canonical_url,
+ });
+ }
+
+ // Open Graph metas
+ if (seoConfig.og_title) {
+ obj.meta.push({
+ hid: 'og:title',
+ property: 'og:title',
+ content: seoConfig.og_title,
+ });
+ }
+ if (seoConfig.og_type) {
+ obj.meta.push({
+ hid: 'og:type',
+ property: 'og:type',
+ content: seoConfig.og_type,
+ });
+ }
+ if (seoConfig.og_image) {
+ obj.meta.push({
+ hid: 'og:image',
+ property: 'og:image',
+ content: seoConfig.og_image,
+ });
+ }
+ if (seoConfig.og_url) {
+ obj.meta.push({
+ hid: 'og:url',
+ property: 'og:url',
+ content: seoConfig.og_url,
+ });
+ }
+ if (seoConfig.og_description) {
+ obj.meta.push({
+ hid: 'og:description',
+ property: 'og:description',
+ content: seoConfig.og_description,
+ });
+ }
+
+ // Twitter metas
+ if (seoConfig.twitter_site) {
+ obj.meta.push({
+ hid: 'twitter:site',
+ name: 'twitter:site',
+ content: seoConfig.twitter_site,
+ });
+ }
+ if (seoConfig.twitter_card) {
+ obj.meta.push({
+ hid: 'twitter:card',
+ name: 'twitter:card',
+ content: seoConfig.twitter_card,
+ });
+ }
+
+ return obj;
+ },
};
diff --git a/plugins/anhqvClient/client.js b/plugins/anhqvClient/client.js
index 9d53a33..0664b5e 100644
--- a/plugins/anhqvClient/client.js
+++ b/plugins/anhqvClient/client.js
@@ -11,6 +11,7 @@ function AnhqvClient({
const CHARACTERS = 'characters';
const CHAPTERS = 'chapters';
const ACTORS = 'actors';
+const SEO_CONFIGS = 'seo-configs';
AnhqvClient.prototype.setBaseURL = function setBaseURL(baseURL) {
this.restClient.defaults.baseURL = baseURL;
@@ -77,4 +78,15 @@ AnhqvClient.prototype.getChapterBySlug = function getChapterBySlug(slug) {
.then((response) => response.data);
};
+/**
+ * Método que sirve para obtener el conjunto de configuraciones de SEO
+ * de una página identificada por su slug.
+ *
+ * @author jualoppaz
+ */
+AnhqvClient.prototype.getSeoConfigBySlug = function getSeoConfigBySlug(slug) {
+ return this.restClient.get(`/${SEO_CONFIGS}/${slug}`)
+ .then((response) => response.data);
+};
+
module.exports = (deps) => AnhqvClient.bind(null, deps);
diff --git a/plugins/nuxt-social-sharing.js b/plugins/nuxt-social-sharing.js
new file mode 100644
index 0000000..d3cf8ec
--- /dev/null
+++ b/plugins/nuxt-social-sharing.js
@@ -0,0 +1,5 @@
+import Vue from 'vue';
+
+const SocialSharing = require('vue-social-sharing');
+
+Vue.use(SocialSharing);
diff --git a/static/favicon.ico b/static/favicon.ico
new file mode 100644
index 0000000..03d4dc7
Binary files /dev/null and b/static/favicon.ico differ
diff --git a/static/images/characters/alicia.jpg b/static/images/characters/alicia-sanz.jpg
similarity index 100%
rename from static/images/characters/alicia.jpg
rename to static/images/characters/alicia-sanz.jpg
diff --git a/static/images/characters/belen.jpg b/static/images/characters/belen-lopez.jpg
similarity index 100%
rename from static/images/characters/belen.jpg
rename to static/images/characters/belen-lopez.jpg
diff --git a/static/images/characters/dani.jpg b/static/images/characters/dani-rubio.jpg
similarity index 100%
rename from static/images/characters/dani.jpg
rename to static/images/characters/dani-rubio.jpg
diff --git a/static/images/characters/emilio.jpg b/static/images/characters/emilio-delgado.jpg
similarity index 100%
rename from static/images/characters/emilio.jpg
rename to static/images/characters/emilio-delgado.jpg
diff --git a/static/images/characters/fernando.jpg b/static/images/characters/fernando-navarro.jpg
similarity index 100%
rename from static/images/characters/fernando.jpg
rename to static/images/characters/fernando-navarro.jpg
diff --git a/static/images/characters/josemi.jpg b/static/images/characters/jose-miguel-cuesta.jpg
similarity index 100%
rename from static/images/characters/josemi.jpg
rename to static/images/characters/jose-miguel-cuesta.jpg
diff --git a/static/images/characters/juan_cuesta.jpg b/static/images/characters/juan-cuesta.jpg
similarity index 100%
rename from static/images/characters/juan_cuesta.jpg
rename to static/images/characters/juan-cuesta.jpg
diff --git a/static/images/characters/lucia.jpg b/static/images/characters/lucia-alvarez.jpg
similarity index 100%
rename from static/images/characters/lucia.jpg
rename to static/images/characters/lucia-alvarez.jpg
diff --git a/static/images/characters/mariano.jpg b/static/images/characters/mariano-delgado.jpg
similarity index 100%
rename from static/images/characters/mariano.jpg
rename to static/images/characters/mariano-delgado.jpg
diff --git a/static/images/characters/marisa.jpg b/static/images/characters/marisa-benito.jpg
similarity index 100%
rename from static/images/characters/marisa.jpg
rename to static/images/characters/marisa-benito.jpg
diff --git a/static/images/characters/mauri.jpg b/static/images/characters/mauricio-hidalgo.jpg
similarity index 100%
rename from static/images/characters/mauri.jpg
rename to static/images/characters/mauricio-hidalgo.jpg
diff --git a/static/images/characters/mozo_mudanza_1.jpg b/static/images/characters/mozo-mudanza-1.jpg
similarity index 100%
rename from static/images/characters/mozo_mudanza_1.jpg
rename to static/images/characters/mozo-mudanza-1.jpg
diff --git a/static/images/characters/mozo_mudanza_2.jpg b/static/images/characters/mozo-mudanza-2.jpg
similarity index 100%
rename from static/images/characters/mozo_mudanza_2.jpg
rename to static/images/characters/mozo-mudanza-2.jpg
diff --git a/static/images/characters/natalia.jpg b/static/images/characters/natalia-cuesta.jpg
similarity index 100%
rename from static/images/characters/natalia.jpg
rename to static/images/characters/natalia-cuesta.jpg
diff --git a/static/images/characters/roberto.jpg b/static/images/characters/roberto-alonso.jpg
similarity index 100%
rename from static/images/characters/roberto.jpg
rename to static/images/characters/roberto-alonso.jpg
diff --git a/static/images/characters/santiago_segura.jpg b/static/images/characters/santiago-segura.jpg
similarity index 100%
rename from static/images/characters/santiago_segura.jpg
rename to static/images/characters/santiago-segura.jpg
diff --git a/static/images/characters/vicenta.jpg b/static/images/characters/vicenta-benito.jpg
similarity index 100%
rename from static/images/characters/vicenta.jpg
rename to static/images/characters/vicenta-benito.jpg
diff --git a/static/images/logo.png b/static/images/logo.png
new file mode 100644
index 0000000..182a7be
Binary files /dev/null and b/static/images/logo.png differ
diff --git a/store/configs.js b/store/configs.js
new file mode 100644
index 0000000..308fc1d
--- /dev/null
+++ b/store/configs.js
@@ -0,0 +1,13 @@
+import Vue from 'vue';
+
+export const state = () => ({
+ currentTitle: '',
+});
+
+export const getters = {};
+
+export const mutations = {
+ setCurrentTitle(state, title) {
+ Vue.set(state, 'currentTitle', title);
+ },
+};
diff --git a/store/seo-configs.js b/store/seo-configs.js
new file mode 100644
index 0000000..e63212f
--- /dev/null
+++ b/store/seo-configs.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+
+export const state = () => ({
+ currentSeoConfig: {},
+});
+
+export const actions = {
+ getSeoConfigBySlug({ commit }, { slug }) {
+ return Vue.anhqvClient.getSeoConfigBySlug(slug)
+ .then((seoConfig) => commit('setCurrentSeoConfig', seoConfig));
+ },
+};
+
+export const mutations = {
+ setCurrentSeoConfig(state, seoConfig) {
+ Vue.set(state, 'currentSeoConfig', seoConfig);
+ },
+};
diff --git a/tests/unit/App.spec.js b/tests/unit/App.spec.js
index 4e0db6f..084a21d 100644
--- a/tests/unit/App.spec.js
+++ b/tests/unit/App.spec.js
@@ -1,4 +1,5 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
import ElementUI from 'element-ui';
import App from '../../layouts/default.vue';
@@ -8,22 +9,45 @@ jest.mock('vue-adblock-detect', () => ({
},
}));
-const localVue = createLocalVue();
-localVue.use(ElementUI);
-
describe('App.vue', () => {
+ let localVue;
+ let state;
+ let mutations;
+ let store;
+
+ beforeAll(() => {
+ localVue = createLocalVue();
+ localVue.use(ElementUI);
+
+ state = {
+ currentTitle: '',
+ };
+
+ mutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ localVue.use(Vuex);
+
+ store = new Vuex.Store({
+ modules: {
+ configs: {
+ namespaced: true,
+ state,
+ mutations,
+ },
+ },
+ });
+ });
+
it('check header border-bottom', () => {
// eslint-disable-next-line no-unused-vars
const wrapper = shallowMount(App, {
localVue,
+ store,
mocks: {
$t: () => {},
$i18n: {},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'nuxt', 'el-container', 'el-header', 'el-main', 'el-footer', 'Menu'],
});
diff --git a/tests/unit/components/ActorCard.spec.js b/tests/unit/components/ActorCard.spec.js
index 805c2f2..4152fed 100644
--- a/tests/unit/components/ActorCard.spec.js
+++ b/tests/unit/components/ActorCard.spec.js
@@ -7,24 +7,6 @@ localVue.use(ElementUI);
describe('ActorCard.vue', () => {
it('check initial data', () => {
- const wrapper = shallowMount(ActorCard, {
- localVue,
- mocks: {
- $t: () => {},
- },
- propsData: {
- actor: {
- shortname: 'John',
- image_url: 'http://path/to/image',
- },
- },
- stubs: ['el-card', 'el-row', 'el-button'],
- });
- expect(wrapper.props().actor.shortname).toBe('John');
- expect(wrapper.props().actor.image_url).toBe('http://path/to/image');
- });
-
- it('it should navigate to detail page', () => {
const wrapper = shallowMount(ActorCard, {
localVue,
mocks: {
@@ -32,27 +14,16 @@ describe('ActorCard.vue', () => {
$i18n: {
locale: 'es',
},
- $router: {
- push: jest.fn(),
- },
},
propsData: {
actor: {
shortname: 'John',
- slug: 'john-doe',
image_url: 'http://path/to/image',
},
},
- stubs: ['el-card', 'el-row', 'el-button'],
- });
-
- wrapper.vm.goToDetail();
-
- expect(wrapper.vm.$router.push).toHaveBeenCalledWith({
- name: 'actors-slug___es',
- params: {
- slug: 'john-doe',
- },
+ stubs: ['el-card', 'el-row', 'el-button', 'nuxt-link'],
});
+ expect(wrapper.props().actor.shortname).toBe('John');
+ expect(wrapper.props().actor.image_url).toBe('http://path/to/image');
});
});
diff --git a/tests/unit/components/ChapterCard.spec.js b/tests/unit/components/ChapterCard.spec.js
index db3fe7a..0001877 100644
--- a/tests/unit/components/ChapterCard.spec.js
+++ b/tests/unit/components/ChapterCard.spec.js
@@ -7,24 +7,6 @@ localVue.use(ElementUI);
describe('ChapterCard.vue', () => {
it('check initial data', () => {
- const wrapper = shallowMount(ChapterCard, {
- localVue,
- mocks: {
- $t: () => {},
- },
- propsData: {
- chapter: {
- name: 'Érase un X',
- image_url: 'http://path/to/image',
- },
- },
- stubs: ['el-card', 'el-row', 'el-button'],
- });
- expect(wrapper.props().chapter.name).toBe('Érase un X');
- expect(wrapper.props().chapter.image_url).toBe('http://path/to/image');
- });
-
- it('it should navigate to detail page', () => {
const wrapper = shallowMount(ChapterCard, {
localVue,
mocks: {
@@ -32,29 +14,16 @@ describe('ChapterCard.vue', () => {
$i18n: {
locale: 'es',
},
- $router: {
- push: jest.fn(),
- },
},
propsData: {
chapter: {
name: 'Érase un X',
- slug: '0x01',
- season: '0',
image_url: 'http://path/to/image',
},
},
- stubs: ['el-card', 'el-row', 'el-button'],
- });
-
- wrapper.vm.goToDetail();
-
- expect(wrapper.vm.$router.push).toHaveBeenCalledWith({
- name: 'seasons-season_number-chapters-slug___es',
- params: {
- slug: '0x01',
- season_number: '0',
- },
+ stubs: ['el-card', 'el-row', 'el-button', 'nuxt-link'],
});
+ expect(wrapper.props().chapter.name).toBe('Érase un X');
+ expect(wrapper.props().chapter.image_url).toBe('http://path/to/image');
});
});
diff --git a/tests/unit/components/CharacterCard.spec.js b/tests/unit/components/CharacterCard.spec.js
index aa38b46..29f62c9 100644
--- a/tests/unit/components/CharacterCard.spec.js
+++ b/tests/unit/components/CharacterCard.spec.js
@@ -7,24 +7,6 @@ localVue.use(ElementUI);
describe('CharacterCard.vue', () => {
it('check initial data', () => {
- const wrapper = shallowMount(CharacterCard, {
- localVue,
- mocks: {
- $t: () => {},
- },
- propsData: {
- character: {
- shortname: 'John',
- image_url: 'http://path/to/image',
- },
- },
- stubs: ['el-card', 'el-row', 'el-button'],
- });
- expect(wrapper.props().character.shortname).toBe('John');
- expect(wrapper.props().character.image_url).toBe('http://path/to/image');
- });
-
- it('it should navigate to detail page', () => {
const wrapper = shallowMount(CharacterCard, {
localVue,
mocks: {
@@ -32,27 +14,16 @@ describe('CharacterCard.vue', () => {
$i18n: {
locale: 'es',
},
- $router: {
- push: jest.fn(),
- },
},
propsData: {
character: {
shortname: 'John',
- slug: 'john-doe',
image_url: 'http://path/to/image',
},
},
- stubs: ['el-card', 'el-row', 'el-button'],
- });
-
- wrapper.vm.goToDetail();
-
- expect(wrapper.vm.$router.push).toHaveBeenCalledWith({
- name: 'characters-slug___es',
- params: {
- slug: 'john-doe',
- },
+ stubs: ['el-card', 'el-row', 'el-button', 'nuxt-link'],
});
+ expect(wrapper.props().character.shortname).toBe('John');
+ expect(wrapper.props().character.image_url).toBe('http://path/to/image');
});
});
diff --git a/tests/unit/components/Header.spec.js b/tests/unit/components/Header.spec.js
index 00e222a..2e55cd2 100644
--- a/tests/unit/components/Header.spec.js
+++ b/tests/unit/components/Header.spec.js
@@ -11,13 +11,9 @@ describe('Header.vue', () => {
localVue,
mocks: {
$t: () => {},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
});
- expect(wrapper.vm.title).toBe('DUMMY');
+
+ expect(wrapper.text()).toBe('ANHQV STATS');
});
});
diff --git a/tests/unit/components/Menu.spec.js b/tests/unit/components/Menu.spec.js
index 760d096..6e4c119 100644
--- a/tests/unit/components/Menu.spec.js
+++ b/tests/unit/components/Menu.spec.js
@@ -23,11 +23,6 @@ describe('Menu.vue', () => {
$i18n: {
locale: 'es',
},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'el-submenu', 'el-menu', 'el-menu-item', 'el-aside'],
});
@@ -50,11 +45,6 @@ describe('Menu.vue', () => {
$i18n: {
locale: 'es',
},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'el-submenu', 'el-menu', 'el-menu-item', 'el-aside'],
methods,
@@ -75,11 +65,6 @@ describe('Menu.vue', () => {
$i18n: {
locale: 'es',
},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'el-submenu', 'el-menu', 'el-menu-item', 'el-aside'],
});
@@ -98,11 +83,6 @@ describe('Menu.vue', () => {
$i18n: {
locale: 'es',
},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'el-submenu', 'el-menu', 'el-menu-item', 'el-aside'],
});
@@ -120,11 +100,6 @@ describe('Menu.vue', () => {
$i18n: {
locale: 'es',
},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
stubs: ['nuxt-link', 'router-view', 'el-submenu', 'el-menu', 'el-menu-item', 'el-aside'],
});
diff --git a/tests/unit/pages/ActorDetail.spec.js b/tests/unit/pages/ActorDetail.spec.js
index f279614..840b725 100644
--- a/tests/unit/pages/ActorDetail.spec.js
+++ b/tests/unit/pages/ActorDetail.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import ActorDetail from '../../../pages/actors/_slug/index.vue';
@@ -12,9 +14,17 @@ describe('ActorDetail.vue', () => {
let store;
let actions;
let state;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
state = {
current: {
@@ -27,6 +37,33 @@ describe('ActorDetail.vue', () => {
destroyCurrent: jest.fn(),
};
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Actor title',
+ description: 'Actor description',
+ canonical_url: 'http://actor.com',
+ og_title: 'Actor og:title',
+ og_type: 'Actor og:type',
+ og_image: 'Actor og:image',
+ og_url: 'Actor og:url',
+ og_description: 'Actor og:description',
+ twitter_site: 'Actor twitter:site',
+ twitter_card: 'Actor twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -36,6 +73,16 @@ describe('ActorDetail.vue', () => {
state,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -61,7 +108,7 @@ describe('ActorDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
@@ -87,12 +134,68 @@ describe('ActorDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(ActorDetail, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ $route: {
+ params: {
+ slug: 'john-doe',
+ },
+ },
+ },
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Actor title');
+ expect(descriptionMeta.content).toEqual('Actor description');
+ expect(canonicalUrlLink.href).toEqual('http://actor.com');
+ expect(ogTitleMeta.content).toEqual('Actor og:title');
+ expect(ogTypeMeta.content).toEqual('Actor og:type');
+ expect(ogImageMeta.content).toEqual('Actor og:image');
+ expect(ogUrlMeta.content).toEqual('Actor og:url');
+ expect(ogDescriptionMeta.content).toEqual('Actor og:description');
+ expect(twitterSiteMeta.content).toEqual('Actor twitter:site');
+ expect(twitterCardMeta.content).toEqual('Actor twitter:card');
+ });
});
describe('handleResize', () => {
@@ -110,7 +213,7 @@ describe('ActorDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -131,7 +234,7 @@ describe('ActorDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -151,7 +254,7 @@ describe('ActorDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/pages/Actors.spec.js b/tests/unit/pages/Actors.spec.js
index 2d5767a..9310a11 100644
--- a/tests/unit/pages/Actors.spec.js
+++ b/tests/unit/pages/Actors.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import Actors from '../../../pages/actors/index.vue';
@@ -11,15 +13,50 @@ describe('Actors.vue', () => {
let localVue;
let store;
let actions;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
actions = {
getAll: jest.fn(),
destroyAll: jest.fn(),
};
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Actors title',
+ description: 'Actors description',
+ canonical_url: 'http://actors.com',
+ og_title: 'Actors og:title',
+ og_type: 'Actors og:type',
+ og_image: 'Actors og:image',
+ og_url: 'Actors og:url',
+ og_description: 'Actors og:description',
+ twitter_site: 'Actors twitter:site',
+ twitter_card: 'Actors twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -28,6 +65,16 @@ describe('Actors.vue', () => {
namespaced: true,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -49,7 +96,7 @@ describe('Actors.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['nuxt-link', 'router-view', 'el-row'],
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
});
@@ -68,12 +115,63 @@ describe('Actors.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['nuxt-link', 'router-view', 'el-row'],
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(Actors, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ },
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Actors title');
+ expect(descriptionMeta.content).toEqual('Actors description');
+ expect(canonicalUrlLink.href).toEqual('http://actors.com');
+ expect(ogTitleMeta.content).toEqual('Actors og:title');
+ expect(ogTypeMeta.content).toEqual('Actors og:type');
+ expect(ogImageMeta.content).toEqual('Actors og:image');
+ expect(ogUrlMeta.content).toEqual('Actors og:url');
+ expect(ogDescriptionMeta.content).toEqual('Actors og:description');
+ expect(twitterSiteMeta.content).toEqual('Actors twitter:site');
+ expect(twitterCardMeta.content).toEqual('Actors twitter:card');
+ });
});
describe('handleResize', () => {
@@ -86,7 +184,7 @@ describe('Actors.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['nuxt-link', 'router-view', 'el-row'],
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -102,7 +200,7 @@ describe('Actors.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['nuxt-link', 'router-view', 'el-row'],
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -117,7 +215,7 @@ describe('Actors.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['nuxt-link', 'router-view', 'el-row'],
+ stubs: ['nuxt-link', 'router-view', 'el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/pages/ChapterDetail.spec.js b/tests/unit/pages/ChapterDetail.spec.js
index 3bc8d7c..d058132 100644
--- a/tests/unit/pages/ChapterDetail.spec.js
+++ b/tests/unit/pages/ChapterDetail.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import ChapterDetail from '../../../pages/seasons/_season_number/chapters/_slug/index.vue';
@@ -12,9 +14,17 @@ describe('ChapterDetail.vue', () => {
let store;
let actions;
let state;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
state = {
current: {
@@ -27,6 +37,33 @@ describe('ChapterDetail.vue', () => {
destroyCurrent: jest.fn(),
};
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Chapter title',
+ description: 'Chapter description',
+ canonical_url: 'http://chapter.com',
+ og_title: 'Chapter og:title',
+ og_type: 'Chapter og:type',
+ og_image: 'Chapter og:image',
+ og_url: 'Chapter og:url',
+ og_description: 'Chapter og:description',
+ twitter_site: 'Chapter twitter:site',
+ twitter_card: 'Chapter twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -36,6 +73,16 @@ describe('ChapterDetail.vue', () => {
state,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -62,7 +109,7 @@ describe('ChapterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
});
@@ -86,12 +133,68 @@ describe('ChapterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(ChapterDetail, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ $route: {
+ params: {
+ chapter_slug: '0x01',
+ },
+ },
+ },
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Chapter title');
+ expect(descriptionMeta.content).toEqual('Chapter description');
+ expect(canonicalUrlLink.href).toEqual('http://chapter.com');
+ expect(ogTitleMeta.content).toEqual('Chapter og:title');
+ expect(ogTypeMeta.content).toEqual('Chapter og:type');
+ expect(ogImageMeta.content).toEqual('Chapter og:image');
+ expect(ogUrlMeta.content).toEqual('Chapter og:url');
+ expect(ogDescriptionMeta.content).toEqual('Chapter og:description');
+ expect(twitterSiteMeta.content).toEqual('Chapter twitter:site');
+ expect(twitterCardMeta.content).toEqual('Chapter twitter:card');
+ });
});
@@ -110,7 +213,7 @@ describe('ChapterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -131,7 +234,7 @@ describe('ChapterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -151,7 +254,7 @@ describe('ChapterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-row', 'el-col', 'el-avatar'],
+ stubs: ['el-card', 'el-row', 'el-col', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/pages/CharacterDetail.spec.js b/tests/unit/pages/CharacterDetail.spec.js
index 94912ac..c5a1a28 100644
--- a/tests/unit/pages/CharacterDetail.spec.js
+++ b/tests/unit/pages/CharacterDetail.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import CharacterDetail from '../../../pages/characters/_slug/index.vue';
@@ -12,9 +14,17 @@ describe('CharacterDetail.vue', () => {
let store;
let actions;
let state;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
state = {
current: {
@@ -27,6 +37,33 @@ describe('CharacterDetail.vue', () => {
destroyCurrent: jest.fn(),
};
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Character title',
+ description: 'Character description',
+ canonical_url: 'http://character.com',
+ og_title: 'Character og:title',
+ og_type: 'Character og:type',
+ og_image: 'Character og:image',
+ og_url: 'Character og:url',
+ og_description: 'Character og:description',
+ twitter_site: 'Character twitter:site',
+ twitter_card: 'Character twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -36,6 +73,16 @@ describe('CharacterDetail.vue', () => {
state,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -61,7 +108,7 @@ describe('CharacterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-col', 'el-row', 'el-avatar'],
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
@@ -87,12 +134,68 @@ describe('CharacterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-col', 'el-row', 'el-avatar'],
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(CharacterDetail, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ $route: {
+ params: {
+ slug: 'john-doe',
+ },
+ },
+ },
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Character title');
+ expect(descriptionMeta.content).toEqual('Character description');
+ expect(canonicalUrlLink.href).toEqual('http://character.com');
+ expect(ogTitleMeta.content).toEqual('Character og:title');
+ expect(ogTypeMeta.content).toEqual('Character og:type');
+ expect(ogImageMeta.content).toEqual('Character og:image');
+ expect(ogUrlMeta.content).toEqual('Character og:url');
+ expect(ogDescriptionMeta.content).toEqual('Character og:description');
+ expect(twitterSiteMeta.content).toEqual('Character twitter:site');
+ expect(twitterCardMeta.content).toEqual('Character twitter:card');
+ });
});
describe('handleResize', () => {
@@ -110,7 +213,7 @@ describe('CharacterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-col', 'el-row', 'el-avatar'],
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -131,7 +234,7 @@ describe('CharacterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-col', 'el-row', 'el-avatar'],
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -151,7 +254,7 @@ describe('CharacterDetail.vue', () => {
},
},
},
- stubs: ['el-card', 'el-col', 'el-row', 'el-avatar'],
+ stubs: ['el-card', 'el-col', 'el-row', 'el-avatar', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/pages/Characters.spec.js b/tests/unit/pages/Characters.spec.js
index 70def74..b94a0cf 100644
--- a/tests/unit/pages/Characters.spec.js
+++ b/tests/unit/pages/Characters.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import Characters from '../../../pages/characters/index.vue';
@@ -11,15 +13,50 @@ describe('Characters.vue', () => {
let localVue;
let store;
let actions;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
actions = {
getAll: jest.fn(),
destroyAll: jest.fn(),
};
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Characters title',
+ description: 'Characters description',
+ canonical_url: 'http://characters.com',
+ og_title: 'Characters og:title',
+ og_type: 'Characters og:type',
+ og_image: 'Characters og:image',
+ og_url: 'Characters og:url',
+ og_description: 'Characters og:description',
+ twitter_site: 'Characters twitter:site',
+ twitter_card: 'Characters twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -28,6 +65,16 @@ describe('Characters.vue', () => {
namespaced: true,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -49,7 +96,7 @@ describe('Characters.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
});
@@ -68,12 +115,63 @@ describe('Characters.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(Characters, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ },
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Characters title');
+ expect(descriptionMeta.content).toEqual('Characters description');
+ expect(canonicalUrlLink.href).toEqual('http://characters.com');
+ expect(ogTitleMeta.content).toEqual('Characters og:title');
+ expect(ogTypeMeta.content).toEqual('Characters og:type');
+ expect(ogImageMeta.content).toEqual('Characters og:image');
+ expect(ogUrlMeta.content).toEqual('Characters og:url');
+ expect(ogDescriptionMeta.content).toEqual('Characters og:description');
+ expect(twitterSiteMeta.content).toEqual('Characters twitter:site');
+ expect(twitterCardMeta.content).toEqual('Characters twitter:card');
+ });
});
@@ -87,7 +185,7 @@ describe('Characters.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -103,7 +201,7 @@ describe('Characters.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -118,7 +216,7 @@ describe('Characters.vue', () => {
mocks: {
$t: () => {},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/pages/Home.spec.js b/tests/unit/pages/Home.spec.js
index cdfe948..31b8f0a 100644
--- a/tests/unit/pages/Home.spec.js
+++ b/tests/unit/pages/Home.spec.js
@@ -1,25 +1,131 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import Home from '../../../pages/index.vue';
-const localVue = createLocalVue();
-localVue.use(ElementUI);
-
describe('Home.vue', () => {
+ let localVue;
+ let store;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
+ beforeAll(() => {
+ localVue = createLocalVue();
+ localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
+
+ configsState = {
+ currentTitle: '',
+ };
+
+ configsMutations = {
+ setCurrentTitle: jest.fn(),
+ };
+
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Home title',
+ description: 'Home description',
+ canonical_url: 'http://home.com',
+ og_title: 'Home og:title',
+ og_type: 'Home og:type',
+ og_image: 'Home og:image',
+ og_url: 'Home og:url',
+ og_description: 'Home og:description',
+ twitter_site: 'Home twitter:site',
+ twitter_card: 'Home twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
+ localVue.use(Vuex);
+
+ store = new Vuex.Store({
+ modules: {
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
+ },
+ });
+ });
+
it('check initial data', () => {
const wrapper = shallowMount(Home, {
localVue,
- stubs: ['nuxt-link', 'router-view', 'font-awesome-icon', 'Adsense', 'el-row', 'el-col', 'el-card'],
+ store,
+ stubs: ['nuxt-link', 'router-view', 'font-awesome-icon', 'Adsense', 'el-row', 'el-col', 'el-card', 'adsbygoogle', 'social-sharing', 'network'],
mocks: {
$t: () => {},
- $route: {
- meta: {
- title: () => 'dummy',
- },
- },
},
});
expect(wrapper.find('#welcome-image').exists()).toBe(true);
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(Home, {
+ localVue,
+ store,
+ stubs: ['nuxt-link', 'router-view', 'font-awesome-icon', 'Adsense', 'el-row', 'el-col', 'el-card', 'adsbygoogle', 'social-sharing', 'network'],
+ mocks: {
+ $t: () => {},
+ },
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Home title');
+ expect(descriptionMeta.content).toEqual('Home description');
+ expect(canonicalUrlLink.href).toEqual('http://home.com');
+ expect(ogTitleMeta.content).toEqual('Home og:title');
+ expect(ogTypeMeta.content).toEqual('Home og:type');
+ expect(ogImageMeta.content).toEqual('Home og:image');
+ expect(ogUrlMeta.content).toEqual('Home og:url');
+ expect(ogDescriptionMeta.content).toEqual('Home og:description');
+ expect(twitterSiteMeta.content).toEqual('Home twitter:site');
+ expect(twitterCardMeta.content).toEqual('Home twitter:card');
+ });
});
diff --git a/tests/unit/pages/Season.spec.js b/tests/unit/pages/Season.spec.js
index 7d06605..d8b0f3c 100644
--- a/tests/unit/pages/Season.spec.js
+++ b/tests/unit/pages/Season.spec.js
@@ -1,5 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import VueMeta from 'vue-meta';
import ElementUI from 'element-ui';
import Season from '../../../pages/seasons/index.vue';
@@ -11,15 +13,42 @@ describe('Season.vue', () => {
let localVue;
let store;
let actions;
+
+ let configsState;
+ let configsMutations;
+
+ let seoConfigState;
+ let seoConfigActions;
+
beforeAll(() => {
localVue = createLocalVue();
localVue.use(ElementUI);
+ localVue.use(VueMeta, { keyName: 'head' });
actions = {
getAll: jest.fn(),
destroyAll: jest.fn(),
};
+ seoConfigState = {
+ currentSeoConfig: {
+ title: 'Chapters title',
+ description: 'Chapters description',
+ canonical_url: 'http://chapters.com',
+ og_title: 'Chapters og:title',
+ og_type: 'Chapters og:type',
+ og_image: 'Chapters og:image',
+ og_url: 'Chapters og:url',
+ og_description: 'Chapters og:description',
+ twitter_site: 'Chapters twitter:site',
+ twitter_card: 'Chapters twitter:card',
+ },
+ };
+
+ seoConfigActions = {
+ getSeoConfigBySlug: jest.fn(),
+ };
+
localVue.use(Vuex);
store = new Vuex.Store({
@@ -28,6 +57,16 @@ describe('Season.vue', () => {
namespaced: true,
actions,
},
+ configs: {
+ namespaced: true,
+ state: configsState,
+ mutations: configsMutations,
+ },
+ 'seo-configs': {
+ namespaced: true,
+ state: seoConfigState,
+ actions: seoConfigActions,
+ },
},
});
});
@@ -53,7 +92,7 @@ describe('Season.vue', () => {
},
},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
@@ -79,12 +118,68 @@ describe('Season.vue', () => {
},
},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
methods,
});
expect(methods.handleResize).toHaveBeenCalled();
});
+
+ it('has correct content', () => {
+ const wrapper = shallowMount(Season, {
+ localVue,
+ store,
+ mocks: {
+ $t: () => {},
+ $route: {
+ params: {
+ season_number: () => '0',
+ },
+ },
+ },
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
+ });
+
+ const { title } = wrapper.vm.$metaInfo;
+ const descriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'description',
+ );
+ const canonicalUrlLink = wrapper.vm.$metaInfo.link.find(
+ (item) => item.rel === 'canonical',
+ );
+ const ogTitleMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:title',
+ );
+ const ogTypeMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:type',
+ );
+ const ogImageMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:image',
+ );
+ const ogUrlMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:url',
+ );
+ const ogDescriptionMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'og:description',
+ );
+ const twitterSiteMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:site',
+ );
+ const twitterCardMeta = wrapper.vm.$metaInfo.meta.find(
+ (item) => item.hid === 'twitter:card',
+ );
+
+ expect(title).toEqual('Chapters title');
+ expect(descriptionMeta.content).toEqual('Chapters description');
+ expect(canonicalUrlLink.href).toEqual('http://chapters.com');
+ expect(ogTitleMeta.content).toEqual('Chapters og:title');
+ expect(ogTypeMeta.content).toEqual('Chapters og:type');
+ expect(ogImageMeta.content).toEqual('Chapters og:image');
+ expect(ogUrlMeta.content).toEqual('Chapters og:url');
+ expect(ogDescriptionMeta.content).toEqual('Chapters og:description');
+ expect(twitterSiteMeta.content).toEqual('Chapters twitter:site');
+ expect(twitterCardMeta.content).toEqual('Chapters twitter:card');
+ });
});
describe('handleResize', () => {
@@ -102,7 +197,7 @@ describe('Season.vue', () => {
},
},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -123,7 +218,7 @@ describe('Season.vue', () => {
},
},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
wrapper.vm.handleResize();
@@ -143,7 +238,7 @@ describe('Season.vue', () => {
},
},
},
- stubs: ['el-row'],
+ stubs: ['el-row', 'social-sharing', 'font-awesome-icon', 'network'],
});
window.removeEventListener = jest.fn();
diff --git a/tests/unit/store/actors.spec.js b/tests/unit/store/actors.spec.js
index c6af6be..b843f58 100644
--- a/tests/unit/store/actors.spec.js
+++ b/tests/unit/store/actors.spec.js
@@ -63,6 +63,16 @@ describe('store/actors.js', () => {
expect(commit).toHaveBeenCalledWith('setCurrent', {});
});
});
+
+ describe('destroyAll', () => {
+ it('it should call setAll mutation', () => {
+ const commit = jest.fn();
+
+ actions.destroyAll({ commit });
+
+ expect(commit).toHaveBeenCalledWith('setAll', []);
+ });
+ });
});
describe('mutations', () => {
diff --git a/tests/unit/store/chapters.spec.js b/tests/unit/store/chapters.spec.js
index c657e82..4c5f4ba 100644
--- a/tests/unit/store/chapters.spec.js
+++ b/tests/unit/store/chapters.spec.js
@@ -68,6 +68,16 @@ describe('store/chapters.js', () => {
expect(commit).toHaveBeenCalledWith('setCurrent', {});
});
});
+
+ describe('destroyAll', () => {
+ it('it should call setAll mutation', () => {
+ const commit = jest.fn();
+
+ actions.destroyAll({ commit });
+
+ expect(commit).toHaveBeenCalledWith('setAll', []);
+ });
+ });
});
describe('mutations', () => {
diff --git a/tests/unit/store/characters.spec.js b/tests/unit/store/characters.spec.js
index 3fcfc97..2791a82 100644
--- a/tests/unit/store/characters.spec.js
+++ b/tests/unit/store/characters.spec.js
@@ -63,6 +63,16 @@ describe('store/characters.js', () => {
expect(commit).toHaveBeenCalledWith('setCurrent', {});
});
});
+
+ describe('destroyAll', () => {
+ it('it should call setAll mutation', () => {
+ const commit = jest.fn();
+
+ actions.destroyAll({ commit });
+
+ expect(commit).toHaveBeenCalledWith('setAll', []);
+ });
+ });
});
describe('mutations', () => {
diff --git a/tests/unit/store/configs.spec.js b/tests/unit/store/configs.spec.js
new file mode 100644
index 0000000..62fa2c9
--- /dev/null
+++ b/tests/unit/store/configs.spec.js
@@ -0,0 +1,21 @@
+
+import Vue from 'vue';
+import { state, mutations } from '../../../store/configs';
+
+describe('store/configs.js', () => {
+ beforeEach(() => {
+ Vue.anhqvClient = {};
+ });
+
+ describe('mutations', () => {
+ describe('setCurrentTitle', () => {
+ it('it should modify currentTitle state property', () => {
+ const title = 'new title';
+
+ mutations.setCurrentTitle(state, title);
+
+ expect(state.currentTitle).toEqual(title);
+ });
+ });
+ });
+});
diff --git a/tests/unit/store/seo-configs.spec.js b/tests/unit/store/seo-configs.spec.js
new file mode 100644
index 0000000..29179b6
--- /dev/null
+++ b/tests/unit/store/seo-configs.spec.js
@@ -0,0 +1,49 @@
+
+import Vue from 'vue';
+import { state, actions, mutations } from '../../../store/seo-configs';
+
+describe('store/seo-configs.js', () => {
+ beforeEach(() => {
+ Vue.anhqvClient = {};
+ });
+
+ describe('actions', () => {
+ describe('getBySlug', () => {
+ it('it should call getSeoConfigBySlug method and setCurrentSeoConfig mutation', (done) => {
+ const expectedSeoConfig = {
+ title: 'Page title',
+ description: 'Page description',
+ };
+
+ const slug = 'page-slug';
+
+ const commit = jest.fn();
+
+ Vue.anhqvClient.getSeoConfigBySlug = jest.fn().mockResolvedValue(expectedSeoConfig);
+
+ actions.getSeoConfigBySlug({ commit }, { slug })
+ .then(() => {
+ expect(Vue.anhqvClient.getSeoConfigBySlug).toHaveBeenCalledWith(slug);
+
+ expect(commit).toHaveBeenCalledWith('setCurrentSeoConfig', expectedSeoConfig);
+ done();
+ });
+ });
+ });
+ });
+
+ describe('mutations', () => {
+ describe('setCurrentSeoConfig', () => {
+ it('it should modify currentSeoConfig state property', () => {
+ const seoConfig = {
+ title: 'Page title',
+ description: 'Page description',
+ };
+
+ mutations.setCurrentSeoConfig(state, seoConfig);
+
+ expect(state.currentSeoConfig).toEqual(seoConfig);
+ });
+ });
+ });
+});
diff --git a/utils/constants.js b/utils/constants.js
index e14c7b2..883c693 100644
--- a/utils/constants.js
+++ b/utils/constants.js
@@ -29,6 +29,12 @@ const constants = {
MOBILE: 20,
},
},
+ SEASONS: {
+ GUTTER: {
+ DEFAULT: 50,
+ MOBILE: 20,
+ },
+ },
},
};