@openneuro/app 4.20.6 → 4.21.0-alpha.1

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.
Files changed (42) hide show
  1. package/package.json +4 -4
  2. package/src/scripts/app.tsx +16 -10
  3. package/src/scripts/components/__tests__/agreement.spec.tsx +24 -0
  4. package/src/scripts/components/agreement.tsx +76 -0
  5. package/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap +10 -330
  6. package/src/scripts/dataset/components/BrainLifeButton.tsx +38 -0
  7. package/src/scripts/dataset/components/CloneDropdown.tsx +31 -0
  8. package/src/scripts/dataset/components/DatasetAlert.tsx +25 -0
  9. package/src/scripts/dataset/components/DatasetGitAccess.tsx +82 -0
  10. package/src/scripts/dataset/components/DatasetHeader.tsx +43 -0
  11. package/src/scripts/dataset/components/DatasetHeaderMeta.tsx +22 -0
  12. package/src/scripts/dataset/components/DatasetToolButton.tsx +52 -0
  13. package/src/scripts/dataset/components/DatasetTools.tsx +149 -0
  14. package/src/scripts/dataset/components/MetaDataBlock.tsx +24 -0
  15. package/src/scripts/dataset/components/MetaDataListBlock.tsx +23 -0
  16. package/src/scripts/dataset/components/ModalitiesMetaDataBlock.tsx +32 -0
  17. package/src/scripts/dataset/components/NemarButton.tsx +34 -0
  18. package/src/scripts/dataset/components/ValidationBlock.tsx +11 -0
  19. package/src/scripts/dataset/components/VersionList.tsx +115 -0
  20. package/src/scripts/dataset/components/__tests__/DatasetAlert.spec.tsx +25 -0
  21. package/src/scripts/dataset/components/__tests__/DatasetHeaders.spec.tsx +18 -0
  22. package/src/scripts/dataset/components/__tests__/DatasetTools.spec.tsx +133 -0
  23. package/src/scripts/dataset/draft-container.tsx +9 -11
  24. package/src/scripts/dataset/files/__tests__/file.spec.jsx +13 -4
  25. package/src/scripts/dataset/files/file.tsx +27 -21
  26. package/src/scripts/dataset/fragments/dataset-alert-draft.tsx +1 -1
  27. package/src/scripts/dataset/fragments/dataset-alert-version.tsx +1 -1
  28. package/src/scripts/dataset/routes/dataset-default.tsx +1 -1
  29. package/src/scripts/dataset/routes/download-dataset.tsx +7 -1
  30. package/src/scripts/dataset/routes/snapshot-default.tsx +1 -1
  31. package/src/scripts/dataset/snapshot-container.tsx +10 -12
  32. package/src/scripts/scss/README.md +3 -0
  33. package/src/scripts/scss/dataset/comments.scss +152 -0
  34. package/src/scripts/scss/dataset/dataset-page.scss +397 -0
  35. package/src/scripts/scss/dataset/dataset-tool.scss +281 -0
  36. package/src/scripts/scss/dataset/dropdown.scss +29 -0
  37. package/src/scripts/scss/dataset/validation.scss +392 -0
  38. package/src/scripts/scss/dataset/version-dropdown.scss +121 -0
  39. package/src/scripts/scss/index.scss +6 -0
  40. package/src/scripts/scss/variables.scss +205 -0
  41. package/src/scripts/utils/__tests__/local-storage.spec.tsx +32 -0
  42. package/src/scripts/utils/local-storage.tsx +53 -0
