@nationalarchives/frontend 0.1.23-prerelease → 0.1.25-prerelease
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/govuk-prototype-kit.config.json +4 -12
- package/nationalarchives/all.css +2 -2
- package/nationalarchives/all.css.map +1 -1
- package/nationalarchives/all.js +1 -1
- package/nationalarchives/all.js.map +1 -1
- package/nationalarchives/assets/fonts/OpenSans-Regular.ttf +0 -0
- package/nationalarchives/assets/fonts/RobotoMono-Medium.ttf +0 -0
- package/nationalarchives/components/_index.scss +1 -1
- package/nationalarchives/components/breadcrumbs/breadcrumbs.css +1 -1
- package/nationalarchives/components/breadcrumbs/breadcrumbs.css.map +1 -1
- package/nationalarchives/components/breadcrumbs/breadcrumbs.stories.js +1 -1
- package/nationalarchives/components/button/button.css +1 -1
- package/nationalarchives/components/button/button.css.map +1 -1
- package/nationalarchives/components/button/button.scss +12 -12
- package/nationalarchives/components/button/template.njk +2 -2
- package/nationalarchives/components/card/card.css +1 -1
- package/nationalarchives/components/card/card.css.map +1 -1
- package/nationalarchives/components/card/card.scss +9 -4
- package/nationalarchives/components/card/card.stories.js +27 -78
- package/nationalarchives/components/card/fixtures.json +17 -17
- package/nationalarchives/components/card/macro-options.json +47 -17
- package/nationalarchives/components/card/template.njk +47 -46
- package/nationalarchives/components/cookie-banner/cookie-banner.css +1 -1
- package/nationalarchives/components/cookie-banner/cookie-banner.css.map +1 -1
- package/nationalarchives/components/cookie-banner/cookie-banner.js +1 -1
- package/nationalarchives/components/cookie-banner/cookie-banner.js.map +1 -1
- package/nationalarchives/components/cookie-banner/cookie-banner.mjs +17 -16
- package/nationalarchives/components/cookie-banner/cookie-banner.scss +1 -1
- package/nationalarchives/components/cookie-banner/cookie-banner.stories.js +95 -45
- package/nationalarchives/components/cookie-banner/fixtures.json +84 -1
- package/nationalarchives/components/cookie-banner/macro-options.json +7 -1
- package/nationalarchives/components/cookie-banner/template.njk +4 -4
- package/nationalarchives/components/featured-records/_index.scss +1 -0
- package/nationalarchives/components/featured-records/featured-records.css +1 -0
- package/nationalarchives/components/featured-records/featured-records.css.map +1 -0
- package/nationalarchives/components/featured-records/featured-records.scss +95 -0
- package/nationalarchives/components/featured-records/featured-records.stories.js +51 -0
- package/nationalarchives/components/featured-records/fixtures.json +4 -0
- package/nationalarchives/components/featured-records/macro-options.json +70 -0
- package/nationalarchives/components/featured-records/macro.njk +3 -0
- package/nationalarchives/components/featured-records/template.njk +20 -0
- package/nationalarchives/components/filters/filters.css +1 -1
- package/nationalarchives/components/filters/filters.css.map +1 -1
- package/nationalarchives/components/filters/filters.scss +6 -6
- package/nationalarchives/components/filters/template.njk +1 -1
- package/nationalarchives/components/footer/footer.css +1 -1
- package/nationalarchives/components/footer/footer.css.map +1 -1
- package/nationalarchives/components/footer/footer.scss +2 -5
- package/nationalarchives/components/footer/footer.stories.js +1 -1
- package/nationalarchives/components/footer/template.njk +4 -4
- package/nationalarchives/components/gallery/gallery.css +1 -1
- package/nationalarchives/components/gallery/gallery.css.map +1 -1
- package/nationalarchives/components/gallery/gallery.scss +2 -2
- package/nationalarchives/components/gallery/gallery.stories.js +2 -2
- package/nationalarchives/components/grid/grid.css +1 -1
- package/nationalarchives/components/grid/grid.css.map +1 -1
- package/nationalarchives/components/grid/grid.scss +12 -0
- package/nationalarchives/components/grid/grid.stories.js +12 -0
- package/nationalarchives/components/header/header.css +1 -1
- package/nationalarchives/components/header/header.css.map +1 -1
- package/nationalarchives/components/header/header.scss +59 -27
- package/nationalarchives/components/header/header.stories.js +4 -6
- package/nationalarchives/components/header/macro-options.json +2 -2
- package/nationalarchives/components/header/template.njk +4 -4
- package/nationalarchives/components/hero/hero.css +1 -1
- package/nationalarchives/components/hero/hero.css.map +1 -1
- package/nationalarchives/components/hero/hero.scss +6 -6
- package/nationalarchives/components/hero/hero.stories.js +6 -0
- package/nationalarchives/components/index-grid/index-grid.css +1 -1
- package/nationalarchives/components/index-grid/index-grid.css.map +1 -1
- package/nationalarchives/components/index-grid/index-grid.scss +1 -1
- package/nationalarchives/components/index-grid/index-grid.stories.js +3 -1
- package/nationalarchives/components/message/message.css +1 -1
- package/nationalarchives/components/message/message.css.map +1 -1
- package/nationalarchives/components/pagination/macro-options.json +6 -0
- package/nationalarchives/components/pagination/pagination.css +1 -1
- package/nationalarchives/components/pagination/pagination.css.map +1 -1
- package/nationalarchives/components/pagination/pagination.scss +5 -1
- package/nationalarchives/components/pagination/pagination.stories.js +417 -2
- package/nationalarchives/components/pagination/template.njk +10 -3
- package/nationalarchives/components/phase-banner/fixtures.json +5 -41
- package/nationalarchives/components/phase-banner/macro-options.json +6 -0
- package/nationalarchives/components/phase-banner/phase-banner.css +1 -1
- package/nationalarchives/components/phase-banner/phase-banner.css.map +1 -1
- package/nationalarchives/components/phase-banner/phase-banner.scss +1 -1
- package/nationalarchives/components/phase-banner/phase-banner.stories.js +4 -28
- package/nationalarchives/components/phase-banner/template.njk +3 -1
- package/nationalarchives/components/picture/picture.css +1 -1
- package/nationalarchives/components/picture/picture.css.map +1 -1
- package/nationalarchives/components/picture/picture.scss +5 -4
- package/nationalarchives/components/sensitive-image/sensitive-image.css +1 -1
- package/nationalarchives/components/sensitive-image/sensitive-image.css.map +1 -1
- package/nationalarchives/components/sensitive-image/sensitive-image.stories.js +3 -0
- package/nationalarchives/components/skip-link/skip-link.css +1 -1
- package/nationalarchives/components/skip-link/skip-link.css.map +1 -1
- package/nationalarchives/components/skip-link/skip-link.stories.js +4 -1
- package/nationalarchives/components/tabs/tabs.css +1 -1
- package/nationalarchives/components/tabs/tabs.css.map +1 -1
- package/nationalarchives/components/tabs/tabs.js +1 -1
- package/nationalarchives/components/tabs/tabs.js.map +1 -1
- package/nationalarchives/components/tabs/tabs.mjs +0 -4
- package/nationalarchives/components/tabs/tabs.stories.js +6 -3
- package/nationalarchives/lib/cookies.mjs +165 -62
- package/nationalarchives/prototype-kit.css +23 -0
- package/nationalarchives/prototype-kit.css.map +1 -0
- package/nationalarchives/{_prototype-kit.scss → prototype-kit.scss} +3 -3
- package/nationalarchives/stories/utilities/colour-schemes/colour-schemes.stories.js +189 -74
- package/nationalarchives/stories/utilities/lists/lists.mdx +18 -0
- package/nationalarchives/stories/utilities/{typography → lists}/lists.stories.js +1 -1
- package/nationalarchives/stories/utilities/overrides/overrides.mdx +27 -20
- package/nationalarchives/stories/utilities/overrides/overrides.stories.js +19 -2
- package/nationalarchives/stories/utilities/tables/tables.mdx +8 -0
- package/nationalarchives/stories/utilities/tables/tables.stories.js +45 -0
- package/nationalarchives/stories/utilities/typography/heading-groups.stories.js +59 -19
- package/nationalarchives/stories/utilities/typography/typography.mdx +3 -25
- package/nationalarchives/stories/utilities/typography/typography.stories.js +28 -2
- package/nationalarchives/templates/layouts/_generic.njk +1 -0
- package/nationalarchives/templates/layouts/_prototype-kit.njk +4 -1
- package/nationalarchives/tests/cookies.test.js +427 -0
- package/nationalarchives/tests/uuid.test.js +17 -0
- package/nationalarchives/tools/_colour.scss +15 -20
- package/nationalarchives/tools/_spacing.scss +91 -2
- package/nationalarchives/tools/_typography.scss +15 -8
- package/nationalarchives/utilities/_a11y.scss +2 -1
- package/nationalarchives/utilities/_colour.scss +100 -0
- package/nationalarchives/utilities/_global.scss +2 -98
- package/nationalarchives/utilities/_index.scss +2 -0
- package/nationalarchives/utilities/_lists.scss +5 -0
- package/nationalarchives/utilities/_overrides.scss +16 -36
- package/nationalarchives/utilities/_tables.scss +86 -0
- package/nationalarchives/utilities/_typography.scss +150 -71
- package/nationalarchives/variables/_colour.scss +10 -8
- package/nationalarchives/variables/_spacing.scss +14 -9
- package/nationalarchives/variables/_typography.scss +10 -7
- package/package.json +14 -14
- package/nationalarchives/assets/fonts/OpenSans-Medium.ttf +0 -0
- package/nationalarchives/assets/fonts/fa-regular-400.ttf +0 -0
- package/nationalarchives/assets/fonts/fa-regular-400.woff2 +0 -0
- package/nationalarchives/components/profile/_index.scss +0 -1
- package/nationalarchives/components/profile/fixtures.json +0 -4
- package/nationalarchives/components/profile/macro-options.json +0 -14
- package/nationalarchives/components/profile/macro.njk +0 -3
- package/nationalarchives/components/profile/profile.css +0 -1
- package/nationalarchives/components/profile/profile.css.map +0 -1
- package/nationalarchives/components/profile/profile.scss +0 -5
- package/nationalarchives/components/profile/profile.stories.js +0 -31
- package/nationalarchives/components/profile/template.njk +0 -15
- package/nationalarchives/lib/font-awesome/regular.css +0 -5
- package/nationalarchives/lib/font-awesome/regular.css.map +0 -1
- package/nationalarchives/lib/font-awesome/regular.scss +0 -28
- package/nationalarchives/stories/development/about.mdx +0 -122
- package/nationalarchives/stories/development/contributing.mdx +0 -32
- package/nationalarchives/stories/development/cookies.mdx +0 -82
- package/nationalarchives/stories/development/publishing.mdx +0 -15
- package/nationalarchives/stories/development/structure.mdx +0 -88
- package/nationalarchives/stories/development/using/compiled.mdx +0 -9
- package/nationalarchives/stories/development/using/hosted.mdx +0 -53
- package/nationalarchives/stories/development/using/npm.mdx +0 -59
@@ -3,7 +3,7 @@ const argTypes = {
|
|
3
3
|
title: { control: "text" },
|
4
4
|
level: { control: "number", min: 1, max: 6, step: 1 },
|
5
5
|
size: { control: "radio", options: ["m", "l", "xl"] },
|
6
|
-
|
6
|
+
plainSupertitle: { control: "boolean" },
|
7
7
|
};
|
8
8
|
|
9
9
|
export default {
|
@@ -11,35 +11,75 @@ export default {
|
|
11
11
|
argTypes,
|
12
12
|
};
|
13
13
|
|
14
|
-
const
|
14
|
+
const HeadingGroupTemplate = ({
|
15
15
|
supertitle,
|
16
16
|
title,
|
17
|
-
level
|
18
|
-
size
|
19
|
-
|
17
|
+
level,
|
18
|
+
size,
|
19
|
+
plainSupertitle,
|
20
20
|
}) =>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
<span class="tna-hgroup__title">${title}</span>
|
26
|
-
</h${level}>
|
27
|
-
</hgroup>`
|
28
|
-
: `<hgroup class="tna-hgroup-${size}">
|
29
|
-
<p class="tna-hgroup__supertitle">${supertitle}</p>
|
21
|
+
`<hgroup class="tna-hgroup-${size}">
|
22
|
+
<p class="tna-hgroup__supertitle${
|
23
|
+
plainSupertitle ? " tna-hgroup__supertitle--plain" : ""
|
24
|
+
}">${supertitle}</p>
|
30
25
|
<h${level} class="tna-hgroup__title">${title}</h${level}>
|
31
26
|
</hgroup>`;
|
32
27
|
|
33
|
-
export const HeadingGroup =
|
28
|
+
export const HeadingGroup = HeadingGroupTemplate.bind({});
|
34
29
|
HeadingGroup.args = {
|
30
|
+
supertitle: "Record revealed",
|
31
|
+
title: "The Monteagle Letter",
|
32
|
+
level: 3,
|
33
|
+
size: "l",
|
34
|
+
plainSupertitle: false,
|
35
|
+
};
|
36
|
+
|
37
|
+
const HeadingGroupSingleSentenceTemplate = ({
|
38
|
+
supertitle,
|
39
|
+
title,
|
40
|
+
level,
|
41
|
+
size,
|
42
|
+
plainSupertitle,
|
43
|
+
}) =>
|
44
|
+
`<hgroup class="tna-hgroup-${size}">
|
45
|
+
<h${level} class="tna-hgroup__title">
|
46
|
+
<span class="tna-hgroup__supertitle${
|
47
|
+
plainSupertitle ? " tna-hgroup__supertitle--plain" : ""
|
48
|
+
}">${supertitle}</span>
|
49
|
+
<span class="tna-hgroup__title">${title}</span>
|
50
|
+
</h${level}>
|
51
|
+
</hgroup>`;
|
52
|
+
|
53
|
+
export const HeadingGroupSingleSentence =
|
54
|
+
HeadingGroupSingleSentenceTemplate.bind({});
|
55
|
+
HeadingGroupSingleSentence.args = {
|
35
56
|
supertitle: "The story of",
|
36
57
|
title: "Alice Hawkins",
|
37
|
-
|
58
|
+
level: 3,
|
59
|
+
size: "l",
|
60
|
+
plainSupertitle: false,
|
38
61
|
};
|
39
62
|
|
40
|
-
|
41
|
-
|
63
|
+
const HeadingGroupPlainSupertitleTemplate = ({
|
64
|
+
supertitle,
|
65
|
+
title,
|
66
|
+
level,
|
67
|
+
size,
|
68
|
+
plainSupertitle,
|
69
|
+
}) =>
|
70
|
+
`<hgroup class="tna-hgroup-${size}">
|
71
|
+
<p class="tna-hgroup__supertitle${
|
72
|
+
plainSupertitle ? " tna-hgroup__supertitle--plain" : ""
|
73
|
+
}">${supertitle}</p>
|
74
|
+
<h${level} class="tna-hgroup__title">${title}</h${level}>
|
75
|
+
</hgroup>`;
|
76
|
+
|
77
|
+
export const HeadingGroupPlainSupertitle =
|
78
|
+
HeadingGroupPlainSupertitleTemplate.bind({});
|
79
|
+
HeadingGroupPlainSupertitle.args = {
|
42
80
|
supertitle: "Record revealed",
|
43
81
|
title: "The Monteagle Letter",
|
44
|
-
|
82
|
+
level: 3,
|
83
|
+
size: "l",
|
84
|
+
plainSupertitle: true,
|
45
85
|
};
|
@@ -2,14 +2,11 @@ import { Meta, Canvas } from "@storybook/blocks";
|
|
2
2
|
import * as HeadingStories from './headings.stories';
|
3
3
|
import * as HeadingGroupStories from './heading-groups.stories';
|
4
4
|
import * as TypographyStories from './typography.stories';
|
5
|
-
import * as ListStories from './lists.stories';
|
6
5
|
|
7
6
|
<Meta of={TypographyStories} />
|
8
7
|
|
9
8
|
# Typography
|
10
9
|
|
11
|
-
We use a set of typefaces...
|
12
|
-
|
13
10
|
## Headings
|
14
11
|
|
15
12
|
<Canvas of={HeadingStories.Headings} />
|
@@ -17,32 +14,13 @@ We use a set of typefaces...
|
|
17
14
|
|
18
15
|
## Heading groups
|
19
16
|
|
20
|
-
Although visually identical, there are two types of header groups based on whether the group should be read as a single sentence or not.
|
21
|
-
|
22
|
-
In the first example, the heading will be read by screen readers as `The story of Alice Hawkins.`
|
23
|
-
|
24
17
|
<Canvas of={HeadingGroupStories.HeadingGroup} />
|
25
|
-
|
26
|
-
In the second example, the heading will be read as two separate sentences; `Record revealed. The Monteagle Letter.`
|
27
|
-
|
28
18
|
<Canvas of={HeadingGroupStories.HeadingGroupSeparated} />
|
29
19
|
|
30
20
|
## General typography
|
31
21
|
|
32
22
|
<Canvas of={TypographyStories.Paragraph} />
|
33
|
-
<Canvas of={TypographyStories.
|
23
|
+
<Canvas of={TypographyStories.LargeParagraph} />
|
34
24
|
<Canvas of={TypographyStories.SceneSetter} />
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
<Canvas of={ListStories.UnorderedList} />
|
39
|
-
<Canvas of={ListStories.OrderedList} />
|
40
|
-
<Canvas of={ListStories.DescriptionList} />
|
41
|
-
<Canvas of={ListStories.DescriptionListWithIcons} />
|
42
|
-
|
43
|
-
### Plain versions
|
44
|
-
|
45
|
-
<Canvas of={ListStories.UnorderedListPlain} />
|
46
|
-
<Canvas of={ListStories.OrderedListPlain} />
|
47
|
-
<Canvas of={ListStories.PlainDescriptionList} />
|
48
|
-
<Canvas of={ListStories.PlainDescriptionListWithIcons} />
|
25
|
+
<Canvas of={TypographyStories.SceneSetterSmall} />
|
26
|
+
<Canvas of={TypographyStories.Blockquote} />
|
@@ -18,17 +18,28 @@ Paragraph.args = {
|
|
18
18
|
],
|
19
19
|
};
|
20
20
|
|
21
|
+
const LargeParagraphTemplate = ({ paragraphs }) =>
|
22
|
+
paragraphs
|
23
|
+
.map((paragraph) => `<p class="tna-large-paragraph">${paragraph}</p>`)
|
24
|
+
.join("");
|
25
|
+
export const LargeParagraph = LargeParagraphTemplate.bind({});
|
26
|
+
LargeParagraph.args = {
|
27
|
+
paragraphs: [
|
28
|
+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel tincidunt velit, a molestie turpis. Sed odio libero, sodales eleifend lorem sit amet, feugiat consequat nibh. Donec ac tellus in dui rutrum maximus. Aliquam vel euismod eros. Integer ut magna velit. Fusce sed dui sit amet metus eleifend dictum quis vitae mi. Aenean sagittis euismod purus, in accumsan metus venenatis nec. Nullam nec velit felis. Sed nec felis eu nisl varius dictum eu quis nisl. Donec dapibus est arcu, vel pellentesque risus pellentesque eget.",
|
29
|
+
],
|
30
|
+
};
|
31
|
+
|
21
32
|
const HeadingLinkTemplate = ({ text, href }) =>
|
22
33
|
`<h2 class="tna-heading-s">
|
23
34
|
<a href="${href}">${text}</a>
|
24
35
|
</h2>`;
|
25
36
|
export const HeadingLink = HeadingLinkTemplate.bind({});
|
26
37
|
HeadingLink.args = {
|
27
|
-
text: "
|
38
|
+
text: "Researching with The National Archives",
|
28
39
|
href: "#",
|
29
40
|
};
|
30
41
|
|
31
|
-
const SceneSetterTemplate = ({ text
|
42
|
+
const SceneSetterTemplate = ({ text }) =>
|
32
43
|
`<p class="tna-scene-setter">
|
33
44
|
${text}
|
34
45
|
</p>`;
|
@@ -37,6 +48,21 @@ SceneSetter.args = {
|
|
37
48
|
text: `We are the official archive of England and Wales. Discover 1,000 years of history through <a href="#">fascinating stories</a> from the past or <a href="#">start your own research</a> and <a href="#">search our catalogue</a> of 32 million records. <a href="#">Plan a visit</a> to access original historic documents from our collections then enjoy the grounds, café, and <a href="#">free exhibitions</a>.`,
|
38
49
|
};
|
39
50
|
|
51
|
+
const SceneSetterSmallTemplate = ({ text }) =>
|
52
|
+
`<p class="tna-scene-setter tna-scene-setter--small">
|
53
|
+
${text}
|
54
|
+
</p>`;
|
55
|
+
export const SceneSetterSmall = SceneSetterSmallTemplate.bind({});
|
56
|
+
SceneSetterSmall.args = {
|
57
|
+
text: `We are the official archive of England and Wales. Discover 1,000 years of history through <a href="#">fascinating stories</a> from the past or <a href="#">start your own research</a> and <a href="#">search our catalogue</a> of 32 million records. <a href="#">Plan a visit</a> to access original historic documents from our collections then enjoy the grounds, café, and <a href="#">free exhibitions</a>.`,
|
58
|
+
};
|
59
|
+
|
60
|
+
// const TextDetailsTemplate = () =>
|
61
|
+
// `<p>
|
62
|
+
// Typed slip with photographs - 'The <span class="tna-detail" title="Italian (miscellaneous)" data-type="misc">Italian</span> Steamer <span class="tna-detail" title="Aida Lauro (person)" data-type="per">Aida Lauro</span> which ran on the rocks near <span class="tna-detail" title="Cape Cornwall (location)" data-type="loc">Cape Cornwall</span> a few days ago is now a total wreck. After a severe buffeting by heavy seas the ship has broken in two. The photograph shows the <span class="tna-detail" title="Aida Lauro (person)" data-type="per">Aida Lauro</span> broken in two by a severe buffeting from the seas near <a href="#" class="tna-detail" title="Cape Cornwall (location)" data-type="loc">Cape Cornwall</a>.
|
63
|
+
// </p>`;
|
64
|
+
// export const TextDetails = TextDetailsTemplate.bind({});
|
65
|
+
|
40
66
|
const BlockquoteTemplate = ({
|
41
67
|
html,
|
42
68
|
author,
|
@@ -25,6 +25,7 @@
|
|
25
25
|
|
26
26
|
{% block stylesheets %}
|
27
27
|
<link rel="stylesheet" type="text/css" href="{{ tnaFrontendCssPath | default('/static/tna-frontend') }}/all.css">
|
28
|
+
<link rel="stylesheet" type="text/css" href="https://use.typekit.net/hkj3kuz.css">
|
28
29
|
{% endblock %}
|
29
30
|
</head>
|
30
31
|
<body class="tna-template__body {{ bodyClasses }}" {%- for attribute, value in bodyAttributes %} {{attribute}}="{{value}}"{% endfor %}>
|
@@ -1,7 +1,10 @@
|
|
1
1
|
{% extends "./_generic.njk" %}
|
2
2
|
|
3
|
+
{% set assetPath = "/plugin-assets/%40nationalarchives%2Ffrontend/nationalarchives/assets" %}
|
4
|
+
|
3
5
|
{% block stylesheets %}
|
4
|
-
{% include "govuk-prototype-kit/includes/stylesheets-plugins.njk" %}
|
6
|
+
{% include "govuk-prototype-kit/includes/stylesheets-plugins.njk" %}
|
7
|
+
<link rel="stylesheet" type="text/css" href="https://use.typekit.net/hkj3kuz.css">
|
5
8
|
{% endblock %}
|
6
9
|
|
7
10
|
{% block bodyEnd %}
|
@@ -0,0 +1,427 @@
|
|
1
|
+
import {
|
2
|
+
jest,
|
3
|
+
describe,
|
4
|
+
expect,
|
5
|
+
test,
|
6
|
+
beforeEach,
|
7
|
+
afterEach,
|
8
|
+
} from "@jest/globals";
|
9
|
+
import { TextEncoder, TextDecoder, store, options } from "util";
|
10
|
+
import Cookies from "../lib/cookies.mjs";
|
11
|
+
|
12
|
+
global.TextEncoder = TextEncoder;
|
13
|
+
global.TextDecoder = TextDecoder;
|
14
|
+
global.store = store;
|
15
|
+
global.options = options;
|
16
|
+
|
17
|
+
const addCookiesToDocument = (document) => {
|
18
|
+
let _cookies = {};
|
19
|
+
document.__defineGetter__("cookie", () => {
|
20
|
+
return Object.keys(_cookies)
|
21
|
+
.map((key) => `${key}=${_cookies[key]}`)
|
22
|
+
.join("; ");
|
23
|
+
});
|
24
|
+
document.__defineSetter__("cookie", (s) => {
|
25
|
+
const keyValue = s.trim().split("=");
|
26
|
+
const key = keyValue[0].trim();
|
27
|
+
const values = keyValue[1].trim().split(";");
|
28
|
+
const value = values[0];
|
29
|
+
_cookies[key] = value;
|
30
|
+
return `${key}=${value}`;
|
31
|
+
});
|
32
|
+
document.clearAllCookies = () => {
|
33
|
+
_cookies = {};
|
34
|
+
};
|
35
|
+
};
|
36
|
+
|
37
|
+
addCookiesToDocument(document);
|
38
|
+
|
39
|
+
describe("No existing cookies", () => {
|
40
|
+
afterEach(() => {
|
41
|
+
document.clearAllCookies();
|
42
|
+
});
|
43
|
+
|
44
|
+
test("Initialisation", async () => {
|
45
|
+
expect(document.cookie).toEqual("");
|
46
|
+
|
47
|
+
const cookies = new Cookies();
|
48
|
+
expect(cookies).toHaveProperty("all");
|
49
|
+
expect(cookies).toBeInstanceOf(Cookies);
|
50
|
+
|
51
|
+
expect(document.cookie).not.toEqual("");
|
52
|
+
});
|
53
|
+
|
54
|
+
test("Getting/setting", async () => {
|
55
|
+
const cookies = new Cookies();
|
56
|
+
expect(cookies).toHaveProperty("get");
|
57
|
+
expect(cookies).toHaveProperty("set");
|
58
|
+
expect(cookies).toHaveProperty("exists");
|
59
|
+
expect(cookies).toHaveProperty("hasValue");
|
60
|
+
|
61
|
+
expect(Object.keys(cookies.all)).toHaveLength(1);
|
62
|
+
|
63
|
+
const testKey = "foo";
|
64
|
+
const testValue = "bar";
|
65
|
+
|
66
|
+
expect(cookies.all).not.toHaveProperty(testKey);
|
67
|
+
expect(cookies.exists(testKey)).toEqual(false);
|
68
|
+
|
69
|
+
cookies.set(testKey, testValue);
|
70
|
+
|
71
|
+
expect(Object.keys(cookies.all)).toHaveLength(2);
|
72
|
+
|
73
|
+
expect(cookies.all).toHaveProperty(testKey);
|
74
|
+
expect(cookies.all[testKey]).toEqual(testValue);
|
75
|
+
expect(cookies.exists(testKey)).toEqual(true);
|
76
|
+
expect(cookies.get(testKey)).toEqual(testValue);
|
77
|
+
expect(cookies.hasValue(testKey, testValue)).toEqual(true);
|
78
|
+
expect(cookies.hasValue(testKey, "different")).toEqual(false);
|
79
|
+
});
|
80
|
+
|
81
|
+
test("Deletion", async () => {
|
82
|
+
const cookies = new Cookies();
|
83
|
+
expect(cookies).toHaveProperty("delete");
|
84
|
+
|
85
|
+
const testKey = "foo";
|
86
|
+
const testValue = "bar";
|
87
|
+
|
88
|
+
cookies.set(testKey, testValue);
|
89
|
+
|
90
|
+
expect(cookies.all).toHaveProperty(testKey);
|
91
|
+
expect(cookies.all[testKey]).toEqual(testValue);
|
92
|
+
expect(cookies.exists(testKey)).toEqual(true);
|
93
|
+
expect(cookies.get(testKey)).toEqual(testValue);
|
94
|
+
|
95
|
+
cookies.delete(testKey);
|
96
|
+
|
97
|
+
// expect(cookies.all).not.toHaveProperty(testKey);
|
98
|
+
// expect(cookies.exists(testKey)).toEqual(false);
|
99
|
+
expect(cookies.get(testKey)).toEqual("");
|
100
|
+
});
|
101
|
+
|
102
|
+
test("Deletion of all", async () => {
|
103
|
+
const cookies = new Cookies();
|
104
|
+
|
105
|
+
const testKeys = ["foo", "bar"];
|
106
|
+
const testValue = "testValue";
|
107
|
+
|
108
|
+
testKeys.forEach((testKey) => cookies.set(testKey, testValue));
|
109
|
+
|
110
|
+
testKeys.forEach((testKey) => {
|
111
|
+
expect(cookies.get(testKey)).toEqual(testValue);
|
112
|
+
});
|
113
|
+
|
114
|
+
cookies.deleteAll();
|
115
|
+
|
116
|
+
testKeys.forEach((testKey) => {
|
117
|
+
expect(cookies.get(testKey)).toEqual("");
|
118
|
+
});
|
119
|
+
});
|
120
|
+
|
121
|
+
test("Initial policies", async () => {
|
122
|
+
const cookies = new Cookies();
|
123
|
+
expect(cookies).toHaveProperty("policies");
|
124
|
+
|
125
|
+
expect(cookies.policies).toHaveProperty("essential");
|
126
|
+
expect(cookies.policies.essential).toEqual(true);
|
127
|
+
expect(JSON.parse(cookies.get("cookies_policy"))).toHaveProperty(
|
128
|
+
"essential",
|
129
|
+
);
|
130
|
+
expect(cookies.policies).toHaveProperty("settings");
|
131
|
+
expect(cookies.policies.settings).toEqual(false);
|
132
|
+
expect(JSON.parse(cookies.get("cookies_policy"))).toHaveProperty(
|
133
|
+
"settings",
|
134
|
+
);
|
135
|
+
expect(cookies.policies).toHaveProperty("usage");
|
136
|
+
expect(cookies.policies.usage).toEqual(false);
|
137
|
+
expect(JSON.parse(cookies.get("cookies_policy"))).toHaveProperty("usage");
|
138
|
+
});
|
139
|
+
|
140
|
+
test("Accept policy", async () => {
|
141
|
+
const cookies = new Cookies();
|
142
|
+
expect(cookies).toHaveProperty("isPolicyAccepted");
|
143
|
+
|
144
|
+
expect(cookies.policies).toHaveProperty("essential");
|
145
|
+
expect(cookies.policies.essential).toEqual(true);
|
146
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
147
|
+
expect(cookies.policies).toHaveProperty("settings");
|
148
|
+
expect(cookies.policies.settings).toEqual(false);
|
149
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
150
|
+
expect(cookies.policies).toHaveProperty("usage");
|
151
|
+
expect(cookies.policies.usage).toEqual(false);
|
152
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
153
|
+
|
154
|
+
cookies.acceptPolicy("settings");
|
155
|
+
expect(cookies.policies.essential).toEqual(true);
|
156
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
157
|
+
expect(cookies.policies.settings).toEqual(true);
|
158
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
159
|
+
expect(cookies.policies.usage).toEqual(false);
|
160
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
161
|
+
|
162
|
+
cookies.acceptPolicy("usage");
|
163
|
+
expect(cookies.policies.essential).toEqual(true);
|
164
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
165
|
+
expect(cookies.policies.settings).toEqual(true);
|
166
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
167
|
+
expect(cookies.policies.usage).toEqual(true);
|
168
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
169
|
+
});
|
170
|
+
|
171
|
+
test("Accept all policies", async () => {
|
172
|
+
const cookies = new Cookies();
|
173
|
+
expect(cookies).toHaveProperty("acceptAllPolicies");
|
174
|
+
|
175
|
+
expect(cookies.policies).toHaveProperty("essential");
|
176
|
+
expect(cookies.policies.essential).toEqual(true);
|
177
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
178
|
+
expect(cookies.policies).toHaveProperty("settings");
|
179
|
+
expect(cookies.policies.settings).toEqual(false);
|
180
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
181
|
+
expect(cookies.policies).toHaveProperty("usage");
|
182
|
+
expect(cookies.policies.usage).toEqual(false);
|
183
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
184
|
+
|
185
|
+
cookies.acceptAllPolicies();
|
186
|
+
expect(cookies.policies.essential).toEqual(true);
|
187
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
188
|
+
expect(cookies.policies.settings).toEqual(true);
|
189
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
190
|
+
expect(cookies.policies.usage).toEqual(true);
|
191
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
192
|
+
});
|
193
|
+
|
194
|
+
test("Reject policy", async () => {
|
195
|
+
const cookies = new Cookies();
|
196
|
+
|
197
|
+
cookies.acceptPolicy("settings");
|
198
|
+
cookies.acceptPolicy("usage");
|
199
|
+
expect(cookies.policies.essential).toEqual(true);
|
200
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
201
|
+
expect(cookies.policies.settings).toEqual(true);
|
202
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
203
|
+
expect(cookies.policies.usage).toEqual(true);
|
204
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
205
|
+
|
206
|
+
cookies.rejectPolicy("settings");
|
207
|
+
expect(cookies.policies.essential).toEqual(true);
|
208
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
209
|
+
expect(cookies.policies.settings).toEqual(false);
|
210
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
211
|
+
expect(cookies.policies.usage).toEqual(true);
|
212
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
213
|
+
|
214
|
+
cookies.rejectPolicy("usage");
|
215
|
+
expect(cookies.policies.essential).toEqual(true);
|
216
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
217
|
+
expect(cookies.policies.settings).toEqual(false);
|
218
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
219
|
+
expect(cookies.policies.usage).toEqual(false);
|
220
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
221
|
+
});
|
222
|
+
|
223
|
+
test("Reject all policies", async () => {
|
224
|
+
const cookies = new Cookies();
|
225
|
+
expect(cookies).toHaveProperty("rejectAllPolicies");
|
226
|
+
|
227
|
+
cookies.acceptAllPolicies();
|
228
|
+
expect(cookies.policies.essential).toEqual(true);
|
229
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
230
|
+
expect(cookies.policies.settings).toEqual(true);
|
231
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
232
|
+
expect(cookies.policies.usage).toEqual(true);
|
233
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
234
|
+
|
235
|
+
cookies.rejectAllPolicies();
|
236
|
+
expect(cookies.policies.essential).toEqual(true);
|
237
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
238
|
+
expect(cookies.policies.settings).toEqual(false);
|
239
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
240
|
+
expect(cookies.policies.usage).toEqual(false);
|
241
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
242
|
+
});
|
243
|
+
|
244
|
+
test("Protected essential policy", async () => {
|
245
|
+
const cookies = new Cookies();
|
246
|
+
|
247
|
+
expect(cookies.policies).toHaveProperty("essential");
|
248
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
249
|
+
|
250
|
+
cookies.acceptPolicy("essential");
|
251
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
252
|
+
|
253
|
+
cookies.rejectPolicy("essential");
|
254
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
255
|
+
|
256
|
+
cookies.rejectAllPolicies();
|
257
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
258
|
+
});
|
259
|
+
|
260
|
+
test("Basic events", async () => {
|
261
|
+
const cookies = new Cookies();
|
262
|
+
expect(cookies).toHaveProperty("on");
|
263
|
+
|
264
|
+
const mockCallback = jest.fn();
|
265
|
+
cookies.on("setCookie", mockCallback);
|
266
|
+
const testKey = "foo";
|
267
|
+
const testValue = "bar";
|
268
|
+
|
269
|
+
cookies.set(testKey, testValue);
|
270
|
+
|
271
|
+
expect(mockCallback.mock.calls).toHaveLength(1);
|
272
|
+
expect(mockCallback.mock.calls[0][0]).toStrictEqual({
|
273
|
+
key: testKey,
|
274
|
+
value: testValue,
|
275
|
+
domain: "",
|
276
|
+
path: "/",
|
277
|
+
sameSite: "Lax",
|
278
|
+
secure: true,
|
279
|
+
maxAge: 31536000,
|
280
|
+
cookie: `${testKey}=${testValue}; samesite=Lax; path=/; max-age=31536000; secure`,
|
281
|
+
});
|
282
|
+
|
283
|
+
cookies.set(testKey, testValue);
|
284
|
+
|
285
|
+
expect(mockCallback.mock.calls).toHaveLength(2);
|
286
|
+
expect(mockCallback.mock.calls[1][0]).toStrictEqual({
|
287
|
+
key: testKey,
|
288
|
+
value: testValue,
|
289
|
+
domain: "",
|
290
|
+
path: "/",
|
291
|
+
sameSite: "Lax",
|
292
|
+
secure: true,
|
293
|
+
maxAge: 31536000,
|
294
|
+
cookie: `${testKey}=${testValue}; samesite=Lax; path=/; max-age=31536000; secure`,
|
295
|
+
});
|
296
|
+
});
|
297
|
+
|
298
|
+
test("All events", async () => {
|
299
|
+
const cookies = new Cookies();
|
300
|
+
|
301
|
+
const mockSetCookieCallback = jest.fn();
|
302
|
+
cookies.on("setCookie", mockSetCookieCallback);
|
303
|
+
const mockDeleteCookieCallback = jest.fn();
|
304
|
+
cookies.on("deleteCookie", mockDeleteCookieCallback);
|
305
|
+
const mockDeleteAllCookiesCallback = jest.fn();
|
306
|
+
cookies.on("deleteAllCookies", mockDeleteAllCookiesCallback);
|
307
|
+
const mockAcceptPolicyCallback = jest.fn();
|
308
|
+
cookies.on("acceptPolicy", mockAcceptPolicyCallback);
|
309
|
+
const mockRejectPolicyCallback = jest.fn();
|
310
|
+
cookies.on("rejectPolicy", mockRejectPolicyCallback);
|
311
|
+
const mockAcceptAllPoliciesCallback = jest.fn();
|
312
|
+
cookies.on("acceptAllPolicies", mockAcceptAllPoliciesCallback);
|
313
|
+
const mockRejectAllPoliciesCallback = jest.fn();
|
314
|
+
cookies.on("rejectAllPolicies", mockRejectAllPoliciesCallback);
|
315
|
+
const mockChangePolicyCallback = jest.fn();
|
316
|
+
cookies.on("changePolicy", mockChangePolicyCallback);
|
317
|
+
|
318
|
+
const testKey = "foo";
|
319
|
+
const testValue = "bar";
|
320
|
+
cookies.set(testKey, testValue);
|
321
|
+
cookies.delete(testKey);
|
322
|
+
cookies.acceptPolicy("settings");
|
323
|
+
cookies.rejectPolicy("settings");
|
324
|
+
cookies.setPolicy("settings", true);
|
325
|
+
cookies.acceptAllPolicies();
|
326
|
+
cookies.rejectAllPolicies();
|
327
|
+
cookies.deleteAll();
|
328
|
+
|
329
|
+
expect(mockSetCookieCallback.mock.calls).toHaveLength(9);
|
330
|
+
expect(mockDeleteCookieCallback.mock.calls).toHaveLength(3);
|
331
|
+
expect(mockDeleteAllCookiesCallback.mock.calls).toHaveLength(1);
|
332
|
+
expect(mockAcceptPolicyCallback.mock.calls).toHaveLength(1);
|
333
|
+
expect(mockRejectPolicyCallback.mock.calls).toHaveLength(1);
|
334
|
+
expect(mockAcceptAllPoliciesCallback.mock.calls).toHaveLength(1);
|
335
|
+
expect(mockRejectAllPoliciesCallback.mock.calls).toHaveLength(1);
|
336
|
+
expect(mockChangePolicyCallback.mock.calls).toHaveLength(7);
|
337
|
+
});
|
338
|
+
|
339
|
+
test("Shared events", async () => {
|
340
|
+
const mockCallback = jest.fn();
|
341
|
+
|
342
|
+
const cookies1 = new Cookies();
|
343
|
+
|
344
|
+
const cookies2 = new Cookies();
|
345
|
+
cookies2.on("setCookie", mockCallback);
|
346
|
+
|
347
|
+
const testKey = "foo";
|
348
|
+
const testValue = "bar";
|
349
|
+
|
350
|
+
cookies1.set(testKey, testValue);
|
351
|
+
expect(mockCallback.mock.calls).toHaveLength(1);
|
352
|
+
|
353
|
+
cookies1.set(testKey, testValue);
|
354
|
+
expect(mockCallback.mock.calls).toHaveLength(2);
|
355
|
+
|
356
|
+
cookies2.set(testKey, testValue);
|
357
|
+
expect(mockCallback.mock.calls).toHaveLength(3);
|
358
|
+
});
|
359
|
+
});
|
360
|
+
|
361
|
+
describe("Existing cookies", () => {
|
362
|
+
beforeEach(() => {
|
363
|
+
document.clearAllCookies();
|
364
|
+
document.cookie =
|
365
|
+
"cookies_policy=%7B%22usage%22%3Afalse%2C%22settings%22%3Atrue%2C%22essential%22%3Atrue%7D";
|
366
|
+
});
|
367
|
+
|
368
|
+
test("Initialisation", async () => {
|
369
|
+
const cookies = new Cookies();
|
370
|
+
|
371
|
+
expect(cookies.all).toHaveProperty("cookies_policy");
|
372
|
+
expect(cookies.policies).toHaveProperty("essential");
|
373
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
374
|
+
expect(cookies.policies).toHaveProperty("settings");
|
375
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(true);
|
376
|
+
expect(cookies.policies).toHaveProperty("usage");
|
377
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
378
|
+
});
|
379
|
+
|
380
|
+
test("Update policies", async () => {
|
381
|
+
const cookies = new Cookies();
|
382
|
+
cookies.acceptPolicy("usage");
|
383
|
+
cookies.rejectPolicy("settings");
|
384
|
+
|
385
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
386
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
387
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(true);
|
388
|
+
});
|
389
|
+
});
|
390
|
+
|
391
|
+
describe("Existing empty cookie policies", () => {
|
392
|
+
beforeEach(() => {
|
393
|
+
document.clearAllCookies();
|
394
|
+
document.cookie = "cookies_policy=%7B%7D";
|
395
|
+
});
|
396
|
+
|
397
|
+
test("Initialisation", async () => {
|
398
|
+
const cookies = new Cookies();
|
399
|
+
|
400
|
+
expect(cookies.all).toHaveProperty("cookies_policy");
|
401
|
+
expect(cookies.policies).toHaveProperty("essential");
|
402
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
403
|
+
expect(cookies.policies).toHaveProperty("settings");
|
404
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
405
|
+
expect(cookies.policies).toHaveProperty("usage");
|
406
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
407
|
+
});
|
408
|
+
});
|
409
|
+
|
410
|
+
describe("Existing malformed cookie policies", () => {
|
411
|
+
beforeEach(() => {
|
412
|
+
document.clearAllCookies();
|
413
|
+
document.cookie = "cookies_policy=foobar";
|
414
|
+
});
|
415
|
+
|
416
|
+
test("Initialisation", async () => {
|
417
|
+
const cookies = new Cookies();
|
418
|
+
|
419
|
+
expect(cookies.all).toHaveProperty("cookies_policy");
|
420
|
+
expect(cookies.policies).toHaveProperty("essential");
|
421
|
+
expect(cookies.isPolicyAccepted("essential")).toEqual(true);
|
422
|
+
expect(cookies.policies).toHaveProperty("settings");
|
423
|
+
expect(cookies.isPolicyAccepted("settings")).toEqual(false);
|
424
|
+
expect(cookies.policies).toHaveProperty("usage");
|
425
|
+
expect(cookies.isPolicyAccepted("usage")).toEqual(false);
|
426
|
+
});
|
427
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
2
|
+
import { TextEncoder, TextDecoder, store, options } from "util";
|
3
|
+
import uuidv4 from "../lib/uuid.mjs";
|
4
|
+
|
5
|
+
global.TextEncoder = TextEncoder;
|
6
|
+
global.TextDecoder = TextDecoder;
|
7
|
+
global.store = store;
|
8
|
+
global.options = options;
|
9
|
+
|
10
|
+
describe("UUID", () => {
|
11
|
+
test("Initialisation", async () => {
|
12
|
+
const uuid1 = uuidv4();
|
13
|
+
const uuid2 = uuidv4();
|
14
|
+
|
15
|
+
expect(uuid1).not.toEqual(uuid2);
|
16
|
+
});
|
17
|
+
});
|