Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

#23: Cookie expiration date (closes #23) #24

Merged
merged 7 commits into from
Oct 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"test": "./node_modules/karma/bin/karma start",
"build": "rm -rf lib && mkdir lib && babel --loose --stage 0 --out-dir lib src",
"lint": "eslint src",
"lint": "eslint src test",
"preversion": "npm run lint && npm run test && npm run build-examples",
"prepublish": "npm run build",
"build-examples": "npm run clean && webpack --config examples/webpack.config.build.js --progress",
Expand Down
36 changes: 33 additions & 3 deletions src/CookieBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@ import omit from 'lodash.omit';
import { t, props } from 'tcomb-react';
import { cookie as cookieLite } from 'browser-cookie-lite';
import styleUtils from './styleUtils';
t.interface.strict = true;

const Props = {
children: t.maybe(t.ReactChildren),
message: t.maybe(t.String),
onAccept: t.maybe(t.Function),
link: t.maybe(t.struct({
link: t.maybe(t.interface({
msg: t.maybe(t.String),
url: t.String,
target: t.maybe(t.enums.of(['_blank', '_self', '_parent', '_top', 'framename']))
})),
buttonMessage: t.maybe(t.String),
cookie: t.maybe(t.String),
cookieExpiration: t.maybe(t.union([
t.Integer,
t.interface({
years: t.maybe(t.Number),
days: t.maybe(t.Number),
hours: t.maybe(t.Number)
})
])),
dismissOnScroll: t.maybe(t.Boolean),
dismissOnScrollThreshold: t.maybe(t.Number),
closeIcon: t.maybe(t.String),
Expand Down Expand Up @@ -45,6 +54,7 @@ export default class CookieBanner extends React.Component {
onAccept: () => {},
dismissOnScroll: true,
cookie: 'accepts-cookies',
cookieExpiration: { years: 1 },
buttonMessage: 'Got it',
dismissOnScrollThreshold: 0,
styles: {}
Expand Down Expand Up @@ -88,9 +98,29 @@ export default class CookieBanner extends React.Component {
}
}

getSecondsSinceExpiration = cookieExpiration => {
if (t.Integer.is(cookieExpiration)) {
return cookieExpiration;
}

const SECONDS_IN_YEAR = 31536000;
const SECONDS_IN_DAY = 86400;
const SECONDS_IN_HOUR = 3600;

const _cookieExpiration = {
years: 0, days: 0, hours: 0,
...cookieExpiration
};

const { years, days, hours } = _cookieExpiration;

return (years * SECONDS_IN_YEAR) + (days * SECONDS_IN_DAY) + (hours * SECONDS_IN_HOUR);
}

onAccept = () => {
const { cookie, onAccept } = this.props;
cookieLite(cookie, true, 60*60*24*365);
const { cookie, cookieExpiration, onAccept } = this.props;

cookieLite(cookie, true, this.getSecondsSinceExpiration(cookieExpiration));
onAccept({ cookie });

if (this.state.listeningScroll) {
Expand Down
46 changes: 33 additions & 13 deletions test/tests/CookieBanner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ import expect from 'expect';
import CookieBanner from '../../src/CookieBanner';

const resetCookies = function () {
const cookies = document.cookie.split(";");
const cookies = document.cookie.split(';');

for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i];
const eqPos = cookie.indexOf("=");
const eqPos = cookie.indexOf('=');
const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT`;
}
};

const renderBanner = (props) => {
const component =
const component = (
<div>
<CookieBanner message='cookie message' {...props} />
</div>;
</div>
);
const cookieWrapper = TestUtils.renderIntoDocument(component);

return {
Expand All @@ -29,14 +30,32 @@ const renderBanner = (props) => {

beforeEach(resetCookies);

describe('CookieBanner', function() {
describe('secondsSinceExpiration', () => {
const { getSecondsSinceExpiration } = new CookieBanner();

it('should be displayed if no cookies are set', function() {
it('should return "cookieExpiration" if it is an integer', () => {
expect(getSecondsSinceExpiration(12345)).toBe(12345);
});

it('should transform "years", "days" and "hours" into seconds', () => {
expect(getSecondsSinceExpiration({ years: 1, days: 10, hours: 5 })).toBe(32418000);
});

it('should handle missing "years", "days" or "hours"', () => {
expect(getSecondsSinceExpiration({ days: 10 })).toBe(864000);
expect(getSecondsSinceExpiration({})).toBe(0);
});

});

describe('CookieBanner', () => {

it('should be displayed if no cookies are set', () => {
const banner = renderBanner().banner;
expect(banner.length).toBe(1, 'cookie banner is not displayed');
});

it('should hide on click', function() {
it('should hide on click', () => {
const banner = renderBanner().banner[0];
const closeButton = TestUtils.findRenderedDOMComponentWithClass(banner, 'button-close');
TestUtils.Simulate.click(closeButton);
Expand All @@ -46,7 +65,7 @@ describe('CookieBanner', function() {
expect(cookieBanner2.length).toBe(0, 'cookie banner is displayed');
});

it('should hide on click when dismissOnScroll is false', function() {
it('should hide on click when dismissOnScroll is false', () => {
const { banner, wrapper } = renderBanner({ dismissOnScroll: false });
const closeButton = TestUtils.findRenderedDOMComponentWithClass(banner[0], 'button-close');
TestUtils.Simulate.click(closeButton);
Expand All @@ -55,7 +74,7 @@ describe('CookieBanner', function() {
expect(cookieBanners.length).toBe(0, 'cookie banner is displayed');
});

it('should be displayed with correct message', function() {
it('should be displayed with correct message', () => {
const cookieWrapper = TestUtils.renderIntoDocument(
<div>
<CookieBanner message='cookie message' />
Expand All @@ -67,20 +86,21 @@ describe('CookieBanner', function() {
expect(message.innerHTML).toBe('cookie message', 'wrong message displayed');
});

it('should be replaced with custom child component', function() {
it('should be replaced with custom child component', () => {

const MyComponent = React.createClass({
render() {
return <div className='my-component'/>;
}
});

const component =
const component = (
<div>
<CookieBanner>
<MyComponent />
</CookieBanner>
</div>;
</div>
);

const cookieWrapper = TestUtils.renderIntoDocument(component);

Expand Down