Skip to content

Commit

Permalink
feat(components): add cookie consent (#179)
Browse files Browse the repository at this point in the history
closes #178
  • Loading branch information
devCrossNet committed Jul 25, 2018
1 parent 0e2c021 commit a30fad4
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 40 deletions.
32 changes: 23 additions & 9 deletions src/app/app/App/App.vue
@@ -1,6 +1,7 @@
<template>
<div id="app" :class="$style.app">
<vue-notification-stack />

<vue-nav-bar>
<ul :class="$style.nav">
<li>
Expand Down Expand Up @@ -51,29 +52,42 @@
<router-view :class="$style.content" />

<vue-footer />

<vue-cookie-consent
current-version="1.0.0"
:cookie-consent-version="cookieConsentVersion"
:set-cookie-consent-version="setCookieConsentVersion">
This is a cookie consent component which shows the cookie consent every time you change the version of the
consent.
</vue-cookie-consent>
</div>
</template>

<script lang="ts">
import { mapActions } from 'vuex';
import VueNavBar from '../../shared/components/VueNavBar/VueNavBar.vue';
import VueGrid from '../../shared/components/VueGrid/VueGrid.vue';
import VueGridItem from '../../shared/components/VueGridItem/VueGridItem.vue';
import VueFooter from '../../shared/components/VueFooter/VueFooter.vue';
import VueNotificationStack from '../../shared/components/VueNotificationStack/VueNotificationStack.vue';
import { loadLocaleAsync } from '../../shared/plugins/i18n/i18n';
import { EventBus } from '../../shared/services/EventBus';
import { mapActions, mapGetters } from 'vuex';
import VueNavBar from '../../shared/components/VueNavBar/VueNavBar.vue';
import VueGrid from '../../shared/components/VueGrid/VueGrid.vue';
import VueGridItem from '../../shared/components/VueGridItem/VueGridItem.vue';
import VueFooter from '../../shared/components/VueFooter/VueFooter.vue';
import VueNotificationStack from '../../shared/components/VueNotificationStack/VueNotificationStack.vue';
import VueCookieConsent from '../../shared/components/VueCookieConsent/VueCookieConsent';
import { loadLocaleAsync } from '../../shared/plugins/i18n/i18n';
import { EventBus } from '../../shared/services/EventBus';
export default {
components: {
VueCookieConsent,
VueNavBar,
VueGrid,
VueGridItem,
VueFooter,
VueNotificationStack,
},
computed: {
...mapGetters('app', ['cookieConsentVersion']),
},
methods: {
...mapActions('app', ['changeLocale']),
...mapActions('app', ['changeLocale', 'setCookieConsentVersion']),
localeSwitch(locale: string): void {
loadLocaleAsync(locale)
.catch((error: Error) => console.log(error));
Expand Down
7 changes: 7 additions & 0 deletions src/app/app/actions.spec.ts
Expand Up @@ -24,4 +24,11 @@ describe('AppActions', () => {
expect(testContext.commit).toHaveBeenCalledWith('CHANGE_LOCALE', 'de');
});

test('it should change the cookie consent version', () => {
AppActions.setCookieConsentVersion(testContext, '1.0.0');

expect(testContext.commit).toHaveBeenCalled();
expect(testContext.commit).toHaveBeenCalledWith('SET_COOKIE_CONSENT_VERSION', '1.0.0');
});

});
5 changes: 4 additions & 1 deletion src/app/app/actions.ts
Expand Up @@ -3,8 +3,11 @@ import { IAppState } from './state';

export interface IAppActions {
changeLocale(context: ActionContext<IAppState, IAppState>, locale: string): void;

setCookieConsentVersion(context: ActionContext<IAppState, IAppState>, version: string): void;
}

export const AppActions: IAppActions = {
changeLocale: ({ commit }: ActionContext<IAppState, IAppState>, locale: string) => commit('CHANGE_LOCALE', locale),
changeLocale: ({ commit }: ActionContext<IAppState, IAppState>, locale: string) => commit('CHANGE_LOCALE', locale),
setCookieConsentVersion: ({ commit }: ActionContext<IAppState, IAppState>, version: string) => commit('SET_COOKIE_CONSENT_VERSION', version),
};
4 changes: 4 additions & 0 deletions src/app/app/getters.spec.ts
Expand Up @@ -7,4 +7,8 @@ describe('AppGetters', () => {
expect(AppGetters.getLocale(AppDefaultState)).toBe(null);
});

test('it should get the cookie consent version', () => {
expect(AppGetters.cookieConsentVersion(AppDefaultState)).toBe('');
});

});
5 changes: 5 additions & 0 deletions src/app/app/getters.ts
Expand Up @@ -2,10 +2,15 @@ import { IAppState } from './state';

