Skip to content

Commit

Permalink
Abstract CookieEventHandler, add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ahosgood committed Nov 16, 2023
1 parent e520e58 commit 7252b5d
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 82 deletions.
1 change: 0 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export const decorators = [
};
const cookies = new Cookies();
cookies.deleteAll();
cookies.destroy();
return Story();
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ Existing.decorators = [
(Story) => {
const cookies = new Cookies();
cookies.set("cookie_preferences_set", true);
cookies.destroy();
return Story();
},
];
Expand Down
101 changes: 57 additions & 44 deletions src/nationalarchives/lib/cookies.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
export class CookieEventHandler {
events = {};

constructor() {
if (CookieEventHandler._instance) {
return CookieEventHandler._instance;
}
CookieEventHandler._instance = this;
}

/**
* Add an event listener.
* @param {string} event - The event to add a listener for.
* @param {function} callback - The callback function to call when the event is triggered.
*/
on(event, callback) {
if (!Object.prototype.hasOwnProperty.call(this.events, event)) {
this.events[event] = [];
}
this.events[event] = [...this.events[event], callback];
}

/** @protected */
trigger(event, data = {}) {
if (Object.prototype.hasOwnProperty.call(this.events, event)) {
this.events[event].forEach((eventToTrigger) =>
eventToTrigger.call(this, data),
);
}
}
}

/**
* Class to handle cookies.
* @class Cookies
Expand All @@ -12,8 +44,6 @@ export default class Cookies {
/** @protected */
secure = true;
/** @protected */
events = {};
/** @protected */
policiesKey = "";

/**
Expand All @@ -29,15 +59,11 @@ export default class Cookies {
secure = true,
policiesKey = "cookies_policy",
} = options;
if (Cookies._instance && Cookies._instance.policiesKey === policiesKey) {
return Cookies._instance;
}
Cookies._instance = this;
this.extraPolicies = extraPolicies;
this.domain = domain;
this.secure = secure;
this.events = {};
this.policiesKey = policiesKey;
this.events = new CookieEventHandler();
this.init();
}

Expand All @@ -54,15 +80,10 @@ export default class Cookies {
});
}

destroy() {
Cookies._instance = null;
this.trigger("destroy");
}

get all() {
const deserialised = {};
document.cookie
.split(";")
.split("; ")
.filter((x) => x)
.forEach((cookie) => {
const parts = cookie.trim().split("=");
Expand All @@ -74,7 +95,11 @@ export default class Cookies {
}

get policies() {
return JSON.parse(this.get(this.policiesKey) || "{}");
try {
return JSON.parse(this.get(this.policiesKey) || "{}");
} catch (e) {
return {};
}
}

/**
Expand Down Expand Up @@ -128,12 +153,12 @@ export default class Cookies {
return;
}
const cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)};${
domain ? ` domain=${domain};` : ""
domain ? ` domain=${domain}; ` : ""
} samesite=${sameSite}; path=${path}; max-age=${maxAge}${
secure ? "; secure" : ""
}`;
document.cookie = cookie;
this.trigger("setCookie", {
this.events.trigger("setCookie", {
key,
value,
maxAge,
Expand All @@ -153,17 +178,17 @@ export default class Cookies {
delete(key, path = "/", domain = null) {
const options = { maxAge: -1, path, domain: domain || undefined };
this.set(key, "", options);
this.trigger("deleteCookie", { key, ...options });
this.events.trigger("deleteCookie", { key, ...options });
}

/**
* Delete all cookies.
*/
deleteAll(path = "/", domain = null) {
Object.keys(this.all).forEach((cookie) =>
this.delete(cookie, path, domain),
);
this.trigger("deleteAllCookies", { path, domain });
Object.keys(this.all).forEach((cookie) => {
this.delete(cookie, path, domain);
});
this.events.trigger("deleteAllCookies", { path, domain });
}

/**
Expand All @@ -172,8 +197,8 @@ export default class Cookies {
*/
acceptPolicy(policy) {
this.setPolicy(policy, true);
this.trigger("acceptPolicy", policy);
this.trigger("changePolicy", { [policy]: true });
this.events.trigger("acceptPolicy", policy);
this.events.trigger("changePolicy", { [policy]: true });
}

/**
Expand All @@ -182,8 +207,8 @@ export default class Cookies {
*/
rejectPolicy(policy) {
this.setPolicy(policy, false);
this.trigger("rejectPolicy", policy);
this.trigger("changePolicy", { [policy]: false });
this.events.trigger("rejectPolicy", policy);
this.events.trigger("changePolicy", { [policy]: false });
}

/**
Expand All @@ -200,7 +225,7 @@ export default class Cookies {
[policy]: accepted,
essential: true,
});
this.trigger("changePolicy", { [policy]: accepted });
this.events.trigger("changePolicy", { [policy]: accepted });
}

/**
Expand All @@ -211,8 +236,8 @@ export default class Cookies {
Object.keys(this.policies).map((k) => [k.toLowerCase(), true]),
);
this.savePolicies(allPolicies);
this.trigger("acceptAllPolicies");
this.trigger("changePolicy", allPolicies);
this.events.trigger("acceptAllPolicies");
this.events.trigger("changePolicy", allPolicies);
}

/**
Expand All @@ -226,8 +251,8 @@ export default class Cookies {
essential: true,
};
this.savePolicies(allPolicies);
this.trigger("rejectAllPolicies");
this.trigger("changePolicy", allPolicies);
this.events.trigger("rejectAllPolicies");
this.events.trigger("changePolicy", allPolicies);
}

/**
Expand All @@ -250,23 +275,11 @@ export default class Cookies {
}

/**
* Accept a policy.
* Add an event listener.
* @param {string} event - The event to add a listener for.
* @param {function} callback - The callback function to call when the event is triggered.
*/
on(event, callback) {
if (!Object.prototype.hasOwnProperty.call(this.events, event)) {
this.events[event] = [];
}
this.events[event] = [...this.events[event], callback];
}

/** @protected */
trigger(event, data = {}) {
if (Object.prototype.hasOwnProperty.call(this.events, event)) {
this.events[event].forEach((eventToTrigger) =>
eventToTrigger.call(this, data),
);
}
this.events.on(event, callback);
}
}
Loading

0 comments on commit 7252b5d

Please sign in to comment.