@@ -0,0 +1,82 @@
1
+ import React from "react"
2
+ import { Tooltip } from "@openneuro/components/tooltip"
3
+ import { Button } from "@openneuro/components/button"
4
+
5
+ function copyToClipboard(text) {
6
+ navigator.clipboard.writeText(text)
7
+ }
8
+
9
+ export interface DatasetGitAccessProps {
10
+ datasetId: string
11
+ worker?: string
12
+ configUrl: string
13
+ gitHash: string
14
+ configGithub?: string
15
+ hasEdit?: boolean
16
+ }
17
+
18
+ export const DatasetGitAccess = ({
19
+ datasetId,
20
+ worker,
21
+ configUrl,
22
+ gitHash,
23
+ configGithub,
24
+ hasEdit,
25
+ }: DatasetGitAccessProps) => {
26
+ const workerId = worker?.split("-").pop()
27
+ const url = `${configUrl}/git/${workerId}/${datasetId}`
28
+ const readURL = `https://github.com/${configGithub}/${datasetId}.git`
29
+ return (
30
+ <div className="dataset-git-access">
31
+ <span>
32
+ <h4>DataLad/Git URL</h4>
33
+ <a href="https://docs.openneuro.org/git" target="_blank">
34
+ View Documentation
35
+ </a>
36
+ </span>
37
+ <div className="git-url">
38
+ {workerId && (
39
+ <Tooltip tooltip="Copy URL To Clipboard" flow="right">
40
+ <Button
41
+ onClick={() => copyToClipboard(readURL)}
42
+ icon="fas fa-clipboard"
43
+ size="small"
44
+ iconSize="18px"
45
+ label="copy Github url"
46
+ />
47
+ </Tooltip>
48
+ )}
49
+ <div>{readURL}</div>
50
+ </div>
51
+ {hasEdit && (
52
+ <div className="git-url">
53
+ {workerId && (
54
+ <Tooltip tooltip="Copy URL To Clipboard" flow="right">
55
+ <Button
56
+ onClick={() => copyToClipboard(url)}
57
+ icon="fas fa-clipboard"
58
+ size="small"
59
+ iconSize="18px"
60
+ label="copy OpenNeuro url"
61
+ />
62
+ </Tooltip>
63
+ )}
64
+ <div>{url}</div>
65
+ </div>
66
+ )}
67
+
68
+ <div className="git-hash">
69
+ <Tooltip tooltip="Copy Git Hash to Clipboard" flow="right">
70
+ <Button
71
+ onClick={() => copyToClipboard(gitHash)}
72
+ icon="fas fa-clipboard"
73
+ size="small"
74
+ iconSize="18px"
75
+ label="copy git hash"
76
+ />
77
+ </Tooltip>
78
+ <div>Git Hash: {gitHash.slice(0, 7)}</div>
79
+ </div>
80
+ </div>
81
+ )
82
+ }
@@ -0,0 +1,43 @@
1
+ import React from "react"
2
+ import { Link } from "react-router-dom"
3
+
4
+ export interface DatasetHeaderProps {
5
+ modality: string
6
+ pageHeading: string
7
+ renderEditor?: () => React.ReactNode
8
+ children?: JSX.Element
9
+ }
10
+
11
+ export const DatasetHeader: React.FC<DatasetHeaderProps> = ({
12
+ pageHeading,
13
+ modality,
14
+ renderEditor,
15
+ children,
16
+ }) => {
17
+ return (
18
+ <div className="dataset-header">
19
+ <div className="container">
20
+ <div className="grid grid-between">
21
+ <div className="col">
22
+ <h1>
23
+ <Link to={"/search/modality/" + modality}>
24
+ <div className="hexagon-wrapper">
25
+ <div className="hexagon no-modality"></div>
26
+ <div className="label">
27
+ {modality
28
+ ? (
29
+ modality.substr(0, 4)
30
+ )
31
+ : <i className="fa fa-circle-o-notch fa-spin"></i>}
32
+ </div>
33
+ </div>
34
+ </Link>
35
+ {renderEditor?.() || pageHeading}
36
+ {children}
37
+ </h1>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ )
43
+ }
@@ -0,0 +1,22 @@
1
+ import React from "react"
2
+ import bytes from "bytes"
3
+
4
+ export interface DatasetHeaderMetaProps {
5
+ datasetId: string
6
+ totalFiles: number
7
+ size: number
8
+ }
9
+
10
+ export const DatasetHeaderMeta: React.FC<DatasetHeaderMetaProps> = ({
11
+ datasetId,
12
+ totalFiles,
13
+ size,
14
+ }) => {
15
+ return (
16
+ <div>
17
+ <span>OpenNeuro Accession Number:</span> {datasetId}
18
+ <span>Files:</span> {totalFiles}
19
+ <span>Size:</span> {bytes(size)}
20
+ </div>
21
+ )
22
+ }
@@ -0,0 +1,52 @@
1
+ import React from "react"
2
+ import styled, { StyledComponent } from "@emotion/styled"
3
+ import { Link } from "react-router-dom"
4
+ import { Tooltip } from "@openneuro/components/tooltip"
5
+ import { Icon } from "@openneuro/components/icon"
6
+ import { useLocation } from "react-router-dom"
7
+
8
+ interface DatasetToolStyleProps {
9
+ active: boolean
10
+ }
11
+
12
+ export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled
13
+ .span<DatasetToolStyleProps>(
14
+ (props) => `
15
+ display: flex;
16
+ margin: 0 auto 10px;
17
+ flex-basis: auto;
18
+ padding: 0 15px;
19
+ justify-content: center;
20
+ a {
21
+ color: var(--current-theme-primary);
22
+ font-size: 17px;
23
+ text-decoration: none;
24
+ font-weight: 400;
25
+ padding: 4px;
26
+ border-bottom: 2px solid transparent;
27
+ border-bottom-color: ${
28
+ props.active ? "var(--current-theme-primary)" : "transparent"
29
+ };
30
+ i {
31
+ margin-right: 6px;
32
+ font-size: 15px;
33
+ }
34
+ &:hover {
35
+ border-bottom-color: var(--current-theme-primary);
36
+ }
37
+ }
38
+ `,
39
+ )
40
+
41
+ export const DatasetToolButton = ({ path, icon, tooltip, label }) => {
42
+ const location = useLocation()
43
+ return (
44
+ <DatasetToolStyle active={location.pathname == path}>
45
+ <Tooltip tooltip={tooltip} flow="up">
46
+ <Link to={path}>
47
+ <Icon icon={`fa ${icon}`} label={label} />
48
+ </Link>
49
+ </Tooltip>
50
+ </DatasetToolStyle>
51
+ )
52
+ }
@@ -0,0 +1,149 @@
1
+ import React from "react"
2
+ import { DatasetToolButton } from "./DatasetToolButton"
3
+ import styled, { StyledComponent } from "@emotion/styled"
4
+ import { useAgreement } from "../../components/agreement"
5
+
6
+ interface DatasetToolStyleProps {}
7
+
8
+ export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled
9
+ .span`
10
+ display: flex;
11
+ justify-content: flex-start;
12
+ flex-wrap: wrap;
13
+ `
14
+
15
+ export interface DatasetToolsProps {
16
+ hasEdit: boolean
17
+ isPublic: boolean
18
+ datasetId: string
19
+ snapshotId?: string
20
+ isAdmin: boolean
21
+ isDatasetAdmin: boolean
22
+ hasSnapshot?: boolean
23
+ hasDerivatives?: boolean
24
+ }
25
+
26
+ export const DatasetTools = ({
27
+ hasEdit,
28
+ isPublic,
29
+ datasetId,
30
+ snapshotId,
31
+ isAdmin,
32
+ hasSnapshot,
33
+ isDatasetAdmin,
34
+ hasDerivatives,
35
+ }: DatasetToolsProps) => {
36
+ const [agree] = useAgreement()
37
+ const isSnapshot = snapshotId
38
+ return (
39
+ <DatasetToolStyle>
40
+ <DatasetToolButton
41
+ tooltip={"View the dataset file tree"}
42
+ path={snapshotId
43
+ ? `/datasets/${datasetId}/versions/${snapshotId}`
44
+ : `/datasets/${datasetId}`}
45
+ icon="fa-folder"
46
+ label="Files"
47
+ />
48
+ {hasEdit && !isPublic && !isSnapshot && (
49
+ <>
50
+ {hasSnapshot
51
+ ? (
52
+ <DatasetToolButton
53
+ tooltip="Publicize the dataset"
54
+ path={`/datasets/${datasetId}/publish`}
55
+ icon="fa-globe"
56
+ label="Publish"
57
+ />
58
+ )
59
+ : (
60
+ <DatasetToolButton
61
+ tooltip="Create a version to publish"
62
+ path={`/datasets/${datasetId}/snapshot?publish`}
63
+ icon="fa-globe"
64
+ label="Publish"
65
+ />
66
+ )}
67
+ </>
68
+ )}
69
+ {hasEdit && !isSnapshot && (
70
+ <DatasetToolButton
71
+ tooltip="Share this dataset with collaborators"
72
+ path={`/datasets/${datasetId}/share`}
73
+ icon="fa-user"
74
+ label="Share"
75
+ />
76
+ )}
77
+ {hasEdit && isSnapshot && (
78
+ <DatasetToolButton
79
+ tooltip="View the Dataset Draft"
80
+ path={`/datasets/${datasetId}`}
81
+ icon="fa-pencil"
82
+ label="View Draft"
83
+ />
84
+ )}
85
+ {hasEdit && !isSnapshot && (
86
+ <DatasetToolButton
87
+ tooltip="Create a new version of the dataset"
88
+ path={`/datasets/${datasetId}/snapshot`}
89
+ icon="fa-camera"
90
+ label="Versioning"
91
+ />
92
+ )}
93
+ {isAdmin && !isSnapshot && (
94
+ <DatasetToolButton
95
+ tooltip="Admin Datalad Tools"
96
+ path={`/datasets/${datasetId}/admin`}
97
+ icon="fa-magic"
98
+ label="Admin"
99
+ />
100
+ )}
101
+ {agree && (
102
+ <DatasetToolButton
103
+ tooltip="How to Download"
104
+ path={snapshotId
105
+ ? `/datasets/${datasetId}/versions/${snapshotId}/download`
106
+ : `/datasets/${datasetId}/download`}
107
+ icon="fa-download"
108
+ label="Download"
109
+ />
110
+ )}
111
+ {hasDerivatives && (
112
+ <DatasetToolButton
113
+ tooltip="Available Derivatives"
114
+ path={snapshotId
115
+ ? `/datasets/${datasetId}/versions/${snapshotId}/derivatives`
116
+ : `/datasets/${datasetId}/derivatives`}
117
+ icon="fa-cubes"
118
+ label="Derivatives"
119
+ />
120
+ )}
121
+ <DatasetToolButton
122
+ tooltip={hasEdit
123
+ ? "A form to describe your dataset (helps colleagues discover your dataset)"
124
+ : "View the dataset metadata"}
125
+ path={snapshotId
126
+ ? `/datasets/${datasetId}/versions/${snapshotId}/metadata`
127
+ : `/datasets/${datasetId}/metadata`}
128
+ icon="fa-file-code"
129
+ label="Metadata"
130
+ />
131
+ {isDatasetAdmin && !isSnapshot && (
132
+ <DatasetToolButton
133
+ tooltip="Remove your dataset from OpenNeuro"
134
+ path={`/datasets/${datasetId}/delete`}
135
+ icon="fa-trash"
136
+ label="Delete"
137
+ />
138
+ )}
139
+ {hasEdit && isSnapshot && (
140
+ <DatasetToolButton
141
+ tooltip="Flag this version as deprecated"
142
+ path={`/datasets/${datasetId}/versions/${snapshotId}/deprecate`}
143
+ icon="fa-remove"
144
+ label="Deprecate Version"
145
+ />
146
+ )}
147
+ </DatasetToolStyle>
148
+ )
149
+ }
@@ -0,0 +1,24 @@
1
+ import Markdown from "markdown-to-jsx"
2
+ import React from "react"
3
+
4
+ export interface MetaDataBlockProps {
5
+ heading: string
6
+ item: React.ReactNode | string[] | number
7
+ className?: string
8
+ renderEditor?: () => React.ReactNode
9
+ }
10
+
11
+ export const MetaDataBlock = ({
12
+ heading,
13
+ item,
14
+ className,
15
+ renderEditor,
16
+ }: MetaDataBlockProps) => {
17
+ const fieldContent = renderEditor ? renderEditor() : item
18
+ return (
19
+ <div className={"dataset-meta-block " + className}>
20
+ <h2 className="dmb-heading">{heading}</h2>
21
+ <>{fieldContent}</>
22
+ </div>
23
+ )
24
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react"
2
+
3
+ export interface MetaDataListBlockProps {
4
+ heading: string
5
+ item: React.ReactNode | string[] | number
6
+ className?: string
7
+ renderEditor?: () => React.ReactNode
8
+ }
9
+
10
+ export const MetaDataListBlock = ({
11
+ heading,
12
+ item,
13
+ className,
14
+ renderEditor,
15
+ }: MetaDataListBlockProps) => {
16
+ const fieldContent = renderEditor ? renderEditor() : item
17
+ return (
18
+ <div className={"dataset-meta-block " + className}>
19
+ <h2 className="dmb-heading">{heading}</h2>
20
+ {fieldContent}
21
+ </div>
22
+ )
23
+ }
@@ -0,0 +1,32 @@
1
+ import React from "react"
2
+ import { Link } from "react-router-dom"
3
+
4
+ export interface ModalitiesMetaDataBlockProps {
5
+ items: string[]
6
+ className?: string
7
+ }
8
+
9
+ export const ModalitiesMetaDataBlock = ({
10
+ items,
11
+ className,
12
+ }: ModalitiesMetaDataBlockProps) => {
13
+ const customCase = {
14
+ mri: "MRI",
15
+ ieeg: "iEEG",
16
+ pet: "PET",
17
+ eeg: "EEG",
18
+ meg: "MEG",
19
+ }
20
+ return (
21
+ <div className={"dataset-meta-block " + className}>
22
+ <h2 className="dmb-heading">Available Modalities</h2>
23
+ {items.map((item, index) => (
24
+ <Link key={index} to={"/search/modality/" + item.toLowerCase()}>
25
+ {item.toLowerCase() in customCase
26
+ ? customCase[item.toLowerCase()]
27
+ : item}
28
+ </Link>
29
+ ))}
30
+ </div>
31
+ )
32
+ }
@@ -0,0 +1,34 @@
1
+ import React from "react"
2
+ import { Tooltip } from "@openneuro/components/tooltip"
3
+ import { Button } from "@openneuro/components/button"
4
+
5
+ export interface NemarButtonProps {
6
+ datasetId: string
7
+ onNemar: boolean
8
+ }
9
+
10
+ export const NemarButton: React.FC<NemarButtonProps> = ({
11
+ datasetId,
12
+ onNemar,
13
+ }) => {
14
+ const url = `https://nemar.org/dataexplorer/detail?dataset_id=${datasetId}`
15
+ return (
16
+ <>
17
+ {onNemar && (
18
+ <div className="brainlife-block">
19
+ <Tooltip tooltip="View and analyze on NEMAR" flow="up">
20
+ <Button
21
+ className="brainlife-link"
22
+ primary={true}
23
+ size="small"
24
+ onClick={() => {
25
+ window.open(url, "_blank")
26
+ }}
27
+ label="NEMAR"
28
+ />
29
+ </Tooltip>
30
+ </div>
31
+ )}
32
+ </>
33
+ )
34
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react"
2
+
3
+ export interface ValidationBlockProps {
4
+ children?: React.ReactNode
5
+ }
6
+
7
+ export const ValidationBlock: React.FC<ValidationBlockProps> = ({
8
+ children,
9
+ }) => {
10
+ return <div className="validation-accordion">{children}</div>
11
+ }
@@ -0,0 +1,115 @@
1
+ import React from "react"
2
+ import { Link } from "react-router-dom"
3
+ import { Dropdown } from "@openneuro/components/dropdown"
4
+
5
+ export interface VersionListProps {
6
+ items: {
7
+ label: string
8
+ value: string
9
+ id: string
10
+ tag: string
11
+ created: Date
12
+ deprecated: boolean
13
+ }[]
14
+ hasEdit: boolean
15
+ selected: string
16
+ setSelected: (selected: string) => void
17
+ className: string
18
+ activeDataset: string
19
+ dateModified: string
20
+ datasetId?: string
21
+ }
22
+ const formatDate = (dateObject) =>
23
+ new Date(dateObject).toISOString().split("T")[0]
24
+
25
+ export const VersionList = ({
26
+ items,
27
+ selected,
28
+ setSelected,
29
+ className,
30
+ dateModified,
31
+ datasetId,
32
+ hasEdit,
33
+ }: VersionListProps) => {
34
+ const deprecatedItem = (itemTag, itemCreated) => {
35
+ setSelected(itemTag)
36
+ }
37
+ const setVersion = (itemTag, itemCreated) => {
38
+ setSelected(itemTag)
39
+ }
40
+ return (
41
+ <>
42
+ <div className="active-version">
43
+ <div>{selected === "draft" ? "Draft" : selected}</div>
44
+ {selected === "draft" ? "Updated" : "Created"}: {dateModified}
45
+ </div>
46
+ {items.length
47
+ ? (
48
+ <Dropdown
49
+ className={className}
50
+ label={
51
+ <div className="version-list-label">
52
+ <b>Versions</b>
53
+ <i className="fas fa-chevron-up" />
54
+ <i className="fas fa-chevron-down" />
55
+ </div>
56
+ }
57
+ >
58
+ <div className="version-list-dropdown">
59
+ <ul>
60
+ <li
61
+ onClick={() => setVersion("draft", dateModified)}
62
+ className={selected === "draft" ? "selected" : ""}
63
+ >
64
+ <Link className="dataset-tool" to={"/datasets/" + datasetId}>
65
+ <span className="label">
66
+ Draft
67
+ <span className="active">
68
+ {selected === "draft" ? "*" : ""}
69
+ </span>
70
+ </span>
71
+ {dateModified}
72
+ </Link>
73
+ </li>
74
+ {items.map((item, index) => (
75
+ <li
76
+ key={index}
77
+ onClick={item.deprecated === true
78
+ ? () => deprecatedItem(item.tag, item.created)
79
+ : () => setVersion(item.tag, formatDate(item.created))}
80
+ className={selected === item.tag ? "selected" : ""}
81
+ >
82
+ <Link
83
+ className="dataset-tool"
84
+ to={"/datasets/" + datasetId + "/versions/" + item.tag}
85
+ >
86
+ <span className="label">
87
+ v{item.tag}
88
+ <span className="active">
89
+ {selected === item.tag ? "*" : ""}
90
+ </span>
91
+ <span className="deprecated">
92
+ {item.deprecated === true ? "Deprecated" : ""}
93
+ </span>
94
+ </span>
95
+ {formatDate(item.created)}
96
+ </Link>
97
+ </li>
98
+ ))}
99
+ </ul>
100
+ </div>
101
+ </Dropdown>
102
+ )
103
+ : hasEdit
104
+ ? (
105
+ <Link
106
+ className="dataset-tool"
107
+ to={"/datasets/" + datasetId + "/snapshot"}
108
+ >
109
+ Create Version
110
+ </Link>
111
+ )
112
+ : null}
113
+ </>
114
+ )
115
+ }
@@ -0,0 +1,25 @@
1
+ import React from "react"
2
+ import { render, screen } from "@testing-library/react"
3
+ import { DatasetAlert } from "../DatasetAlert"
4
+
5
+ describe("DatasetAlert component", () => {
6
+ it("all props are rendered", () => {
7
+ render(
8
+ <DatasetAlert alert="alert text" footer="footer text" level="warning">
9
+ <span role="marquee">test text</span>
10
+ </DatasetAlert>,
11
+ )
12
+
13
+ expect(screen.getByRole("marquee")).toBeVisible()
14
+ expect(screen.getByText("alert text")).toBeVisible()
15
+ expect(screen.getByText("footer text")).toBeVisible()
16
+ })
17
+ it('sets the correct alert class based on "level" prop', () => {
18
+ render(
19
+ <DatasetAlert alert="alert text" footer="footer text" level="warning">
20
+ Warning!
21
+ </DatasetAlert>,
22
+ )
23
+ expect(screen.getByRole("alert")).toHaveClass("warning")
24
+ })
25
+ })
@@ -0,0 +1,18 @@
1
+ import React from "react"
2
+ import { render, screen } from "@testing-library/react"
3
+ import { MemoryRouter } from "react-router-dom"
4
+ import { DatasetHeader } from "../DatasetHeader"
5
+
6
+ describe("DatasetHeader component", () => {
7
+ it("renders with an undefined modality", () => {
8
+ render(
9
+ <DatasetHeader
10
+ pageHeading="test page"
11
+ modality={undefined}
12
+ renderEditor={() => <></>}
13
+ />,
14
+ { wrapper: MemoryRouter },
15
+ )
16
+ expect(screen.queryByRole("heading")).toBeInTheDocument()
17
+ })
18
+ })