export interface IAppGetters {
getLocale(state: IAppState): string;

cookieConsentVersion(state: IAppState): string;
}

export const AppGetters: IAppGetters = {
getLocale(state: IAppState): string {
return state.locale;
},
cookieConsentVersion(state: IAppState): string {
return state.cookieConsentVersion;
},
};
5 changes: 5 additions & 0 deletions src/app/app/mutations.spec.ts
Expand Up @@ -13,4 +13,9 @@ describe('AppMutations', () => {
AppMutations.CHANGE_LOCALE(testState, 'de');
expect(testState.locale).toBe('de');
});

test('it should change the cookie consent version', () => {
AppMutations.SET_COOKIE_CONSENT_VERSION(testState, '1.0.0');
expect(testState.cookieConsentVersion).toBe('1.0.0');
});
});
7 changes: 6 additions & 1 deletion src/app/app/mutations.ts
Expand Up @@ -2,10 +2,15 @@ import { IAppState } from './state';

export interface IAppMutations {
CHANGE_LOCALE(state: IAppState, locale: string): void;

SET_COOKIE_CONSENT_VERSION(state: IAppState, version: string): void;
}

export const AppMutations: IAppMutations = {
CHANGE_LOCALE: (state: IAppState, locale: string) => {
CHANGE_LOCALE: (state: IAppState, locale: string) => {
state.locale = locale;
},
SET_COOKIE_CONSENT_VERSION: (state: IAppState, version: string) => {
state.cookieConsentVersion = version;
},
};
10 changes: 6 additions & 4 deletions src/app/app/state.ts
Expand Up @@ -5,11 +5,13 @@ export interface IAppState {
config: IAppConfig;
defaultMessages: any;
redirectTo: string;
cookieConsentVersion: string;
}

export const AppDefaultState: IAppState = {
locale: null,
config: null,
defaultMessages: {},
redirectTo: null,
locale: null,
config: null,
defaultMessages: {},
redirectTo: null,
cookieConsentVersion: '',
};
21 changes: 21 additions & 0 deletions src/app/shared/animations/FadeAnimation/FadeAnimation.spec.ts
@@ -0,0 +1,21 @@
import { createLocalVue, mount } from '@vue/test-utils';
import FadeAnimation from './FadeAnimation.vue';

const localVue = createLocalVue();

describe('FadeAnimation.vue', () => {

test('renders component', () => {
const wrapper = mount(FadeAnimation,
{
localVue,
slots: {
default: '<div>foo</div>',
},
},
);

expect(wrapper.text()).toBe('foo');
});

});
33 changes: 33 additions & 0 deletions src/app/shared/animations/FadeAnimation/FadeAnimation.vue
@@ -0,0 +1,33 @@
<template>
<transition
:enter-class="$style.enter"
:enter-active-class="$style.enterActive"
:enter-to-class="$style.enterTo"
:leave-class="$style.leave"
:leave-active-class="$style.leaveActive"
:leave-to-class="$style.leaveTo">
<slot />
</transition>
</template>

<script lang="ts">
export default {
name: 'FadeAnimation',
};
</script>

<style lang="scss" module>
@import "../../styles";
.enterActive, .leaveActive {
transition: $fade-animation-transition;
}
.enterTo, .leave {
opacity: 1;
}
.enter, .leaveTo {
opacity: 0;
}
</style>
39 changes: 15 additions & 24 deletions src/app/shared/components/VueCarousel/VueCarousel.vue
Expand Up @@ -4,14 +4,14 @@
@mouseenter="pause = true"
@mouseleave="pause = false">

<transition v-for="(image, idx) in preloadedImages"
:key="idx"
:enter-class="$style.enter"
:enter-active-class="$style.enterActive"
:enter-to-class="$style.enterTo"
:leave-class="$style.leave"
:leave-active-class="$style.leaveActive"
:leave-to-class="$style.leaveTo">
<fade-animation v-for="(image, idx) in preloadedImages"
:key="idx"
:enter-class="$style.enter"
:enter-active-class="$style.enterActive"
:enter-to-class="$style.enterTo"
:leave-class="$style.leave"
:leave-active-class="$style.leaveActive"
:leave-to-class="$style.leaveTo">

<div
v-if="isActiveSlide(idx)"
Expand All @@ -25,7 +25,7 @@
</div>
</div>

</transition>
</fade-animation>

<ul v-if="showIndicator"
:class="$style.indicator">
Expand All @@ -40,15 +40,18 @@
</template>

<script lang="ts">
import FadeAnimation from '../../animations/FadeAnimation/FadeAnimation';
export interface ICarouselImage {
copyright?: string;
alt?: string;
url: string;
}
export default {
name: 'VueCarousel',
props: {
name: 'VueCarousel',
components: { FadeAnimation },
props: {
images: {
type: Array,
default: (): any[] => [],
Expand Down Expand Up @@ -79,7 +82,7 @@
preloadedImages: [],
};
},
methods: {
methods: {
isActiveSlide(idx: number) {
return this.currentSlide === idx;
},
Expand Down Expand Up @@ -174,16 +177,4 @@
}
}
}
.enterActive, .leaveActive {
transition: $carousel-transition;
}
.enterTo, .leave {
opacity: 1;
}
.enter, .leaveTo {
opacity: 0;
}
</style>
@@ -0,0 +1,80 @@
import { createLocalVue, mount } from '@vue/test-utils';
import VueCookieConsent from './VueCookieConsent.vue';

const localVue = createLocalVue();

describe('VueCookieConsent.vue', () => {

test('renders visible component and simulates consent click', () => {
const setCookieConsentVersion: any = jest.fn();

const wrapper = mount(VueCookieConsent,
{
localVue,
slots: {
default: 'foo',
},
propsData: {
currentVersion: '1.1.0',
cookieConsentVersion: '1.0.0',
setCookieConsentVersion,
},
},
) as any;

expect(wrapper.text()).toBe('foo');
expect(wrapper.findAll('.button')).toHaveLength(1);
expect(wrapper.vm.show).toBeTruthy();

wrapper.find('.button').trigger('click');

expect(setCookieConsentVersion).toHaveBeenCalledWith('1.1.0');
});

test('renders hidden component', () => {
const wrapper = mount(VueCookieConsent,
{
localVue,
slots: {
default: 'foo',
},
propsData: {
currentVersion: '1.0.0',
cookieConsentVersion: '1.0.0',
setCookieConsentVersion: jest.fn(),
},
},
) as any;

expect(wrapper.text()).toBe('');
expect(wrapper.findAll('.button')).toHaveLength(0);
expect(wrapper.vm.show).toBeFalsy();
});

test('test watchers', () => {
const wrapper = mount(VueCookieConsent,
{
localVue,
slots: {
default: 'foo',
},
propsData: {
currentVersion: '1.1.0',
cookieConsentVersion: '1.0.0',
setCookieConsentVersion: jest.fn(),
},
},
) as any;

expect(wrapper.text()).toBe('foo');
expect(wrapper.findAll('.button')).toHaveLength(1);
expect(wrapper.vm.show).toBeTruthy();

wrapper.setProps({ cookieConsentVersion: '1.1.0' });
expect(wrapper.vm.show).toBeFalsy();

wrapper.setProps({ cookieConsentVersion: '1.0.0' });
expect(wrapper.vm.show).toBeTruthy();
});

});
@@ -0,0 +1,18 @@
import { storiesOf } from '@storybook/vue';
import { action } from '@storybook/addon-actions';
import VueInfoAddon from 'storybook-addon-vue-info';
import VueCookieConsent from './VueCookieConsent.vue';

const story = (storiesOf('VueCookieConsent', module) as any);

story.addDecorator(VueInfoAddon);

story.add('Default', () => ({
components: { VueCookieConsent },
template: `<vue-cookie-consent current-version="1.0.0" cookie-consent-version="" :set-cookie-consent-version="action">
VueCookieConsent
</vue-cookie-consent>`,
methods: {
action: action('@onClick'),
},
}));

0 comments on commit a30fad4

Please sign in to comment.