mirror of
https://github.com/mattermost/mattermost.git
synced 2026-09-24 16:05:00 +08:00
MM-67725: (test) Migrate enzyme to RTL (#34966)
This commit is contained in:
+53
-167
@@ -1,183 +1,69 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/FormattedMarkdownMessage should allow to disable links 1`] = `
|
||||
<IntlProvider
|
||||
defaultFormats={Object {}}
|
||||
defaultLocale="en"
|
||||
fallbackOnEmptyString={true}
|
||||
formats={Object {}}
|
||||
locale="en"
|
||||
messages={
|
||||
Object {
|
||||
"test.bar": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
"test.foo": "**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)",
|
||||
"test.vals": "*Hi* {petName}!",
|
||||
}
|
||||
}
|
||||
onError={[Function]}
|
||||
onWarn={[Function]}
|
||||
textComponent={Symbol(react.fragment)}
|
||||
>
|
||||
<FormattedMarkdownMessage
|
||||
defaultMessage="*Hi* {petName}!"
|
||||
disableLinks={true}
|
||||
id="test.vals"
|
||||
values={
|
||||
Object {
|
||||
"petName": "http://www.mattermost.com",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<em>Hi</em> http://www.mattermost.com!",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</FormattedMarkdownMessage>
|
||||
</IntlProvider>
|
||||
<div>
|
||||
<span>
|
||||
<em>
|
||||
Hi
|
||||
</em>
|
||||
http://www.mattermost.com!
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FormattedMarkdownMessage should backup to default 1`] = `
|
||||
<IntlProvider
|
||||
defaultFormats={Object {}}
|
||||
defaultLocale="en"
|
||||
fallbackOnEmptyString={true}
|
||||
formats={Object {}}
|
||||
locale="en"
|
||||
messages={
|
||||
Object {
|
||||
"test.bar": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
"test.foo": "**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)",
|
||||
"test.vals": "*Hi* {petName}!",
|
||||
}
|
||||
}
|
||||
onError={[Function]}
|
||||
onWarn={[Function]}
|
||||
textComponent={Symbol(react.fragment)}
|
||||
>
|
||||
<FormattedMarkdownMessage
|
||||
defaultMessage="testing default message"
|
||||
id="xxx"
|
||||
>
|
||||
<span
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "testing default message",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</FormattedMarkdownMessage>
|
||||
</IntlProvider>
|
||||
<div>
|
||||
<span>
|
||||
testing default message
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FormattedMarkdownMessage should escape non-BR 1`] = `
|
||||
<IntlProvider
|
||||
defaultFormats={Object {}}
|
||||
defaultLocale="en"
|
||||
fallbackOnEmptyString={true}
|
||||
formats={Object {}}
|
||||
locale="en"
|
||||
messages={
|
||||
Object {
|
||||
"test.bar": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
"test.foo": "**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)",
|
||||
"test.vals": "*Hi* {petName}!",
|
||||
}
|
||||
}
|
||||
onError={[Function]}
|
||||
onWarn={[Function]}
|
||||
textComponent={Symbol(react.fragment)}
|
||||
>
|
||||
<FormattedMarkdownMessage
|
||||
defaultMessage=""
|
||||
id="test.bar"
|
||||
values={
|
||||
Object {
|
||||
"b": [Function],
|
||||
"script": [Function],
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</FormattedMarkdownMessage>
|
||||
</IntlProvider>
|
||||
<div>
|
||||
<span>
|
||||
<b>hello</b> <script>var malicious = true;</script> world!
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FormattedMarkdownMessage should render message 1`] = `
|
||||
<IntlProvider
|
||||
defaultFormats={Object {}}
|
||||
defaultLocale="en"
|
||||
fallbackOnEmptyString={true}
|
||||
formats={Object {}}
|
||||
locale="en"
|
||||
messages={
|
||||
Object {
|
||||
"test.bar": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
"test.foo": "**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)",
|
||||
"test.vals": "*Hi* {petName}!",
|
||||
}
|
||||
}
|
||||
onError={[Function]}
|
||||
onWarn={[Function]}
|
||||
textComponent={Symbol(react.fragment)}
|
||||
>
|
||||
<FormattedMarkdownMessage
|
||||
defaultMessage="**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)"
|
||||
id="test.foo"
|
||||
>
|
||||
<span
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<strong>bold</strong> <em>italic</em> <a href=\\"https://mattermost.com/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">link</a> <br/> <a href=\\"https://mattermost.com/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">link target blank</a>",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</FormattedMarkdownMessage>
|
||||
</IntlProvider>
|
||||
<div>
|
||||
<span>
|
||||
<strong>
|
||||
bold
|
||||
</strong>
|
||||
|
||||
<em>
|
||||
italic
|
||||
</em>
|
||||
|
||||
<a
|
||||
href="https://mattermost.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
link
|
||||
</a>
|
||||
<br/>
|
||||
<a
|
||||
href="https://mattermost.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
link target blank
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FormattedMarkdownMessage values should work 1`] = `
|
||||
<IntlProvider
|
||||
defaultFormats={Object {}}
|
||||
defaultLocale="en"
|
||||
fallbackOnEmptyString={true}
|
||||
formats={Object {}}
|
||||
locale="en"
|
||||
messages={
|
||||
Object {
|
||||
"test.bar": "<b>hello</b> <script>var malicious = true;</script> world!",
|
||||
"test.foo": "**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)",
|
||||
"test.vals": "*Hi* {petName}!",
|
||||
}
|
||||
}
|
||||
onError={[Function]}
|
||||
onWarn={[Function]}
|
||||
textComponent={Symbol(react.fragment)}
|
||||
>
|
||||
<FormattedMarkdownMessage
|
||||
defaultMessage="*Hi* {petName}!"
|
||||
id="test.vals"
|
||||
values={
|
||||
Object {
|
||||
"petName": "sweetie",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<em>Hi</em> sweetie!",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</FormattedMarkdownMessage>
|
||||
</IntlProvider>
|
||||
<div>
|
||||
<span>
|
||||
<em>
|
||||
Hi
|
||||
</em>
|
||||
sweetie!
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,362 +1,386 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/GetLinkModal should have called onHide 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="none"
|
||||
show={true}
|
||||
exports[`components/GetLinkModal should have called onHide when close button is clicked 1`] = `
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
id="getLinkModalLabel"
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
role="none"
|
||||
>
|
||||
<h2
|
||||
className="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<textarea
|
||||
className="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
onClick={[Function]}
|
||||
readOnly={true}
|
||||
value="https://mattermost.com"
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
componentClass="div"
|
||||
>
|
||||
<button
|
||||
className="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
<div
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="get_link.close"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary btn-success pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
className="icon icon-check"
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Copied"
|
||||
id="get_link.clipboard"
|
||||
/>
|
||||
</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
<div
|
||||
class="a11y__modal modal-dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
id="getLinkModalLabel"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h2
|
||||
class="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<textarea
|
||||
class="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
readonly=""
|
||||
>
|
||||
https://mattermost.com
|
||||
</textarea>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary btn-success pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="icon icon-check"
|
||||
/>
|
||||
Copied
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`components/GetLinkModal should have called onHide 2`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="none"
|
||||
show={true}
|
||||
exports[`components/GetLinkModal should have called onHide when close button is clicked 2`] = `
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
id="getLinkModalLabel"
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
role="none"
|
||||
>
|
||||
<h2
|
||||
className="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<textarea
|
||||
className="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
onClick={[Function]}
|
||||
readOnly={true}
|
||||
value="https://mattermost.com"
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
componentClass="div"
|
||||
>
|
||||
<button
|
||||
className="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
<div
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="get_link.close"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
className="icon icon-link-variant"
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Copy Link"
|
||||
id="get_link.copy"
|
||||
/>
|
||||
</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
<div
|
||||
class="a11y__modal modal-dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
id="getLinkModalLabel"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h2
|
||||
class="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<textarea
|
||||
class="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
readonly=""
|
||||
>
|
||||
https://mattermost.com
|
||||
</textarea>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="icon icon-link-variant"
|
||||
/>
|
||||
Copy Link
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`components/GetLinkModal should match snapshot when all props is set 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="none"
|
||||
show={true}
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
id="getLinkModalLabel"
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
role="none"
|
||||
>
|
||||
<h2
|
||||
className="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<p>
|
||||
help text
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<textarea
|
||||
className="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
onClick={[Function]}
|
||||
readOnly={true}
|
||||
value="https://mattermost.com"
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
componentClass="div"
|
||||
>
|
||||
<button
|
||||
className="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
<div
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="get_link.close"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
className="icon icon-link-variant"
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Copy Link"
|
||||
id="get_link.copy"
|
||||
/>
|
||||
</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
<div
|
||||
class="a11y__modal modal-dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
id="getLinkModalLabel"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h2
|
||||
class="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<p>
|
||||
help text
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<textarea
|
||||
class="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
readonly=""
|
||||
>
|
||||
https://mattermost.com
|
||||
</textarea>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="icon icon-link-variant"
|
||||
/>
|
||||
Copy Link
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`components/GetLinkModal should match snapshot when helpText is not set 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="none"
|
||||
show={true}
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
id="getLinkModalLabel"
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
role="none"
|
||||
>
|
||||
<h2
|
||||
className="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<textarea
|
||||
className="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
onClick={[Function]}
|
||||
readOnly={true}
|
||||
value="https://mattermost.com"
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
componentClass="div"
|
||||
>
|
||||
<button
|
||||
className="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
<div
|
||||
aria-labelledby="getLinkModalLabel"
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="get_link.close"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
className="icon icon-link-variant"
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Copy Link"
|
||||
id="get_link.copy"
|
||||
/>
|
||||
</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
<div
|
||||
class="a11y__modal modal-dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
id="getLinkModalLabel"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h2
|
||||
class="modal-title"
|
||||
>
|
||||
title
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<textarea
|
||||
class="form-control no-resize min-height"
|
||||
dir="auto"
|
||||
id="linkModalTextArea"
|
||||
readonly=""
|
||||
>
|
||||
https://mattermost.com
|
||||
</textarea>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-tertiary"
|
||||
id="linkModalCloseButton"
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary pull-left"
|
||||
data-copy-btn="true"
|
||||
id="linkModalCopyLink"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="icon icon-link-variant"
|
||||
/>
|
||||
Copy Link
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,225 +1,251 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/ListModal should match snapshot 1`] = `
|
||||
<div>
|
||||
<Modal
|
||||
animation={true}
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal more-modal more-modal--action"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[Function]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
show={true}
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
>
|
||||
<ModalTitle
|
||||
bsClass="modal-title"
|
||||
componentClass="h1"
|
||||
>
|
||||
<span
|
||||
className="name"
|
||||
>
|
||||
list modal
|
||||
</span>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
<div
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
className="filtered-user-list"
|
||||
class="a11y__modal more-modal more-modal--action modal-dialog"
|
||||
>
|
||||
<div
|
||||
className="filter-row"
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
className="col-xs-12"
|
||||
class="modal-header"
|
||||
>
|
||||
<label
|
||||
className="hidden-label"
|
||||
htmlFor="searchUsersInput"
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
search for name
|
||||
</label>
|
||||
<input
|
||||
className="form-control filter-textbox"
|
||||
id="searchUsersInput"
|
||||
onChange={[Function]}
|
||||
placeholder="search for name"
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h1
|
||||
class="modal-title"
|
||||
>
|
||||
<span
|
||||
class="name"
|
||||
>
|
||||
list modal
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="col-sm-12"
|
||||
class="modal-body"
|
||||
>
|
||||
<span
|
||||
className="member-count pull-left"
|
||||
<div
|
||||
class="filtered-user-list"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="{startCount, number} - {endCount, number} of {total, number} total"
|
||||
id="list_modal.paginatorCount"
|
||||
values={
|
||||
Object {
|
||||
"endCount": 0,
|
||||
"startCount": 0,
|
||||
"total": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="more-modal__list"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<LoadingScreen
|
||||
key="loading"
|
||||
position="absolute"
|
||||
<div
|
||||
class="filter-row"
|
||||
>
|
||||
<div
|
||||
class="col-xs-12"
|
||||
>
|
||||
<label
|
||||
class="hidden-label"
|
||||
for="searchUsersInput"
|
||||
>
|
||||
search for name
|
||||
</label>
|
||||
<input
|
||||
class="form-control filter-textbox"
|
||||
id="searchUsersInput"
|
||||
placeholder="search for name"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="col-sm-12"
|
||||
>
|
||||
<span
|
||||
class="member-count pull-left"
|
||||
>
|
||||
1 - 2 of 3 total
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="more-modal__list"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="item"
|
||||
data-testid="item-123"
|
||||
>
|
||||
123
|
||||
</div>
|
||||
<div
|
||||
class="item"
|
||||
data-testid="item-234"
|
||||
>
|
||||
234
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="filter-controls"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="filter-controls"
|
||||
/>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`components/ListModal should match snapshot with title bar button 1`] = `
|
||||
<div>
|
||||
<Modal
|
||||
animation={true}
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal more-modal more-modal--action"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[Function]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
show={true}
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
>
|
||||
<ModalTitle
|
||||
bsClass="modal-title"
|
||||
componentClass="h1"
|
||||
>
|
||||
<span
|
||||
className="name"
|
||||
>
|
||||
list modal
|
||||
</span>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
<div
|
||||
class="fade in modal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
className="filtered-user-list"
|
||||
class="a11y__modal more-modal more-modal--action modal-dialog"
|
||||
>
|
||||
<div
|
||||
className="filter-row"
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
className="col-xs-12"
|
||||
class="modal-header"
|
||||
>
|
||||
<label
|
||||
className="hidden-label"
|
||||
htmlFor="searchUsersInput"
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
search for name
|
||||
</label>
|
||||
<input
|
||||
className="form-control filter-textbox"
|
||||
id="searchUsersInput"
|
||||
onChange={[Function]}
|
||||
placeholder="search for name"
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h1
|
||||
class="modal-title"
|
||||
>
|
||||
<span
|
||||
class="name"
|
||||
>
|
||||
list modal
|
||||
</span>
|
||||
</h1>
|
||||
<a
|
||||
class="btn btn-md btn-primary"
|
||||
href="#"
|
||||
>
|
||||
Add Foo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="col-sm-12"
|
||||
class="modal-body"
|
||||
>
|
||||
<span
|
||||
className="member-count pull-left"
|
||||
<div
|
||||
class="filtered-user-list"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="{startCount, number} - {endCount, number} of {total, number} total"
|
||||
id="list_modal.paginatorCount"
|
||||
values={
|
||||
Object {
|
||||
"endCount": 0,
|
||||
"startCount": 0,
|
||||
"total": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="more-modal__list"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<LoadingScreen
|
||||
key="loading"
|
||||
position="absolute"
|
||||
<div
|
||||
class="filter-row"
|
||||
>
|
||||
<div
|
||||
class="col-xs-12"
|
||||
>
|
||||
<label
|
||||
class="hidden-label"
|
||||
for="searchUsersInput"
|
||||
>
|
||||
search for name
|
||||
</label>
|
||||
<input
|
||||
class="form-control filter-textbox"
|
||||
id="searchUsersInput"
|
||||
placeholder="search for name"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="col-sm-12"
|
||||
>
|
||||
<span
|
||||
class="member-count pull-left"
|
||||
>
|
||||
1 - 2 of 3 total
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="more-modal__list"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="item"
|
||||
data-testid="item-123"
|
||||
>
|
||||
123
|
||||
</div>
|
||||
<div
|
||||
class="item"
|
||||
data-testid="item-234"
|
||||
>
|
||||
234
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="filter-controls"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="filter-controls"
|
||||
/>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,29 +1,51 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/LoadingImagePreview should match snapshot 1`] = `
|
||||
<div
|
||||
className="view-image__loading"
|
||||
>
|
||||
<Memo(LoadingSpinner) />
|
||||
<span
|
||||
className="loader-percent"
|
||||
exports[`components/LoadingImagePreview should match snapshot with progress 50% 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="view-image__loading"
|
||||
>
|
||||
Loading
|
||||
50%
|
||||
</span>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="loader-percent"
|
||||
>
|
||||
Loading
|
||||
50%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/LoadingImagePreview should match snapshot 2`] = `
|
||||
<div
|
||||
className="view-image__loading"
|
||||
>
|
||||
<Memo(LoadingSpinner) />
|
||||
<span
|
||||
className="loader-percent"
|
||||
exports[`components/LoadingImagePreview should match snapshot with progress 90% 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="view-image__loading"
|
||||
>
|
||||
Loading
|
||||
90%
|
||||
</span>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="loader-percent"
|
||||
>
|
||||
Loading
|
||||
90%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,34 +1,55 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`component/PDFPreview should match snapshot, loading 1`] = `
|
||||
<div
|
||||
className="view-image__loading"
|
||||
>
|
||||
<Memo(LoadingSpinner) />
|
||||
<div>
|
||||
<div
|
||||
class="view-image__loading"
|
||||
>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`component/PDFPreview should match snapshot, not successful 1`] = `
|
||||
<Connect(Component)
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "pdf",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileUrl="https://pre-release.mattermost.com/api/v4/files/ips59w4w9jnfbrs3o94m1dbdie"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="file-details__container"
|
||||
>
|
||||
<a
|
||||
class="file-details__preview"
|
||||
href="https://pre-release.mattermost.com/api/v4/files/ips59w4w9jnfbrs3o94m1dbdie"
|
||||
>
|
||||
<span
|
||||
class="file-details__preview-helper"
|
||||
/>
|
||||
<img
|
||||
alt="file preview"
|
||||
src=""
|
||||
/>
|
||||
</a>
|
||||
<div
|
||||
class="file-details"
|
||||
>
|
||||
<div
|
||||
class="file-details__name"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
<div
|
||||
class="file-details__info"
|
||||
>
|
||||
File type PDF, Size 1B
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,79 +1,81 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/ChannelInfoModal should match snapshot 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="postDeletedModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
data-testid="postDeletedModal"
|
||||
dialogClassName="a11y__modal"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="none"
|
||||
show={true}
|
||||
exports[`components/PostDeletedModal should match snapshot 1`] = `
|
||||
<body
|
||||
class="modal-open"
|
||||
style="padding-right: 0px;"
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
role="none"
|
||||
>
|
||||
<ModalTitle
|
||||
bsClass="modal-title"
|
||||
componentClass="h1"
|
||||
id="postDeletedModalLabel"
|
||||
<div
|
||||
class="fade modal-backdrop in"
|
||||
/>
|
||||
<div
|
||||
aria-labelledby="postDeletedModalLabel"
|
||||
class="fade in modal"
|
||||
data-testid="postDeletedModal"
|
||||
role="dialog"
|
||||
style="display: block; padding-right: 0px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Comment could not be posted"
|
||||
id="post_delete.notPosted"
|
||||
/>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Someone deleted the message on which you tried to post a comment."
|
||||
id="post_delete.someone"
|
||||
/>
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter
|
||||
bsClass="modal-footer"
|
||||
componentClass="div"
|
||||
>
|
||||
<button
|
||||
autoFocus={true}
|
||||
className="btn btn-primary"
|
||||
data-testid="postDeletedModalOkButton"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Okay"
|
||||
id="post_delete.okay"
|
||||
/>
|
||||
</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
<div
|
||||
class="a11y__modal modal-dialog"
|
||||
>
|
||||
<div
|
||||
class="modal-content"
|
||||
role="document"
|
||||
>
|
||||
<div
|
||||
class="modal-header"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
class="sr-only"
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
<h1
|
||||
class="modal-title"
|
||||
id="postDeletedModalLabel"
|
||||
>
|
||||
Comment could not be posted
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
class="modal-body"
|
||||
>
|
||||
<p>
|
||||
Someone deleted the message on which you tried to post a comment.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="modal-footer"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
data-testid="postDeletedModalOkButton"
|
||||
type="button"
|
||||
>
|
||||
Okay
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
+15
-15
@@ -9,7 +9,7 @@ import type {ContentFlaggingNotificationSettings} from '@mattermost/types/config
|
||||
|
||||
import ContentFlaggingNotificationSettingsSection from './notification_settings';
|
||||
|
||||
const renderWithIntl = (component: React.ReactElement) => {
|
||||
const renderWithContext = (component: React.ReactElement) => {
|
||||
return render(
|
||||
<IntlProvider locale='en'>
|
||||
{component}
|
||||
@@ -36,14 +36,14 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should render section title and description', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
expect(screen.getByText('Notification Settings')).toBeInTheDocument();
|
||||
expect(screen.getByText('Choose who receives notifications from the System bot when content is flagged and reviewed')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render all notification setting sections', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
expect(screen.getByText('Notify when content is flagged')).toBeInTheDocument();
|
||||
expect(screen.getByText('Notify when a reviewer is assigned')).toBeInTheDocument();
|
||||
@@ -52,7 +52,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should render all checkbox labels', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
// Should have multiple instances of these labels across different sections
|
||||
expect(screen.getAllByText('Reviewer(s)')).toHaveLength(4);
|
||||
@@ -61,7 +61,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should set correct default checked values for checkboxes', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
expect(screen.getByTestId('flagged_reviewers')).toBeChecked();
|
||||
expect(screen.getByTestId('flagged_author')).not.toBeChecked();
|
||||
@@ -81,7 +81,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should handle checkbox change when adding a target', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
const flaggedAuthorsCheckbox = screen.getByTestId('flagged_author');
|
||||
fireEvent.click(flaggedAuthorsCheckbox);
|
||||
@@ -97,7 +97,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should handle checkbox change when removing a target', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
const removedAuthorCheckbox = screen.getByTestId('removed_author');
|
||||
fireEvent.click(removedAuthorCheckbox);
|
||||
@@ -113,14 +113,14 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should disable flagged_reviewers checkbox', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
const flaggedReviewersCheckbox = screen.getByTestId('flagged_reviewers');
|
||||
expect(flaggedReviewersCheckbox).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should not disable other checkboxes', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
expect(screen.getByTestId('flagged_author')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('assigned_reviewers')).not.toBeDisabled();
|
||||
@@ -138,7 +138,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
value: {} as ContentFlaggingNotificationSettings,
|
||||
};
|
||||
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...propsWithoutMapping}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...propsWithoutMapping}/>);
|
||||
|
||||
const flaggedReviewersCheckbox = screen.getByTestId('flagged_reviewers');
|
||||
fireEvent.click(flaggedReviewersCheckbox);
|
||||
@@ -165,7 +165,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
} as ContentFlaggingNotificationSettings,
|
||||
};
|
||||
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...propsWithPartialMapping}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...propsWithPartialMapping}/>);
|
||||
|
||||
const assignedReviewersCheckbox = screen.getByTestId('assigned_reviewers');
|
||||
fireEvent.click(assignedReviewersCheckbox);
|
||||
@@ -179,7 +179,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should not add duplicate targets', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
// Try to add 'reviewers' to flagged again (it's already there)
|
||||
const flaggedReviewersCheckbox = screen.getByTestId('flagged_reviewers');
|
||||
@@ -197,7 +197,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should handle multiple checkbox changes correctly', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
// First change: add author to flagged
|
||||
const flaggedAuthorsCheckbox = screen.getByTestId('flagged_author');
|
||||
@@ -229,7 +229,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
});
|
||||
|
||||
test('should handle unchecking and rechecking the same checkbox', () => {
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...defaultProps}/>);
|
||||
|
||||
const removedAuthorCheckbox = screen.getByTestId('removed_author');
|
||||
|
||||
@@ -271,7 +271,7 @@ describe('ContentFlaggingNotificationSettingsSection', () => {
|
||||
} as unknown as ContentFlaggingNotificationSettings,
|
||||
};
|
||||
|
||||
renderWithIntl(<ContentFlaggingNotificationSettingsSection {...propsWithEmptyArrays}/>);
|
||||
renderWithContext(<ContentFlaggingNotificationSettingsSection {...propsWithEmptyArrays}/>);
|
||||
|
||||
// All checkboxes should be unchecked
|
||||
expect(screen.getByTestId('flagged_reviewers')).not.toBeChecked();
|
||||
|
||||
@@ -1,108 +1,134 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Components/AlertBanner should match snapshot 1`] = `
|
||||
<div
|
||||
className="AlertBanner info AlertBanner--sys"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="AlertBanner__icon"
|
||||
>
|
||||
<InformationOutlineIcon
|
||||
size={24}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__body"
|
||||
class="AlertBanner info AlertBanner--sys"
|
||||
>
|
||||
<div
|
||||
className="AlertBanner__title"
|
||||
class="AlertBanner__icon"
|
||||
>
|
||||
title
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__message"
|
||||
class="AlertBanner__body"
|
||||
>
|
||||
message
|
||||
<div
|
||||
class="AlertBanner__title"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
class="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Components/AlertBanner should match snapshot for app variant 1`] = `
|
||||
<div
|
||||
className="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="AlertBanner__icon"
|
||||
>
|
||||
<InformationOutlineIcon
|
||||
size={24}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__body"
|
||||
class="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div
|
||||
className="AlertBanner__title"
|
||||
class="AlertBanner__icon"
|
||||
>
|
||||
title
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__message"
|
||||
class="AlertBanner__body"
|
||||
>
|
||||
message
|
||||
<div
|
||||
class="AlertBanner__title"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
class="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Components/AlertBanner should match snapshot when buttons are passed 1`] = `
|
||||
<div
|
||||
className="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="AlertBanner__body"
|
||||
class="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div
|
||||
className="AlertBanner__title"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__actionButtons"
|
||||
class="AlertBanner__body"
|
||||
>
|
||||
<div
|
||||
id="actionButtonLeft"
|
||||
/>
|
||||
class="AlertBanner__title"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
id="actionButtonRight"
|
||||
/>
|
||||
class="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
</div>
|
||||
<div
|
||||
class="AlertBanner__actionButtons"
|
||||
>
|
||||
<div
|
||||
id="actionButtonLeft"
|
||||
/>
|
||||
<div
|
||||
id="actionButtonRight"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Components/AlertBanner should match snapshot when icon disabled 1`] = `
|
||||
<div
|
||||
className="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="AlertBanner__body"
|
||||
class="AlertBanner info AlertBanner--app"
|
||||
>
|
||||
<div
|
||||
className="AlertBanner__title"
|
||||
class="AlertBanner__body"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
className="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
<div
|
||||
class="AlertBanner__title"
|
||||
>
|
||||
title
|
||||
</div>
|
||||
<div
|
||||
class="AlertBanner__message"
|
||||
>
|
||||
message
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import AlertBanner from 'components/alert_banner';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import AlertBanner from '.';
|
||||
|
||||
describe('Components/AlertBanner', () => {
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<AlertBanner
|
||||
mode='info'
|
||||
message='message'
|
||||
@@ -16,11 +17,11 @@ describe('Components/AlertBanner', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot for app variant', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<AlertBanner
|
||||
mode='info'
|
||||
message='message'
|
||||
@@ -29,11 +30,11 @@ describe('Components/AlertBanner', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when icon disabled', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<AlertBanner
|
||||
hideIcon={true}
|
||||
mode='info'
|
||||
@@ -43,11 +44,11 @@ describe('Components/AlertBanner', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when buttons are passed', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<AlertBanner
|
||||
hideIcon={true}
|
||||
mode='info'
|
||||
@@ -59,6 +60,6 @@ describe('Components/AlertBanner', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+37
-66
@@ -1,102 +1,73 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/analytics/doughnut_chart.tsx should match snapshot, loaded with data 1`] = `
|
||||
<DoughnutChart
|
||||
data={
|
||||
Object {
|
||||
"datasets": Array [
|
||||
Object {
|
||||
"data": Array [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
height={400}
|
||||
title="Test"
|
||||
width={600}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="col-sm-6"
|
||||
class="col-sm-6"
|
||||
>
|
||||
<div
|
||||
className="total-count"
|
||||
class="total-count"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
class="content"
|
||||
>
|
||||
<canvas
|
||||
height={400}
|
||||
width={600}
|
||||
height="400"
|
||||
width="600"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DoughnutChart>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/doughnut_chart.tsx should match snapshot, loaded without data 1`] = `
|
||||
<DoughnutChart
|
||||
height={400}
|
||||
title="Test"
|
||||
width={600}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="col-sm-6"
|
||||
class="col-sm-6"
|
||||
>
|
||||
<div
|
||||
className="total-count"
|
||||
class="total-count"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
class="content"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Loading..."
|
||||
id="analytics.chart.loading"
|
||||
>
|
||||
<span>
|
||||
Loading...
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/doughnut_chart.tsx should match snapshot, on loading 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="col-sm-6"
|
||||
>
|
||||
<div
|
||||
class="total-count"
|
||||
>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DoughnutChart>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/doughnut_chart.tsx should match snapshot, on loading 1`] = `
|
||||
<div
|
||||
className="col-sm-6"
|
||||
>
|
||||
<div
|
||||
className="total-count"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Loading..."
|
||||
id="analytics.chart.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,82 +1,77 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/analytics/line_chart.tsx should match snapshot, loaded with data 1`] = `
|
||||
<div
|
||||
className="col-sm-12"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count by-day"
|
||||
class="col-sm-12"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="total-count by-day"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<canvas
|
||||
data-labels={
|
||||
Array [
|
||||
"test1",
|
||||
"test2",
|
||||
"test3",
|
||||
]
|
||||
}
|
||||
data-testid="test"
|
||||
height={400}
|
||||
width={600}
|
||||
/>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<canvas
|
||||
data-labels="test1,test2,test3"
|
||||
data-testid="test"
|
||||
height="0"
|
||||
style="display: block; box-sizing: border-box; height: 0px; width: 0px;"
|
||||
width="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/line_chart.tsx should match snapshot, loaded without data 1`] = `
|
||||
<div
|
||||
className="col-sm-12"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count by-day"
|
||||
class="col-sm-12"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="total-count by-day"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<h5>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Not enough data for a meaningful representation."
|
||||
id="analytics.chart.meaningful"
|
||||
/>
|
||||
</h5>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<h5>
|
||||
Not enough data for a meaningful representation.
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/line_chart.tsx should match snapshot, on loading 1`] = `
|
||||
<div
|
||||
className="col-sm-12"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count by-day"
|
||||
class="col-sm-12"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="total-count by-day"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Loading..."
|
||||
id="analytics.chart.loading"
|
||||
/>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+51
-48
@@ -1,78 +1,81 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/analytics/statistic_count.tsx should match snapshot, loaded 1`] = `
|
||||
<div
|
||||
className="grid-statistics__card"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count"
|
||||
class="grid-statistics__card"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
data-testid="undefinedTitle"
|
||||
class="total-count"
|
||||
>
|
||||
Test
|
||||
<i
|
||||
className="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
4
|
||||
<div
|
||||
class="title"
|
||||
data-testid="undefinedTitle"
|
||||
>
|
||||
Test
|
||||
<i
|
||||
class="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
4
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/statistic_count.tsx should match snapshot, loaded with zero value 1`] = `
|
||||
<div
|
||||
className="grid-statistics__card"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count"
|
||||
class="grid-statistics__card"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
data-testid="undefinedTitle"
|
||||
class="total-count"
|
||||
>
|
||||
Test Zero
|
||||
<i
|
||||
className="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
0
|
||||
<div
|
||||
class="title"
|
||||
data-testid="undefinedTitle"
|
||||
>
|
||||
Test Zero
|
||||
<i
|
||||
class="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/statistic_count.tsx should match snapshot, on loading 1`] = `
|
||||
<div
|
||||
className="grid-statistics__card"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count"
|
||||
class="grid-statistics__card"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
data-testid="undefinedTitle"
|
||||
class="total-count"
|
||||
>
|
||||
Test
|
||||
<i
|
||||
className="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Loading..."
|
||||
id="analytics.chart.loading"
|
||||
/>
|
||||
<div
|
||||
class="title"
|
||||
data-testid="undefinedTitle"
|
||||
>
|
||||
Test
|
||||
<i
|
||||
class="fa test-icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,83 +1,75 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/analytics/table_chart.tsx should match snapshot, loaded with data 1`] = `
|
||||
<div
|
||||
className="col-sm-6"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count recent-active-users"
|
||||
class="col-sm-6"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="total-count recent-active-users"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
key="table-entry-test1"
|
||||
>
|
||||
<td>
|
||||
<WithTooltip
|
||||
title="test-tip1"
|
||||
>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<span>
|
||||
test1
|
||||
</span>
|
||||
</WithTooltip>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
test-value1
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
key="table-entry-test2"
|
||||
>
|
||||
<td>
|
||||
<WithTooltip
|
||||
title="test-tip2"
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
test-value1
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>
|
||||
test2
|
||||
</span>
|
||||
</WithTooltip>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
test-value2
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
test-value2
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/analytics/table_chart.tsx should match snapshot, loaded without data 1`] = `
|
||||
<div
|
||||
className="col-sm-6"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="total-count recent-active-users"
|
||||
class="col-sm-6"
|
||||
>
|
||||
<div
|
||||
className="title"
|
||||
class="total-count recent-active-users"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
className="content"
|
||||
>
|
||||
<table>
|
||||
<tbody />
|
||||
</table>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<table>
|
||||
<tbody />
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ChartData} from 'chart.js';
|
||||
import {shallow, mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import DoughnutChart from 'components/analytics/doughnut_chart';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
jest.mock('chart.js');
|
||||
|
||||
describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
test('should match snapshot, on loading', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<DoughnutChart
|
||||
title='Test'
|
||||
height={400}
|
||||
@@ -21,14 +20,14 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded without data', () => {
|
||||
const Chart = jest.requireMock('chart.js');
|
||||
const data: ChartData | undefined = undefined;
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<DoughnutChart
|
||||
title='Test'
|
||||
height={400}
|
||||
@@ -38,7 +37,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
);
|
||||
|
||||
expect(Chart).not.toHaveBeenCalled();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded with data', () => {
|
||||
@@ -49,7 +48,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
],
|
||||
};
|
||||
|
||||
const wrapper = mount(
|
||||
const {container} = renderWithContext(
|
||||
<DoughnutChart
|
||||
title='Test'
|
||||
height={400}
|
||||
@@ -59,7 +58,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
);
|
||||
|
||||
expect(Chart).toHaveBeenCalledWith(expect.anything(), {data, options: {}, type: 'doughnut'});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should create and destroy the chart on mount and unmount with data', () => {
|
||||
@@ -72,7 +71,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
labels: ['test1', 'test2', 'test3'],
|
||||
};
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
const {unmount} = renderWithContext(
|
||||
<DoughnutChart
|
||||
title='Test'
|
||||
height={400}
|
||||
@@ -82,7 +81,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
);
|
||||
|
||||
expect(Chart).toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
unmount();
|
||||
});
|
||||
|
||||
test('should update the chart on data change', () => {
|
||||
@@ -102,7 +101,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
labels: ['test1', 'test2', 'test3', 'test4'],
|
||||
};
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
const {rerender} = renderWithContext(
|
||||
<DoughnutChart
|
||||
title='Test'
|
||||
height={400}
|
||||
@@ -114,10 +113,24 @@ describe('components/analytics/doughnut_chart.tsx', () => {
|
||||
expect(Chart).toHaveBeenCalled();
|
||||
expect(Chart.mock.instances[0].update).not.toHaveBeenCalled();
|
||||
|
||||
wrapper.setProps({title: 'new title'});
|
||||
rerender(
|
||||
<DoughnutChart
|
||||
title='new title'
|
||||
height={400}
|
||||
width={600}
|
||||
data={oldData}
|
||||
/>,
|
||||
);
|
||||
expect(Chart.mock.instances[0].update).not.toHaveBeenCalled();
|
||||
|
||||
wrapper.setProps({data: newData});
|
||||
rerender(
|
||||
<DoughnutChart
|
||||
title='new title'
|
||||
height={400}
|
||||
width={600}
|
||||
data={newData}
|
||||
/>,
|
||||
);
|
||||
expect(Chart.mock.instances[0].update).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import LineChart from 'components/analytics/line_chart';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import LineChart from './line_chart';
|
||||
|
||||
describe('components/analytics/line_chart.tsx', () => {
|
||||
test('should match snapshot, on loading', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<LineChart
|
||||
id='test'
|
||||
title='Test'
|
||||
@@ -17,7 +18,7 @@ describe('components/analytics/line_chart.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded without data', () => {
|
||||
@@ -26,7 +27,7 @@ describe('components/analytics/line_chart.tsx', () => {
|
||||
labels: [],
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<LineChart
|
||||
id='test'
|
||||
title='Test'
|
||||
@@ -36,7 +37,7 @@ describe('components/analytics/line_chart.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded with data', () => {
|
||||
@@ -47,7 +48,7 @@ describe('components/analytics/line_chart.tsx', () => {
|
||||
labels: ['test1', 'test2', 'test3'],
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<LineChart
|
||||
id='test'
|
||||
title='Test'
|
||||
@@ -57,6 +58,6 @@ describe('components/analytics/line_chart.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import StatisticCount from 'components/analytics/statistic_count';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import StatisticCount from './statistic_count';
|
||||
|
||||
describe('components/analytics/statistic_count.tsx', () => {
|
||||
test('should match snapshot, on loading', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<StatisticCount
|
||||
title='Test'
|
||||
icon='test-icon'
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<StatisticCount
|
||||
title='Test'
|
||||
icon='test-icon'
|
||||
@@ -27,11 +28,11 @@ describe('components/analytics/statistic_count.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded with zero value', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<StatisticCount
|
||||
title='Test Zero'
|
||||
icon='test-icon'
|
||||
@@ -39,12 +40,12 @@ describe('components/analytics/statistic_count.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should apply formatter function when provided', () => {
|
||||
const mockFormatter = (value: number) => `${value}%`;
|
||||
const wrapper = shallow(
|
||||
renderWithContext(
|
||||
<StatisticCount
|
||||
title='Test'
|
||||
icon='test-icon'
|
||||
@@ -54,6 +55,6 @@ describe('components/analytics/statistic_count.tsx', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-testid="test-stat"]').text()).toBe('42%');
|
||||
expect(screen.getByTestId('test-stat')).toHaveTextContent('42%');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import TableChart from 'components/analytics/table_chart';
|
||||
import type {TableItem} from 'components/analytics/table_chart';
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import type {TableItem} from './table_chart';
|
||||
import TableChart from './table_chart';
|
||||
|
||||
describe('components/analytics/table_chart.tsx', () => {
|
||||
test('should match snapshot, loaded without data', () => {
|
||||
const data: TableItem[] = [];
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<TableChart
|
||||
title='Test'
|
||||
data={data}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, loaded with data', () => {
|
||||
@@ -27,13 +28,13 @@ describe('components/analytics/table_chart.tsx', () => {
|
||||
{name: 'test2', tip: 'test-tip2', value: <p>{'test-value2'}</p>},
|
||||
];
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<TableChart
|
||||
title='Test'
|
||||
data={data}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,232 +1,186 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning a group followed by punctuation 1`] = `
|
||||
<Fragment>
|
||||
<UserGroupPopoverController
|
||||
group={
|
||||
Object {
|
||||
"allow_reference": true,
|
||||
"create_at": 1,
|
||||
"delete_at": 0,
|
||||
"description": "",
|
||||
"display_name": "group_display_name",
|
||||
"has_syncables": false,
|
||||
"id": "qwerty1",
|
||||
"member_count": 0,
|
||||
"name": "developers",
|
||||
"remote_id": "",
|
||||
"scheme_admin": false,
|
||||
"source": "",
|
||||
"update_at": 1,
|
||||
}
|
||||
}
|
||||
returnFocus={[Function]}
|
||||
<div>
|
||||
<span
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
>
|
||||
<a
|
||||
className="group-mention-link"
|
||||
class="group-mention-link"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
tabindex="0"
|
||||
>
|
||||
@developers
|
||||
</a>
|
||||
</UserGroupPopoverController>
|
||||
</span>
|
||||
.
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning a group that is allowed reference 1`] = `
|
||||
<Fragment>
|
||||
<UserGroupPopoverController
|
||||
group={
|
||||
Object {
|
||||
"allow_reference": true,
|
||||
"create_at": 1,
|
||||
"delete_at": 0,
|
||||
"description": "",
|
||||
"display_name": "group_display_name",
|
||||
"has_syncables": false,
|
||||
"id": "qwerty1",
|
||||
"member_count": 0,
|
||||
"name": "developers",
|
||||
"remote_id": "",
|
||||
"scheme_admin": false,
|
||||
"source": "",
|
||||
"update_at": 1,
|
||||
}
|
||||
}
|
||||
returnFocus={[Function]}
|
||||
<div>
|
||||
<span
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
>
|
||||
<a
|
||||
className="group-mention-link"
|
||||
class="group-mention-link"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
tabindex="0"
|
||||
>
|
||||
@developers
|
||||
</a>
|
||||
</UserGroupPopoverController>
|
||||
</Fragment>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning a group that is allowed reference with group highlight disabled 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-developers
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning a group that is not allowed reference 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-marketing
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning all 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-all
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning all with mixed case 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-aLL
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning current user 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc1/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none mention--highlight"
|
||||
userId="abc1"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none mention--highlight"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@First Last
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc2/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc2"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@Nick
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user containing and followed by punctuation 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc3/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc3"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@Dot Matrix
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</button>
|
||||
.
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user containing punctuation 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc3/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc3"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@Dot Matrix
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user followed by punctuation 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc2/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc2"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@Nick
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</button>
|
||||
...
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user with different teammate name display setting 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc2/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc2"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@user1
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when mentioning user with mixed case 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
returnFocus={[Function]}
|
||||
src="/api/v4/users/abc2/image"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="style--none"
|
||||
userId="abc2"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="style--none"
|
||||
>
|
||||
<span
|
||||
className="mention-link"
|
||||
class="mention-link"
|
||||
>
|
||||
@Nick
|
||||
</span>
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when not mentioning a user 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-notauser
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/AtMention should match snapshot when not mentioning a user with mixed case 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
(at)-NOTAuser
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import AtMention from 'components/at_mention/at_mention';
|
||||
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
/* eslint-disable global-require */
|
||||
import AtMention from './at_mention';
|
||||
|
||||
describe('components/AtMention', () => {
|
||||
const baseProps = {
|
||||
@@ -33,7 +30,7 @@ describe('components/AtMention', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot when mentioning user', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='user1'
|
||||
@@ -42,11 +39,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning user with different teammate name display setting', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='user1'
|
||||
@@ -56,11 +53,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning user followed by punctuation', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='user1...'
|
||||
@@ -69,11 +66,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning user containing punctuation', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='userdot.'
|
||||
@@ -82,11 +79,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning user containing and followed by punctuation', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='userdot..'
|
||||
@@ -95,11 +92,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning user with mixed case', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='USeR1'
|
||||
@@ -108,11 +105,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning current user', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='currentUser'
|
||||
@@ -121,11 +118,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning all', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='all'
|
||||
@@ -134,11 +131,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning all with mixed case', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='aLL'
|
||||
@@ -147,11 +144,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when not mentioning a user', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='notauser'
|
||||
@@ -160,11 +157,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when not mentioning a user with mixed case', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='NOTAuser'
|
||||
@@ -173,11 +170,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning a group that is allowed reference', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='developers'
|
||||
@@ -186,11 +183,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning a group that is allowed reference with group highlight disabled', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='developers'
|
||||
@@ -200,11 +197,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning a group that is not allowed reference', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='marketing'
|
||||
@@ -213,11 +210,11 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when mentioning a group followed by punctuation', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='developers.'
|
||||
@@ -226,7 +223,7 @@ describe('components/AtMention', () => {
|
||||
</AtMention>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('fetchMissingUsers', () => {
|
||||
@@ -245,7 +242,7 @@ describe('components/AtMention', () => {
|
||||
});
|
||||
|
||||
test('when fetchMissingUsers is false, should not fetch an unloaded user on mount', () => {
|
||||
shallow(
|
||||
render(
|
||||
<AtMention
|
||||
{...baseProps}
|
||||
mentionName='someuser'
|
||||
|
||||
@@ -1,58 +1,50 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import * as useOpenPricingModal from 'components/common/hooks/useOpenPricingModal';
|
||||
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import AtPlanMention from './index';
|
||||
|
||||
describe('components/AtPlanMention', () => {
|
||||
it('should open pricing modal when plan mentioned is trial', () => {
|
||||
it('should open pricing modal when plan mentioned is trial', async () => {
|
||||
const openPricingModal = jest.fn();
|
||||
jest.spyOn(useOpenPricingModal, 'default').mockImplementation(() => ({
|
||||
openPricingModal,
|
||||
isAirGapped: false,
|
||||
}));
|
||||
|
||||
const wrapper = shallow(<AtPlanMention plan='Enterprise trial'/>);
|
||||
wrapper.find('a').simulate('click', {
|
||||
preventDefault: () => {
|
||||
},
|
||||
});
|
||||
renderWithContext(<AtPlanMention plan='Enterprise trial'/>);
|
||||
await userEvent.click(screen.getByText('Enterprise trial'));
|
||||
|
||||
expect(openPricingModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should open pricing modal when plan mentioned is Enterprise', () => {
|
||||
it('should open pricing modal when plan mentioned is Enterprise', async () => {
|
||||
const openPricingModal = jest.fn();
|
||||
jest.spyOn(useOpenPricingModal, 'default').mockImplementation(() => ({
|
||||
openPricingModal,
|
||||
isAirGapped: false,
|
||||
}));
|
||||
|
||||
const wrapper = shallow(<AtPlanMention plan='Enterprise plan'/>);
|
||||
wrapper.find('a').simulate('click', {
|
||||
preventDefault: () => {
|
||||
},
|
||||
});
|
||||
renderWithContext(<AtPlanMention plan='Enterprise plan'/>);
|
||||
await userEvent.click(screen.getByText('Enterprise plan'));
|
||||
|
||||
expect(openPricingModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should open purchase modal when plan mentioned is professional', () => {
|
||||
it('should open purchase modal when plan mentioned is professional', async () => {
|
||||
const openPricingModal = jest.fn();
|
||||
jest.spyOn(useOpenPricingModal, 'default').mockImplementation(() => ({
|
||||
openPricingModal,
|
||||
isAirGapped: false,
|
||||
}));
|
||||
|
||||
const wrapper = shallow(<AtPlanMention plan='Professional plan'/>);
|
||||
wrapper.find('a').simulate('click', {
|
||||
preventDefault: () => {
|
||||
},
|
||||
});
|
||||
renderWithContext(<AtPlanMention plan='Professional plan'/>);
|
||||
await userEvent.click(screen.getByText('Professional plan'));
|
||||
|
||||
expect(openPricingModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -64,9 +56,9 @@ describe('components/AtPlanMention', () => {
|
||||
isAirGapped: true,
|
||||
}));
|
||||
|
||||
const wrapper = shallow(<AtPlanMention plan='Enterprise plan'/>);
|
||||
expect(wrapper.find('span').exists()).toBe(true);
|
||||
expect(wrapper.find('a').exists()).toBe(false);
|
||||
expect(wrapper.find('span').text()).toBe('Enterprise plan');
|
||||
renderWithContext(<AtPlanMention plan='Enterprise plan'/>);
|
||||
|
||||
// When air-gapped, renders as span instead of anchor
|
||||
expect(screen.getByText('Enterprise plan').tagName).toBe('SPAN');
|
||||
});
|
||||
});
|
||||
|
||||
+26
-24
@@ -1,31 +1,33 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`/components/common/CircularChart should match snapshot 1`] = `
|
||||
<div
|
||||
className="CircularChart"
|
||||
>
|
||||
<svg
|
||||
className="circular-chart success"
|
||||
height="100"
|
||||
viewBox="0 0 36 36"
|
||||
width="100"
|
||||
<div>
|
||||
<div
|
||||
class="CircularChart"
|
||||
>
|
||||
<path
|
||||
className="circle-bg"
|
||||
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
|
||||
/>
|
||||
<path
|
||||
className="circle"
|
||||
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
|
||||
strokeDasharray="75, 100"
|
||||
/>
|
||||
<text
|
||||
className="percentageOrNumber"
|
||||
x="18"
|
||||
y="20.70"
|
||||
<svg
|
||||
class="circular-chart success"
|
||||
height="100"
|
||||
viewBox="0 0 36 36"
|
||||
width="100"
|
||||
>
|
||||
75
|
||||
</text>
|
||||
</svg>
|
||||
<path
|
||||
class="circle-bg"
|
||||
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
|
||||
/>
|
||||
<path
|
||||
class="circle"
|
||||
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
|
||||
stroke-dasharray="75, 100"
|
||||
/>
|
||||
<text
|
||||
class="percentageOrNumber"
|
||||
x="18"
|
||||
y="20.70"
|
||||
>
|
||||
75
|
||||
</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import CircularChart from 'components/common/circular_chart/circular_chart';
|
||||
import {render, screen} from 'tests/react_testing_utils';
|
||||
|
||||
// import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import CircularChart from './circular_chart';
|
||||
|
||||
describe('/components/common/CircularChart', () => {
|
||||
const baseProps = {
|
||||
@@ -17,33 +16,33 @@ describe('/components/common/CircularChart', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<CircularChart
|
||||
{...baseProps}
|
||||
type={'success'}
|
||||
/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('test circularChart contains the text value as specified in the base props', () => {
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<CircularChart
|
||||
{...baseProps}
|
||||
type={'success'}
|
||||
/>);
|
||||
const circularChartText = wrapper.find('.percentageOrNumber').text();
|
||||
const circularChartText = screen.getByText('75');
|
||||
|
||||
expect(parseInt(circularChartText, 10)).toBe(baseProps.value);
|
||||
expect(circularChartText).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('test circularChart contains the text value with the percentage symbol when isPercentage is set to true', () => {
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<CircularChart
|
||||
{...{...baseProps, isPercentage: true}}
|
||||
type={'success'}
|
||||
/>);
|
||||
const circularChartText = wrapper.find('.percentageOrNumber').text();
|
||||
const circularChartText = screen.getByText('75 %');
|
||||
|
||||
expect(circularChartText).toBe(`${baseProps.value.toString()} %`);
|
||||
expect(circularChartText).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+20
-5
@@ -1,10 +1,25 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/custom_status/custom_status_emoji should match snapshot 1`] = `<CustomStatusEmoji />`;
|
||||
exports[`components/custom_status/custom_status_emoji should match snapshot 1`] = `
|
||||
<div>
|
||||
<span
|
||||
aria-label=":smile:"
|
||||
class="emoticon"
|
||||
data-emoticon="smile"
|
||||
style="background-image: url(\\"/static/emoji/1f604.png\\"); background-size: contain; height: 16px; width: 16px; max-height: 16px; max-width: 16px; min-height: 16px; min-width: 16px; overflow: hidden; margin-left: 4px; margin-top: -1px;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/custom_status/custom_status_emoji should match snapshot with props 1`] = `
|
||||
<CustomStatusEmoji
|
||||
emojiSize={34}
|
||||
showTooltip={true}
|
||||
/>
|
||||
<div>
|
||||
<span>
|
||||
<span
|
||||
aria-label=":smile:"
|
||||
class="emoticon"
|
||||
data-emoticon="smile"
|
||||
style="background-image: url(\\"/static/emoji/1f604.png\\"); background-size: contain; height: 34px; width: 34px; max-height: 34px; max-width: 34px; min-height: 34px; min-width: 34px; overflow: hidden; margin-left: 4px; margin-top: -1px;"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+21
-44
@@ -1,55 +1,32 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/custom_status/custom_status_emoji should match snapshot 1`] = `
|
||||
<button
|
||||
className="statusSuggestion__row cursor--pointer"
|
||||
onClick={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className="statusSuggestion__icon"
|
||||
<div>
|
||||
<button
|
||||
class="statusSuggestion__row cursor--pointer"
|
||||
tabindex="0"
|
||||
>
|
||||
<Memo(RenderEmoji)
|
||||
emojiName=""
|
||||
size={20}
|
||||
<div
|
||||
class="statusSuggestion__icon"
|
||||
/>
|
||||
</div>
|
||||
<CustomStatusText
|
||||
className="statusSuggestion__text"
|
||||
text=""
|
||||
/>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/custom_status/custom_status_emoji should match snapshot with duration 1`] = `
|
||||
<button
|
||||
className="statusSuggestion__row cursor--pointer"
|
||||
onClick={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className="statusSuggestion__icon"
|
||||
<div>
|
||||
<button
|
||||
class="statusSuggestion__row cursor--pointer"
|
||||
tabindex="0"
|
||||
>
|
||||
<Memo(RenderEmoji)
|
||||
emojiName=""
|
||||
size={20}
|
||||
<div
|
||||
class="statusSuggestion__icon"
|
||||
/>
|
||||
</div>
|
||||
<CustomStatusText
|
||||
className="statusSuggestion__text with_duration"
|
||||
text=""
|
||||
/>
|
||||
<span
|
||||
className="statusSuggestion__duration"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Today"
|
||||
id="custom_status.expiry_dropdown.today"
|
||||
/>
|
||||
</span>
|
||||
</button>
|
||||
<span
|
||||
class="statusSuggestion__duration"
|
||||
>
|
||||
Today
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+16
-4
@@ -1,9 +1,21 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/custom_status/custom_status_text should match snapshot 1`] = `<CustomStatusText />`;
|
||||
exports[`components/custom_status/custom_status_text should match snapshot 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="overflow--ellipsis text-nowrap "
|
||||
>
|
||||
Available
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/custom_status/custom_status_text should match snapshot with props 1`] = `
|
||||
<CustomStatusText
|
||||
text="In a meeting"
|
||||
/>
|
||||
<div>
|
||||
<span
|
||||
class="overflow--ellipsis text-nowrap custom-class"
|
||||
>
|
||||
In a meeting
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import * as CustomStatusSelectors from 'selectors/views/custom_status';
|
||||
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import CustomStatusEmoji from './custom_status_emoji';
|
||||
|
||||
@@ -15,42 +13,45 @@ jest.mock('mattermost-redux/selectors/entities/timezone');
|
||||
jest.mock('selectors/views/custom_status');
|
||||
|
||||
describe('components/custom_status/custom_status_emoji', () => {
|
||||
const store = mockStore({});
|
||||
|
||||
const getCustomStatus = () => {
|
||||
return null;
|
||||
const customStatus = {
|
||||
emoji: 'smile',
|
||||
text: 'Happy',
|
||||
};
|
||||
(CustomStatusSelectors.makeGetCustomStatus as jest.Mock).mockReturnValue(getCustomStatus);
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(true);
|
||||
|
||||
beforeEach(() => {
|
||||
(CustomStatusSelectors.makeGetCustomStatus as jest.Mock).mockReturnValue(() => customStatus);
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(true);
|
||||
(CustomStatusSelectors.isCustomStatusExpired as jest.Mock).mockReturnValue(false);
|
||||
});
|
||||
|
||||
it('should match snapshot', () => {
|
||||
const wrapper = mount(<CustomStatusEmoji/>, {wrappingComponent: Provider, wrappingComponentProps: {store}});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = renderWithContext(<CustomStatusEmoji/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot with props', () => {
|
||||
const wrapper = mount(
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusEmoji
|
||||
emojiSize={34}
|
||||
showTooltip={true}
|
||||
/>,
|
||||
{wrappingComponent: Provider, wrappingComponentProps: {store}},
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not render when EnableCustomStatus in config is false', () => {
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(false);
|
||||
const wrapper = mount(<CustomStatusEmoji/>, {wrappingComponent: Provider, wrappingComponentProps: {store}});
|
||||
const {container} = renderWithContext(<CustomStatusEmoji/>);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBeTruthy();
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('should not render when custom status is expired', () => {
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(true);
|
||||
(CustomStatusSelectors.isCustomStatusExpired as jest.Mock).mockReturnValue(true);
|
||||
const wrapper = mount(<CustomStatusEmoji/>, {wrappingComponent: Provider, wrappingComponentProps: {store}});
|
||||
const {container} = renderWithContext(<CustomStatusEmoji/>);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBeTruthy();
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {CustomStatusDuration} from '@mattermost/types/users';
|
||||
|
||||
import {renderWithContext, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import CustomStatusSuggestion from './custom_status_suggestion';
|
||||
|
||||
describe('components/custom_status/custom_status_emoji', () => {
|
||||
@@ -20,11 +21,11 @@ describe('components/custom_status/custom_status_emoji', () => {
|
||||
};
|
||||
|
||||
it('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusSuggestion {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot with duration', () => {
|
||||
@@ -35,29 +36,41 @@ describe('components/custom_status/custom_status_emoji', () => {
|
||||
duration: CustomStatusDuration.TODAY,
|
||||
},
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusSuggestion {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should call handleSuggestionClick when click occurs on div', () => {
|
||||
const wrapper = shallow(
|
||||
it('should call handleSuggestionClick when click occurs on div', async () => {
|
||||
// Suppress the DOM nesting warning (button inside button) which is a component issue
|
||||
const originalError = console.error;
|
||||
console.error = jest.fn();
|
||||
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusSuggestion {...baseProps}/>,
|
||||
);
|
||||
|
||||
wrapper.find('.statusSuggestion__row').simulate('click');
|
||||
await userEvent.click(container.querySelector('.statusSuggestion__row')!);
|
||||
expect(baseProps.handleSuggestionClick).toHaveBeenCalledTimes(1);
|
||||
|
||||
console.error = originalError;
|
||||
});
|
||||
|
||||
it('should render clearButton when hover occurs on div', () => {
|
||||
const wrapper = shallow(
|
||||
it('should render clearButton when hover occurs on div', async () => {
|
||||
// Suppress the DOM nesting warning (button inside button) which is a component issue
|
||||
const originalError = console.error;
|
||||
console.error = jest.fn();
|
||||
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusSuggestion {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.suggestion-clear').exists()).toBeFalsy();
|
||||
wrapper.find('.statusSuggestion__row').simulate('mouseEnter');
|
||||
expect(wrapper.find('.suggestion-clear').exists()).toBeTruthy();
|
||||
expect(container.querySelector('.suggestion-clear')).not.toBeInTheDocument();
|
||||
await userEvent.hover(container.querySelector('.statusSuggestion__row')!);
|
||||
expect(container.querySelector('.suggestion-clear')).toBeInTheDocument();
|
||||
|
||||
console.error = originalError;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import * as CustomStatusSelectors from 'selectors/views/custom_status';
|
||||
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import CustomStatusText from './custom_status_text';
|
||||
|
||||
jest.mock('selectors/views/custom_status');
|
||||
|
||||
describe('components/custom_status/custom_status_text', () => {
|
||||
const store = mockStore({});
|
||||
beforeEach(() => {
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('should match snapshot', () => {
|
||||
const wrapper = mount(<CustomStatusText/>, {wrappingComponent: Provider, wrappingComponentProps: {store}});
|
||||
const {container} = renderWithContext(<CustomStatusText text='Available'/>);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot with props', () => {
|
||||
const wrapper = mount(
|
||||
const {container} = renderWithContext(
|
||||
<CustomStatusText
|
||||
text='In a meeting'
|
||||
className='custom-class'
|
||||
/>,
|
||||
{wrappingComponent: Provider, wrappingComponentProps: {store}},
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not render when EnableCustomStatus in config is false', () => {
|
||||
(CustomStatusSelectors.isCustomStatusEnabled as any as jest.Mock).mockReturnValue(false);
|
||||
const wrapper = mount(<CustomStatusText/>, {wrappingComponent: Provider, wrappingComponentProps: {store}});
|
||||
const {container} = renderWithContext(<CustomStatusText/>);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBeTruthy();
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/error_page/ErrorLink should match snapshot 1`] = `
|
||||
<ForwardRef
|
||||
href="https://docs.mattermost.com/deployment/sso-gitlab.html"
|
||||
location="error_link"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="GitLab"
|
||||
id="error.oauth_missing_code.gitlab.link"
|
||||
/>
|
||||
</ForwardRef>
|
||||
<div>
|
||||
<a
|
||||
href="https://docs.mattermost.com/deployment/sso-gitlab.html?utm_source=mattermost&utm_medium=in-product&utm_content=error_link&uid=uid-123&sid=sid-456&edition=team&server_version=11.4.0"
|
||||
location="error_link"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
GitLab
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+131
-181
@@ -1,208 +1,158 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, channel_not_found type 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="The channel you're requesting is private or does not exist. Please contact an Administrator to be added to the channel."
|
||||
id="error.channel_not_found.message"
|
||||
/>
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
The channel you're requesting is private or does not exist. Please contact an Administrator to be added to the channel.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, channel_not_found type 2`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Your guest account has no channels assigned. Please contact an administrator."
|
||||
id="error.channel_not_found.message_guest"
|
||||
/>
|
||||
</p>
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, channel_not_found type for guest 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
Your guest account has no channels assigned. Please contact an administrator.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, local_storage type 1`] = `
|
||||
<div>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Mattermost was unable to load because a setting in your browser prevents the use of its local storage features. To allow Mattermost to load, try the following actions:"
|
||||
id="error.local_storage.message"
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Enable cookies"
|
||||
id="error.local_storage.help1"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Turn off private browsing"
|
||||
id="error.local_storage.help2"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Use a supported browser (IE 11, Chrome 61+, Firefox 60+, Safari 12+, Edge 42+)"
|
||||
id="error.local_storage.help3"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
Mattermost was unable to load because a setting in your browser prevents the use of its local storage features. To allow Mattermost to load, try the following actions:
|
||||
<ul>
|
||||
<li>
|
||||
Enable cookies
|
||||
</li>
|
||||
<li>
|
||||
Turn off private browsing
|
||||
</li>
|
||||
<li>
|
||||
Use a supported browser (IE 11, Chrome 61+, Firefox 60+, Safari 12+, Edge 42+)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, no type but with message 1`] = `
|
||||
<p>
|
||||
error message
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, no type nor message 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="An error has occurred."
|
||||
id="error.generic.message"
|
||||
/>
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_access_denied type 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="You must authorize Mattermost to log in with {service}."
|
||||
id="error.oauth_access_denied"
|
||||
values={
|
||||
Object {
|
||||
"service": "Gitlab",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_invalid_param type 1`] = `
|
||||
<p>
|
||||
error message
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_invalid_redirect_url type 1`] = `
|
||||
<p>
|
||||
error message
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_missing_code type 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="The service provider {service} did not provide an authorization code in the redirect URL."
|
||||
id="error.oauth_missing_code"
|
||||
values={
|
||||
Object {
|
||||
"service": "Gitlab",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="For {link} make sure your administrator enabled the Google+ API."
|
||||
id="error.oauth_missing_code.google"
|
||||
values={
|
||||
Object {
|
||||
"link": <ErrorLink
|
||||
message={
|
||||
Object {
|
||||
"defaultMessage": "Google Apps",
|
||||
"id": "error.oauth_missing_code.google.link",
|
||||
}
|
||||
}
|
||||
url="https://docs.mattermost.com/deployment/sso-google.html"
|
||||
/>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="For {link} make sure the administrator of your Microsoft organization has enabled the Mattermost app."
|
||||
id="error.oauth_missing_code.office365"
|
||||
values={
|
||||
Object {
|
||||
"link": <ErrorLink
|
||||
message={
|
||||
Object {
|
||||
"defaultMessage": "Entra ID",
|
||||
"id": "error.oauth_missing_code.office365.link",
|
||||
}
|
||||
}
|
||||
url="https://docs.mattermost.com/deployment/sso-office.html"
|
||||
/>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="For {link} please make sure you followed the setup instructions."
|
||||
id="error.oauth_missing_code.gitlab"
|
||||
values={
|
||||
Object {
|
||||
"link": <ErrorLink
|
||||
message={
|
||||
Object {
|
||||
"defaultMessage": "GitLab",
|
||||
"id": "error.oauth_missing_code.gitlab.link",
|
||||
}
|
||||
}
|
||||
url="https://docs.mattermost.com/deployment/sso-gitlab.html"
|
||||
/>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="If you reviewed the above and are still having trouble with configuration, you may post in our {link} where we'll be happy to help with issues during setup."
|
||||
id="error.oauth_missing_code.forum"
|
||||
values={
|
||||
Object {
|
||||
"link": <ErrorLink
|
||||
message={
|
||||
Object {
|
||||
"defaultMessage": "Troubleshooting forum",
|
||||
"id": "error.oauth_missing_code.forum.link",
|
||||
}
|
||||
}
|
||||
url="https://forum.mattermost.com/c/trouble-shoot"
|
||||
/>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
error message
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, no type nor message 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
An error has occurred.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_access_denied type 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
You must authorize Mattermost to log in with Gitlab.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_invalid_param type 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
error message
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_invalid_redirect_url type 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
error message
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, oauth_missing_code type 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<p>
|
||||
The service provider Gitlab did not provide an authorization code in the redirect URL.
|
||||
</p>
|
||||
<p>
|
||||
For
|
||||
<a
|
||||
href="https://docs.mattermost.com/deployment/sso-google.html?utm_source=mattermost&utm_medium=in-product&utm_content=error_link&uid=user-id-123&sid=telemetry-id-456&edition=team&server_version=9.0.0"
|
||||
location="error_link"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Google Apps
|
||||
</a>
|
||||
make sure your administrator enabled the Google+ API.
|
||||
</p>
|
||||
<p>
|
||||
For
|
||||
<a
|
||||
href="https://docs.mattermost.com/deployment/sso-office.html?utm_source=mattermost&utm_medium=in-product&utm_content=error_link&uid=user-id-123&sid=telemetry-id-456&edition=team&server_version=9.0.0"
|
||||
location="error_link"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Entra ID
|
||||
</a>
|
||||
make sure the administrator of your Microsoft organization has enabled the Mattermost app.
|
||||
</p>
|
||||
<p>
|
||||
For
|
||||
<a
|
||||
href="https://docs.mattermost.com/deployment/sso-gitlab.html?utm_source=mattermost&utm_medium=in-product&utm_content=error_link&uid=user-id-123&sid=telemetry-id-456&edition=team&server_version=9.0.0"
|
||||
location="error_link"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
GitLab
|
||||
</a>
|
||||
please make sure you followed the setup instructions.
|
||||
</p>
|
||||
<p>
|
||||
If you reviewed the above and are still having trouble with configuration, you may post in our
|
||||
<a
|
||||
href="https://forum.mattermost.com/c/trouble-shoot?utm_source=mattermost&utm_medium=in-product&utm_content=error_link&uid=user-id-123&sid=telemetry-id-456&edition=team&server_version=9.0.0"
|
||||
location="error_link"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Troubleshooting forum
|
||||
</a>
|
||||
where we'll be happy to help with issues during setup.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, page_not_found type 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="The page you were trying to reach does not exist"
|
||||
id="error.not_found.message"
|
||||
/>
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
The page you were trying to reach does not exist
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, permalink_not_found type 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Permalink belongs to a deleted message or to a channel to which you do not have access."
|
||||
id="permalink.error.access"
|
||||
/>
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
Permalink belongs to a deleted message or to a channel to which you do not have access.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorMessage should match snapshot, team_not_found type 1`] = `
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="The team you're requesting is private or does not exist. Please contact your Administrator for an invitation."
|
||||
id="error.team_not_found.message"
|
||||
/>
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
The team you're requesting is private or does not exist. Please contact your Administrator for an invitation.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,77 +1,67 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, channel_not_found type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Channel Not Found"
|
||||
id="error.channel_not_found.title"
|
||||
/>
|
||||
<div>
|
||||
Channel Not Found
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, local_storage type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Cannot Load Mattermost"
|
||||
id="error.local_storage.title"
|
||||
/>
|
||||
<div>
|
||||
Cannot Load Mattermost
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, no type but with title 1`] = `
|
||||
<Fragment>
|
||||
<div>
|
||||
error title
|
||||
</Fragment>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, no type nor title 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Error"
|
||||
id="error.generic.title"
|
||||
/>
|
||||
<div>
|
||||
Error
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, oauth_access_denied type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Authorization Error"
|
||||
id="error.oauth_access_denied.title"
|
||||
/>
|
||||
<div>
|
||||
Authorization Error
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, oauth_invalid_param type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="OAuth Parameter Error"
|
||||
id="error.oauth_invalid_param.title"
|
||||
/>
|
||||
<div>
|
||||
OAuth Parameter Error
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, oauth_invalid_redirect_url type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="OAuth Parameter Error"
|
||||
id="error.oauth_invalid_param.title"
|
||||
/>
|
||||
<div>
|
||||
OAuth Parameter Error
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, oauth_missing_code type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Mattermost Needs Your Help"
|
||||
id="error.oauth_missing_code.title"
|
||||
/>
|
||||
<div>
|
||||
Mattermost Needs Your Help
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, page_not_found type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Page Not Found"
|
||||
id="error.not_found.title"
|
||||
/>
|
||||
<div>
|
||||
Page Not Found
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, permalink_not_found type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Message Not Found"
|
||||
id="permalink.error.title"
|
||||
/>
|
||||
<div>
|
||||
Message Not Found
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/error_page/ErrorTitle should match snapshot, team_not_found type 1`] = `
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Team Not Found"
|
||||
id="error.team_not_found.title"
|
||||
/>
|
||||
<div>
|
||||
Team Not Found
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import ErrorLink from 'components/error_page/error_link';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import ErrorLink from './error_link';
|
||||
|
||||
describe('components/error_page/ErrorLink', () => {
|
||||
const baseProps = {
|
||||
@@ -16,10 +17,23 @@ describe('components/error_page/ErrorLink', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorLink {...baseProps}/>,
|
||||
{
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'uid-123',
|
||||
},
|
||||
general: {
|
||||
config: {
|
||||
TelemetryId: 'sid-456',
|
||||
Version: '11.4.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import ErrorMessage from 'components/error_page/error_message';
|
||||
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import {ErrorPageTypes} from 'utils/constants';
|
||||
|
||||
import ErrorMessage from './error_message';
|
||||
|
||||
describe('components/error_page/ErrorMessage', () => {
|
||||
const baseProps = {
|
||||
type: ErrorPageTypes.LOCAL_STORAGE,
|
||||
@@ -15,110 +15,136 @@ describe('components/error_page/ErrorMessage', () => {
|
||||
service: '',
|
||||
};
|
||||
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'user-id-123',
|
||||
},
|
||||
general: {
|
||||
config: {
|
||||
TelemetryId: 'telemetry-id-456',
|
||||
Version: '9.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
test('should match snapshot, local_storage type', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...baseProps}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, permalink_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.PERMALINK_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_missing_code type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_MISSING_CODE, service: 'Gitlab'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_access_denied type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_ACCESS_DENIED, service: 'Gitlab'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_invalid_param type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_INVALID_PARAM, message: 'error message'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_invalid_redirect_url type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_INVALID_REDIRECT_URL, message: 'error message'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, page_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.PAGE_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, team_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.TEAM_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, channel_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.CHANNEL_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
const wrapper2 = shallow(
|
||||
<ErrorMessage
|
||||
{...props}
|
||||
isGuest={true}
|
||||
/>,
|
||||
test('should match snapshot, channel_not_found type for guest', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.CHANNEL_NOT_FOUND, isGuest: true};
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper2).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, no type but with message', () => {
|
||||
const props = {...baseProps, type: '', message: 'error message'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, no type nor message', () => {
|
||||
const props = {...baseProps, type: '', message: ''};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorMessage {...props}/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import ErrorTitle from 'components/error_page/error_title';
|
||||
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import {ErrorPageTypes} from 'utils/constants';
|
||||
|
||||
import ErrorTitle from './error_title';
|
||||
|
||||
describe('components/error_page/ErrorTitle', () => {
|
||||
const baseProps = {
|
||||
type: ErrorPageTypes.LOCAL_STORAGE,
|
||||
@@ -15,100 +15,100 @@ describe('components/error_page/ErrorTitle', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot, local_storage type', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, permalink_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.PERMALINK_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_missing_code type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_MISSING_CODE};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_access_denied type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_ACCESS_DENIED};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_invalid_param type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_INVALID_PARAM};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, oauth_invalid_redirect_url type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.OAUTH_INVALID_REDIRECT_URL};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, page_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.PAGE_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, team_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.TEAM_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, channel_not_found type', () => {
|
||||
const props = {...baseProps, type: ErrorPageTypes.CHANNEL_NOT_FOUND};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, no type but with title', () => {
|
||||
const props = {...baseProps, type: '', title: 'error title'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, no type nor title', () => {
|
||||
const props = {...baseProps, type: '', title: ''};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ErrorTitle {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import ExternalImage from './external_image';
|
||||
|
||||
describe('ExternalImage', () => {
|
||||
@@ -23,10 +24,10 @@ describe('ExternalImage', () => {
|
||||
};
|
||||
|
||||
test('should render an image', () => {
|
||||
const wrapper = shallow(<ExternalImage {...baseProps}/>);
|
||||
const {container} = render(<ExternalImage {...baseProps}/>);
|
||||
|
||||
expect(baseProps.children).toHaveBeenCalledWith(baseProps.src);
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an image without image metadata', () => {
|
||||
@@ -35,10 +36,10 @@ describe('ExternalImage', () => {
|
||||
imageMetadata: undefined,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<ExternalImage {...props}/>);
|
||||
const {container} = render(<ExternalImage {...props}/>);
|
||||
|
||||
expect(baseProps.children).toHaveBeenCalledWith(baseProps.src);
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an SVG when enabled', () => {
|
||||
@@ -53,10 +54,10 @@ describe('ExternalImage', () => {
|
||||
src: 'https://example.com/logo.svg',
|
||||
};
|
||||
|
||||
const wrapper = shallow(<ExternalImage {...props}/>);
|
||||
const {container} = render(<ExternalImage {...props}/>);
|
||||
|
||||
expect(props.children).toHaveBeenCalledWith(props.src);
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should not render an SVG when disabled', () => {
|
||||
@@ -72,10 +73,10 @@ describe('ExternalImage', () => {
|
||||
src: 'https://example.com/logo.svg',
|
||||
};
|
||||
|
||||
const wrapper = shallow(<ExternalImage {...props}/>);
|
||||
const {container} = render(<ExternalImage {...props}/>);
|
||||
|
||||
expect(props.children).toHaveBeenCalledWith('');
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should pass src through the image proxy when enabled', () => {
|
||||
@@ -84,9 +85,9 @@ describe('ExternalImage', () => {
|
||||
hasImageProxy: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<ExternalImage {...props}/>);
|
||||
const {container} = render(<ExternalImage {...props}/>);
|
||||
|
||||
expect(props.children).toHaveBeenCalledWith(Client4.getBaseRoute() + '/image?url=' + encodeURIComponent(props.src));
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+94
-43
@@ -1,77 +1,128 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/file_attachment/FilenameOverlay should match snapshot, compact display 1`] = `
|
||||
<WithTooltip
|
||||
title="test_filename"
|
||||
>
|
||||
<div>
|
||||
<a
|
||||
className="post-image__name btn btn-icon btn-sm"
|
||||
class="post-image__name btn btn-icon btn-sm"
|
||||
href="#"
|
||||
onClick={[MockFunction]}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<AttachmentIcon
|
||||
className="icon"
|
||||
/>
|
||||
<span
|
||||
class="icon"
|
||||
>
|
||||
<svg
|
||||
aria-label="Attachment Icon"
|
||||
height="16px"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16px"
|
||||
>
|
||||
<g
|
||||
fill="inherit"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g
|
||||
fill="inherit"
|
||||
fill-rule="nonzero"
|
||||
transform="translate(-1029.000000, -954.000000)"
|
||||
>
|
||||
<g
|
||||
transform="translate(25.000000, 937.000000)"
|
||||
>
|
||||
<g
|
||||
transform="translate(1004.000000, 17.000000)"
|
||||
>
|
||||
<path
|
||||
d="M5.35,15.56 C3.98,15.56 2.61,15.039 1.567,13.997 C0.557,12.984 0,11.642 0,10.212 C0,8.783 0.557,7.44 1.566,6.429 L6.869,1.126 C8.371,-0.376 10.812,-0.375 12.314,1.125 C13.815,2.627 13.815,5.069 12.314,6.57 L7.011,11.873 C6.094,12.792 4.603,12.79 3.687,11.873 C2.771,10.958 2.771,9.467 3.687,8.551 L8.99,3.248 C9.323,2.916 9.861,2.916 10.193,3.248 C10.525,3.579 10.525,4.118 10.193,4.449 L4.89,9.752 C4.637,10.006 4.637,10.418 4.89,10.672 C5.143,10.923 5.555,10.925 5.809,10.672 L11.113,5.369 C11.952,4.53 11.952,3.166 11.113,2.327 C10.276,1.49 8.911,1.488 8.073,2.327 L2.769,7.631 C2.079,8.32 1.699,9.237 1.699,10.212 C1.699,11.188 2.079,12.104 2.768,12.794 C4.19,14.216 6.502,14.216 7.925,12.798 L7.929,12.794 C7.929,12.793 7.929,12.793 7.929,12.793 L15.355,5.369 C15.687,5.037 16.224,5.037 16.556,5.369 C16.888,5.7 16.888,6.239 16.556,6.57 L8.779,14.348 L8.761,14.332 C7.776,15.15 6.562,15.56 5.35,15.56 Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
test_filename
|
||||
</a>
|
||||
</WithTooltip>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_attachment/FilenameOverlay should match snapshot, standard but not downloadable 1`] = `
|
||||
<span
|
||||
className="post-image__name"
|
||||
>
|
||||
test_filename
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="post-image__name"
|
||||
>
|
||||
test_filename
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_attachment/FilenameOverlay should match snapshot, standard display 1`] = `
|
||||
<div
|
||||
className="post-image__name"
|
||||
>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "view_image_popover.download",
|
||||
}
|
||||
}
|
||||
<div>
|
||||
<div
|
||||
class="post-image__name"
|
||||
>
|
||||
<ForwardRef
|
||||
<a
|
||||
aria-label="download"
|
||||
className="btn btn-icon btn-sm"
|
||||
class="btn btn-icon btn-sm"
|
||||
download="test_filename"
|
||||
href="/api/v4/files/thumbnail_id?download=1"
|
||||
location="filename_overlay"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
test_filename
|
||||
</ForwardRef>
|
||||
</WithTooltip>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_attachment/FilenameOverlay should match snapshot, with Download icon as children 1`] = `
|
||||
<div
|
||||
className="post-image__name"
|
||||
>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "view_image_popover.download",
|
||||
}
|
||||
}
|
||||
<div>
|
||||
<div
|
||||
class="post-image__name"
|
||||
>
|
||||
<ForwardRef
|
||||
<a
|
||||
aria-label="download"
|
||||
className="btn btn-icon btn-sm"
|
||||
class="btn btn-icon btn-sm"
|
||||
download="test_filename"
|
||||
href="/api/v4/files/thumbnail_id?download=1"
|
||||
location="filename_overlay"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<AttachmentIcon />
|
||||
</ForwardRef>
|
||||
</WithTooltip>
|
||||
<span>
|
||||
<svg
|
||||
aria-label="Attachment Icon"
|
||||
height="16px"
|
||||
role="img"
|
||||
viewBox="0 0 16 16"
|
||||
width="16px"
|
||||
>
|
||||
<g
|
||||
fill="inherit"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g
|
||||
fill="inherit"
|
||||
fill-rule="nonzero"
|
||||
transform="translate(-1029.000000, -954.000000)"
|
||||
>
|
||||
<g
|
||||
transform="translate(25.000000, 937.000000)"
|
||||
>
|
||||
<g
|
||||
transform="translate(1004.000000, 17.000000)"
|
||||
>
|
||||
<path
|
||||
d="M5.35,15.56 C3.98,15.56 2.61,15.039 1.567,13.997 C0.557,12.984 0,11.642 0,10.212 C0,8.783 0.557,7.44 1.566,6.429 L6.869,1.126 C8.371,-0.376 10.812,-0.375 12.314,1.125 C13.815,2.627 13.815,5.069 12.314,6.57 L7.011,11.873 C6.094,12.792 4.603,12.79 3.687,11.873 C2.771,10.958 2.771,9.467 3.687,8.551 L8.99,3.248 C9.323,2.916 9.861,2.916 10.193,3.248 C10.525,3.579 10.525,4.118 10.193,4.449 L4.89,9.752 C4.637,10.006 4.637,10.418 4.89,10.672 C5.143,10.923 5.555,10.925 5.809,10.672 L11.113,5.369 C11.952,4.53 11.952,3.166 11.113,2.327 C10.276,1.49 8.911,1.488 8.073,2.327 L2.769,7.631 C2.079,8.32 1.699,9.237 1.699,10.212 C1.699,11.188 2.079,12.104 2.768,12.794 C4.19,14.216 6.502,14.216 7.925,12.798 L7.929,12.794 C7.929,12.793 7.929,12.793 7.929,12.793 L15.355,5.369 C15.687,5.037 16.224,5.037 16.556,5.369 C16.888,5.7 16.888,6.239 16.556,6.57 L8.779,14.348 L8.761,14.332 C7.776,15.15 6.562,15.56 5.35,15.56 Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+34
-32
@@ -1,51 +1,53 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`FileThumbnail should render a normal-sized image 1`] = `
|
||||
<div
|
||||
className="post-image normal"
|
||||
style={
|
||||
Object {
|
||||
"backgroundImage": "url(/api/v4/files/thumbnail_id/thumbnail)",
|
||||
"backgroundSize": "cover",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="post-image normal"
|
||||
style="background-image: url(\\"/api/v4/files/thumbnail_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FileThumbnail should render a small image 1`] = `
|
||||
<div
|
||||
className="post-image small"
|
||||
style={
|
||||
Object {
|
||||
"backgroundImage": "url(/api/v4/files/thumbnail_id/thumbnail)",
|
||||
"backgroundSize": "cover",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="post-image small"
|
||||
style="background-image: url(\\"/api/v4/files/thumbnail_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FileThumbnail should render an icon for a PDF 1`] = `
|
||||
<div
|
||||
className="file-icon pdf"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="file-icon pdf"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FileThumbnail should render an icon for a PSD (MM-67077) 1`] = `
|
||||
<div
|
||||
className="file-icon generic"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="file-icon generic"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FileThumbnail should render an icon for an SVG when SVG previews are disabled 1`] = `
|
||||
<div
|
||||
className="file-icon generic"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="file-icon generic"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FileThumbnail should render an svg when svg previews are enabled 1`] = `
|
||||
<img
|
||||
alt="file thumbnail image"
|
||||
className="post-image normal"
|
||||
src="/api/v4/files/thumbnail_id"
|
||||
/>
|
||||
<div>
|
||||
<img
|
||||
alt="file thumbnail image"
|
||||
class="post-image normal"
|
||||
src="/api/v4/files/thumbnail_id"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+18
-17
@@ -1,9 +1,10 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import FileThumbnail from './file_thumbnail';
|
||||
|
||||
describe('FileThumbnail', () => {
|
||||
@@ -29,11 +30,11 @@ describe('FileThumbnail', () => {
|
||||
};
|
||||
|
||||
test('should render a small image', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render a normal-sized image', () => {
|
||||
@@ -46,11 +47,11 @@ describe('FileThumbnail', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render an svg when svg previews are enabled', () => {
|
||||
@@ -63,12 +64,12 @@ describe('FileThumbnail', () => {
|
||||
enableSVGs: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('img').exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(container.querySelector('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an icon for an SVG when SVG previews are disabled', () => {
|
||||
@@ -81,12 +82,12 @@ describe('FileThumbnail', () => {
|
||||
enableSVGs: false,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('div.file-icon').exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(container.querySelector('div.file-icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an icon for a PDF', () => {
|
||||
@@ -98,12 +99,12 @@ describe('FileThumbnail', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('div.file-icon').exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(container.querySelector('div.file-icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an icon for a PSD (MM-67077)', () => {
|
||||
@@ -115,11 +116,11 @@ describe('FileThumbnail', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FileThumbnail {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('div.file-icon').exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(container.querySelector('div.file-icon')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import FilenameOverlay from 'components/file_attachment/filename_overlay';
|
||||
import AttachmentIcon from 'components/widgets/icons/attachment_icon';
|
||||
|
||||
import {render, renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
describe('components/file_attachment/FilenameOverlay', () => {
|
||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||
const fileInfo = {
|
||||
@@ -35,47 +36,47 @@ describe('components/file_attachment/FilenameOverlay', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot, standard display', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FilenameOverlay {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, compact display', () => {
|
||||
test('should match snapshot, compact display', async () => {
|
||||
const handleImageClick = jest.fn();
|
||||
const props = {...baseProps, compactDisplay: true, handleImageClick};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FilenameOverlay {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find(AttachmentIcon).exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(container.querySelector('.icon')).toBeInTheDocument();
|
||||
|
||||
wrapper.find('a').first().simulate('click');
|
||||
await userEvent.click(screen.getByRole('link'));
|
||||
expect(handleImageClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should match snapshot, with Download icon as children', () => {
|
||||
const props = {...baseProps, canDownload: true};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FilenameOverlay {...props}>
|
||||
<AttachmentIcon/>
|
||||
</FilenameOverlay>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find(AttachmentIcon).exists()).toBe(true);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(screen.getByRole('img', {name: 'Attachment Icon'})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should match snapshot, standard but not downloadable', () => {
|
||||
const props = {...baseProps, canDownload: false};
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<FilenameOverlay {...props}>
|
||||
<AttachmentIcon/>
|
||||
</FilenameOverlay>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+47
-43
@@ -1,65 +1,69 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/FileInfoPreview should match snapshot, can download files 1`] = `
|
||||
<div
|
||||
className="file-details__container"
|
||||
>
|
||||
<a
|
||||
className="file-details__preview"
|
||||
href="https://pre-release.mattermost.com/api/v4/files/rqir81f7a7ft8m6j6ej7g1txuo"
|
||||
>
|
||||
<span
|
||||
className="file-details__preview-helper"
|
||||
/>
|
||||
<img
|
||||
alt="file preview"
|
||||
src=""
|
||||
/>
|
||||
</a>
|
||||
<div>
|
||||
<div
|
||||
className="file-details"
|
||||
class="file-details__container"
|
||||
>
|
||||
<div
|
||||
className="file-details__name"
|
||||
<a
|
||||
class="file-details__preview"
|
||||
href="https://pre-release.mattermost.com/api/v4/files/rqir81f7a7ft8m6j6ej7g1txuo"
|
||||
>
|
||||
Test Image
|
||||
</div>
|
||||
<span
|
||||
class="file-details__preview-helper"
|
||||
/>
|
||||
<img
|
||||
alt="file preview"
|
||||
src=""
|
||||
/>
|
||||
</a>
|
||||
<div
|
||||
className="file-details__info"
|
||||
class="file-details"
|
||||
>
|
||||
File type JPG, Size 100B
|
||||
<div
|
||||
class="file-details__name"
|
||||
>
|
||||
Test Image
|
||||
</div>
|
||||
<div
|
||||
class="file-details__info"
|
||||
>
|
||||
File type JPG, Size 100B
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FileInfoPreview should match snapshot, cannot download files 1`] = `
|
||||
<div
|
||||
className="file-details__container"
|
||||
>
|
||||
<span
|
||||
className="file-details__preview"
|
||||
<div>
|
||||
<div
|
||||
class="file-details__container"
|
||||
>
|
||||
<span
|
||||
className="file-details__preview-helper"
|
||||
/>
|
||||
<img
|
||||
alt="file preview"
|
||||
src=""
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className="file-details"
|
||||
>
|
||||
<div
|
||||
className="file-details__name"
|
||||
class="file-details__preview"
|
||||
>
|
||||
Test Image 2
|
||||
</div>
|
||||
<span
|
||||
class="file-details__preview-helper"
|
||||
/>
|
||||
<img
|
||||
alt="file preview"
|
||||
src=""
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className="file-details__info"
|
||||
class="file-details"
|
||||
>
|
||||
File type PNG, Size 200B
|
||||
<div
|
||||
class="file-details__name"
|
||||
>
|
||||
Test Image 2
|
||||
</div>
|
||||
<div
|
||||
class="file-details__info"
|
||||
>
|
||||
File type PNG, Size 200B
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import type {FileInfo} from '@mattermost/types/files';
|
||||
|
||||
import FileInfoPreview from 'components/file_info_preview/file_info_preview';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import FileInfoPreview from './file_info_preview';
|
||||
|
||||
describe('components/FileInfoPreview', () => {
|
||||
test('should match snapshot, can download files', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileInfoPreview
|
||||
fileUrl='https://pre-release.mattermost.com/api/v4/files/rqir81f7a7ft8m6j6ej7g1txuo'
|
||||
fileInfo={{name: 'Test Image', size: 100, extension: 'jpg'} as FileInfo}
|
||||
@@ -18,11 +19,11 @@ describe('components/FileInfoPreview', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, cannot download files', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileInfoPreview
|
||||
fileUrl='https://pre-release.mattermost.com/api/v4/files/aasf9afshaskj1asf91jasf0a0'
|
||||
fileInfo={{name: 'Test Image 2', size: 200, extension: 'png'} as FileInfo}
|
||||
@@ -30,6 +31,6 @@ describe('components/FileInfoPreview', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+163
-350
@@ -1,415 +1,228 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/file_search_result/FileSearchResultItem should match snapshot 1`] = `
|
||||
<div
|
||||
className="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<button
|
||||
className="FileSearchResultItem"
|
||||
onClick={[Function]}
|
||||
<div>
|
||||
<div
|
||||
class="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<Connect(Component)
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="fileData"
|
||||
<button
|
||||
class="FileSearchResultItem"
|
||||
>
|
||||
<div
|
||||
className="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
class="post-image normal"
|
||||
style="background-image: url(\\"/api/v4/files/file_info_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
<div
|
||||
className="fileMetadata"
|
||||
class="fileData"
|
||||
>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<Connect(injectIntl(Timestamp))
|
||||
ranges={
|
||||
Array [
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Today"
|
||||
id="date_separator.today"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
0,
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Yesterday"
|
||||
id="date_separator.yesterday"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
-1,
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
<div
|
||||
class="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
<div
|
||||
class="fileMetadata"
|
||||
>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<time
|
||||
datetime="1970-01-01T00:00:00.001"
|
||||
>
|
||||
January 01, 1970 at 12:00 AM
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "file_search_result_item.download",
|
||||
}
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="action-icon download-icon btn btn-icon btn-sm"
|
||||
class="action-icon download-icon btn btn-icon btn-sm"
|
||||
href="/api/v4/files/file_info_id?download=1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="icon icon-download-outline"
|
||||
class="icon icon-download-outline"
|
||||
/>
|
||||
</a>
|
||||
</WithTooltip>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_search_result/FileSearchResultItem should match snapshot with DM 1`] = `
|
||||
<div
|
||||
className="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<button
|
||||
className="FileSearchResultItem"
|
||||
onClick={[Function]}
|
||||
<div>
|
||||
<div
|
||||
class="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<Connect(Component)
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="fileData"
|
||||
<button
|
||||
class="FileSearchResultItem"
|
||||
>
|
||||
<div
|
||||
className="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
class="post-image normal"
|
||||
style="background-image: url(\\"/api/v4/files/file_info_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
<div
|
||||
className="fileMetadata"
|
||||
class="fileData"
|
||||
>
|
||||
<Memo(Tag)
|
||||
className="file-search-channel-name"
|
||||
text={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Direct Message"
|
||||
id="search_item.file_tag.direct_message"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<Connect(injectIntl(Timestamp))
|
||||
ranges={
|
||||
Array [
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Today"
|
||||
id="date_separator.today"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
0,
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Yesterday"
|
||||
id="date_separator.yesterday"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
-1,
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
<div
|
||||
class="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
<div
|
||||
class="fileMetadata"
|
||||
>
|
||||
<div
|
||||
class="TagWrapper-kezsCu gCuUKH Tag Tag--xs file-search-channel-name"
|
||||
>
|
||||
<span
|
||||
class="TagText-bWoQAI beIloY"
|
||||
>
|
||||
Direct Message
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<time
|
||||
datetime="1970-01-01T00:00:00.001"
|
||||
>
|
||||
January 01, 1970 at 12:00 AM
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "file_search_result_item.download",
|
||||
}
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="action-icon download-icon btn btn-icon btn-sm"
|
||||
class="action-icon download-icon btn btn-icon btn-sm"
|
||||
href="/api/v4/files/file_info_id?download=1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="icon icon-download-outline"
|
||||
class="icon icon-download-outline"
|
||||
/>
|
||||
</a>
|
||||
</WithTooltip>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_search_result/FileSearchResultItem should match snapshot with GM 1`] = `
|
||||
<div
|
||||
className="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<button
|
||||
className="FileSearchResultItem"
|
||||
onClick={[Function]}
|
||||
<div>
|
||||
<div
|
||||
class="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<Connect(Component)
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="fileData"
|
||||
<button
|
||||
class="FileSearchResultItem"
|
||||
>
|
||||
<div
|
||||
className="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
class="post-image normal"
|
||||
style="background-image: url(\\"/api/v4/files/file_info_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
<div
|
||||
className="fileMetadata"
|
||||
class="fileData"
|
||||
>
|
||||
<Memo(Tag)
|
||||
className="file-search-channel-name"
|
||||
text={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Group Message"
|
||||
id="search_item.file_tag.group_message"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<Connect(injectIntl(Timestamp))
|
||||
ranges={
|
||||
Array [
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Today"
|
||||
id="date_separator.today"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
0,
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Yesterday"
|
||||
id="date_separator.yesterday"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
-1,
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
<div
|
||||
class="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
<div
|
||||
class="fileMetadata"
|
||||
>
|
||||
<div
|
||||
class="TagWrapper-kezsCu gCuUKH Tag Tag--xs file-search-channel-name"
|
||||
>
|
||||
<span
|
||||
class="TagText-bWoQAI beIloY"
|
||||
>
|
||||
Group Message
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<time
|
||||
datetime="1970-01-01T00:00:00.001"
|
||||
>
|
||||
January 01, 1970 at 12:00 AM
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "file_search_result_item.download",
|
||||
}
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="action-icon download-icon btn btn-icon btn-sm"
|
||||
class="action-icon download-icon btn btn-icon btn-sm"
|
||||
href="/api/v4/files/file_info_id?download=1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="icon icon-download-outline"
|
||||
class="icon icon-download-outline"
|
||||
/>
|
||||
</a>
|
||||
</WithTooltip>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/file_search_result/FileSearchResultItem should match snapshot with channel name 1`] = `
|
||||
<div
|
||||
className="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<button
|
||||
className="FileSearchResultItem"
|
||||
onClick={[Function]}
|
||||
<div>
|
||||
<div
|
||||
class="search-item__container"
|
||||
data-testid="search-item-container"
|
||||
>
|
||||
<Connect(Component)
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="fileData"
|
||||
<button
|
||||
class="FileSearchResultItem"
|
||||
>
|
||||
<div
|
||||
className="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
class="post-image normal"
|
||||
style="background-image: url(\\"/api/v4/files/file_info_id/thumbnail\\"); background-size: cover;"
|
||||
/>
|
||||
<div
|
||||
className="fileMetadata"
|
||||
class="fileData"
|
||||
>
|
||||
<Memo(Tag)
|
||||
className="file-search-channel-name"
|
||||
text="test"
|
||||
/>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<Connect(injectIntl(Timestamp))
|
||||
ranges={
|
||||
Array [
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Today"
|
||||
id="date_separator.today"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
0,
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Yesterday"
|
||||
id="date_separator.yesterday"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
-1,
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
<div
|
||||
class="fileDataName"
|
||||
>
|
||||
name
|
||||
</div>
|
||||
<div
|
||||
class="fileMetadata"
|
||||
>
|
||||
<div
|
||||
class="TagWrapper-kezsCu gCuUKH Tag Tag--xs file-search-channel-name"
|
||||
>
|
||||
<span
|
||||
class="TagText-bWoQAI beIloY"
|
||||
>
|
||||
test
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
1B
|
||||
</span>
|
||||
<span>
|
||||
•
|
||||
</span>
|
||||
<time
|
||||
datetime="1970-01-01T00:00:00.001"
|
||||
>
|
||||
January 01, 1970 at 12:00 AM
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<WithTooltip
|
||||
title={
|
||||
Object {
|
||||
"defaultMessage": "Download",
|
||||
"id": "file_search_result_item.download",
|
||||
}
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="action-icon download-icon btn btn-icon btn-sm"
|
||||
class="action-icon download-icon btn btn-icon btn-sm"
|
||||
href="/api/v4/files/file_info_id?download=1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="icon icon-download-outline"
|
||||
class="icon icon-download-outline"
|
||||
/>
|
||||
</a>
|
||||
</WithTooltip>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+9
-10
@@ -1,12 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import type {ShallowWrapper} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import type {ChannelType} from '@mattermost/types/channels';
|
||||
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -28,11 +27,11 @@ describe('components/file_search_result/FileSearchResultItem', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper: ShallowWrapper<any, any, FileSearchResultItem> = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileSearchResultItem {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with channel name', () => {
|
||||
@@ -41,11 +40,11 @@ describe('components/file_search_result/FileSearchResultItem', () => {
|
||||
channelDisplayName: 'test',
|
||||
};
|
||||
|
||||
const wrapper: ShallowWrapper<any, any, FileSearchResultItem> = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileSearchResultItem {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with DM', () => {
|
||||
@@ -55,11 +54,11 @@ describe('components/file_search_result/FileSearchResultItem', () => {
|
||||
channelType: Constants.DM_CHANNEL as ChannelType,
|
||||
};
|
||||
|
||||
const wrapper: ShallowWrapper<any, any, FileSearchResultItem> = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileSearchResultItem {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with GM', () => {
|
||||
@@ -69,10 +68,10 @@ describe('components/file_search_result/FileSearchResultItem', () => {
|
||||
channelType: Constants.GM_CHANNEL as ChannelType,
|
||||
};
|
||||
|
||||
const wrapper: ShallowWrapper<any, any, FileSearchResultItem> = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileSearchResultItem {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+45
-48
@@ -1,78 +1,75 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/FileUploadOverlay should match snapshot when file upload is showing with no overlay type 1`] = `
|
||||
<div
|
||||
className="file-overlay hidden"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="overlay__indent"
|
||||
class="file-overlay hidden"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div
|
||||
className="overlay__circle vertical"
|
||||
class="overlay__indent"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Drop a file to upload it."
|
||||
id="upload_overlay.info"
|
||||
/>
|
||||
<div
|
||||
class="overlay__circle vertical"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
Drop a file to upload it.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FileUploadOverlay should match snapshot when file upload is showing with overlay type of center 1`] = `
|
||||
<div
|
||||
className="file-overlay hidden center-file-overlay"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="overlay__indent"
|
||||
class="file-overlay hidden center-file-overlay"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div
|
||||
className="overlay__circle vertical"
|
||||
class="overlay__indent"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Drop a file to upload it."
|
||||
id="upload_overlay.info"
|
||||
/>
|
||||
<div
|
||||
class="overlay__circle vertical"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
Drop a file to upload it.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/FileUploadOverlay should match snapshot when file upload is showing with overlay type of right 1`] = `
|
||||
<div
|
||||
className="file-overlay hidden right-file-overlay"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="overlay__indent"
|
||||
class="file-overlay hidden right-file-overlay"
|
||||
id="fileUploadOverlay"
|
||||
>
|
||||
<div
|
||||
className="overlay__circle vertical"
|
||||
class="overlay__indent"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Drop a file to upload it."
|
||||
id="upload_overlay.info"
|
||||
/>
|
||||
<div
|
||||
class="overlay__circle vertical"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
Drop a file to upload it.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import FileUploadOverlay from 'components/file_upload_overlay/index';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import FileUploadOverlay from './index';
|
||||
|
||||
describe('components/FileUploadOverlay', () => {
|
||||
test('should match snapshot when file upload is showing with no overlay type', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileUploadOverlay
|
||||
overlayType=''
|
||||
id={'fileUploadOverlay'}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when file upload is showing with overlay type of right', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileUploadOverlay
|
||||
overlayType='right'
|
||||
id={'fileUploadOverlay'}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when file upload is showing with overlay type of center', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<FileUploadOverlay
|
||||
overlayType='center'
|
||||
id={'fileUploadOverlay'}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {IntlProvider} from 'react-intl';
|
||||
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import FormattedMarkdownMessage from './formatted_markdown_message';
|
||||
|
||||
jest.unmock('react-intl');
|
||||
@@ -15,8 +16,8 @@ describe('components/FormattedMarkdownMessage', () => {
|
||||
id: 'test.foo',
|
||||
defaultMessage: '**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)',
|
||||
};
|
||||
const wrapper = mount(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should backup to default', () => {
|
||||
@@ -24,8 +25,8 @@ describe('components/FormattedMarkdownMessage', () => {
|
||||
id: 'xxx',
|
||||
defaultMessage: 'testing default message',
|
||||
};
|
||||
const wrapper = mount(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should escape non-BR', () => {
|
||||
@@ -37,8 +38,8 @@ describe('components/FormattedMarkdownMessage', () => {
|
||||
script: (...content: string[]) => `<script>${content}</script>`,
|
||||
},
|
||||
};
|
||||
const wrapper = mount(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('values should work', () => {
|
||||
@@ -49,8 +50,8 @@ describe('components/FormattedMarkdownMessage', () => {
|
||||
petName: 'sweetie',
|
||||
},
|
||||
};
|
||||
const wrapper = mount(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should allow to disable links', () => {
|
||||
@@ -62,12 +63,12 @@ describe('components/FormattedMarkdownMessage', () => {
|
||||
},
|
||||
disableLinks: true,
|
||||
};
|
||||
const wrapper = mount(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(wrapProvider(<FormattedMarkdownMessage {...props}/>));
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
export function wrapProvider(el: JSX.Element) {
|
||||
function wrapProvider(el: JSX.Element) {
|
||||
const enTranslationData = {
|
||||
'test.foo': '**bold** *italic* [link](https://mattermost.com/) <br/> [link target blank](!https://mattermost.com/)',
|
||||
'test.bar': '<b>hello</b> <script>var malicious = true;</script> world!',
|
||||
@@ -79,6 +80,6 @@ export function wrapProvider(el: JSX.Element) {
|
||||
messages={enTranslationData}
|
||||
>
|
||||
{el}
|
||||
</IntlProvider>)
|
||||
;
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
|
||||
import GetLinkModal from 'components/get_link_modal';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {act} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, act, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
describe('components/GetLinkModal', () => {
|
||||
const onHide = jest.fn();
|
||||
@@ -32,87 +29,116 @@ describe('components/GetLinkModal', () => {
|
||||
const helpText = 'help text';
|
||||
const props = {...requiredProps, helpText};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {baseElement} = renderWithContext(
|
||||
<GetLinkModal {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when helpText is not set', () => {
|
||||
const wrapper = shallow(
|
||||
const {baseElement} = renderWithContext(
|
||||
<GetLinkModal {...requiredProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should have called onHide', () => {
|
||||
test('should have called onHide when close button is clicked', async () => {
|
||||
const user = userEvent.setup({advanceTimers: jest.advanceTimersByTime});
|
||||
const newOnHide = jest.fn();
|
||||
const props = {...requiredProps, onHide: newOnHide};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {baseElement} = renderWithContext(
|
||||
<GetLinkModal {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.find(Modal).first().props().onHide();
|
||||
// Click the modal header X button (triggers Modal's onHide)
|
||||
const modalCloseButton = baseElement.querySelector('.close') as HTMLElement;
|
||||
await user.click(modalCloseButton);
|
||||
expect(newOnHide).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.state('copiedLink')).toBe(false);
|
||||
|
||||
wrapper.setProps({show: true});
|
||||
wrapper.setState({copiedLink: true});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.state('copiedLink')).toBe(true);
|
||||
// Copy link to set copiedLink state to true
|
||||
const copyButton = screen.getByRole('button', {name: /Copy Link/});
|
||||
await user.click(copyButton);
|
||||
expect(copyButton).toHaveTextContent('Copied');
|
||||
expect(copyButton).toHaveClass('btn-success');
|
||||
|
||||
wrapper.find('#linkModalCloseButton').simulate('click');
|
||||
// Take snapshot with copied state
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
|
||||
// Click the footer close button
|
||||
const footerCloseButton = baseElement.querySelector('#linkModalCloseButton') as HTMLElement;
|
||||
await user.click(footerCloseButton);
|
||||
expect(newOnHide).toHaveBeenCalledTimes(2);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.state('copiedLink')).toBe(false);
|
||||
|
||||
// Take snapshot after closing (copiedLink should be reset)
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
|
||||
// Verify copiedLink was reset (button should show Copy Link, not Copied)
|
||||
expect(copyButton).toHaveTextContent('Copy Link');
|
||||
expect(copyButton).not.toHaveClass('btn-success');
|
||||
});
|
||||
|
||||
test('should have handle copyLink', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
test('should have handle copyLink', async () => {
|
||||
const user = userEvent.setup({advanceTimers: jest.advanceTimersByTime});
|
||||
const {baseElement} = renderWithContext(
|
||||
<GetLinkModal {...requiredProps}/>,
|
||||
);
|
||||
wrapper.find('#linkModalTextArea').simulate('click');
|
||||
expect(wrapper.state('copiedLink')).toBe(true);
|
||||
});
|
||||
|
||||
test('should change button state when copying', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<GetLinkModal {...requiredProps}/>,
|
||||
);
|
||||
const textarea = baseElement.querySelector('#linkModalTextArea') as HTMLElement;
|
||||
const copyButton = screen.getByRole('button', {name: /Copy Link/});
|
||||
|
||||
// Initial state
|
||||
expect(wrapper.find('#linkModalCopyLink').text()).toContain('Copy Link');
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-primary')).toBe(true);
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-success')).toBe(false);
|
||||
expect(copyButton).toHaveTextContent('Copy Link');
|
||||
|
||||
// Click on the textarea triggers copyLink
|
||||
await user.click(textarea);
|
||||
|
||||
// Button should now show "Copied"
|
||||
expect(copyButton).toHaveTextContent('Copied');
|
||||
expect(copyButton).toHaveClass('btn-success');
|
||||
});
|
||||
|
||||
test('should change button state when copying', async () => {
|
||||
const user = userEvent.setup({advanceTimers: jest.advanceTimersByTime});
|
||||
renderWithContext(
|
||||
<GetLinkModal {...requiredProps}/>,
|
||||
);
|
||||
|
||||
const copyButton = screen.getByRole('button', {name: /Copy Link/});
|
||||
|
||||
// Initial state
|
||||
expect(copyButton).toHaveTextContent('Copy Link');
|
||||
expect(copyButton).toHaveClass('btn-primary');
|
||||
expect(copyButton).not.toHaveClass('btn-success');
|
||||
|
||||
// After copying
|
||||
wrapper.find('#linkModalCopyLink').simulate('click');
|
||||
expect(wrapper.find('#linkModalCopyLink').text()).toContain('Copied');
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-primary')).toBe(true);
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-success')).toBe(true);
|
||||
await user.click(copyButton);
|
||||
expect(copyButton).toHaveTextContent('Copied');
|
||||
expect(copyButton).toHaveClass('btn-primary');
|
||||
expect(copyButton).toHaveClass('btn-success');
|
||||
|
||||
// After timeout
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('#linkModalCopyLink').text()).toContain('Copy Link');
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-primary')).toBe(true);
|
||||
expect(wrapper.find('#linkModalCopyLink').hasClass('btn-success')).toBe(false);
|
||||
expect(copyButton).toHaveTextContent('Copy Link');
|
||||
expect(copyButton).toHaveClass('btn-primary');
|
||||
expect(copyButton).not.toHaveClass('btn-success');
|
||||
});
|
||||
|
||||
test('should cleanup timeout on unmount', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
test('should cleanup timeout on unmount', async () => {
|
||||
const user = userEvent.setup({advanceTimers: jest.advanceTimersByTime});
|
||||
const {unmount} = renderWithContext(
|
||||
<GetLinkModal {...requiredProps}/>,
|
||||
);
|
||||
|
||||
wrapper.find('#linkModalCopyLink').simulate('click');
|
||||
expect(wrapper.state('copiedLink')).toBe(true);
|
||||
const copyButton = screen.getByRole('button', {name: /Copy Link/});
|
||||
await user.click(copyButton);
|
||||
expect(copyButton).toHaveTextContent('Copied');
|
||||
|
||||
wrapper.unmount();
|
||||
unmount();
|
||||
jest.advanceTimersByTime(1000);
|
||||
|
||||
// If we get here without errors, the timeout was properly cleaned up
|
||||
|
||||
@@ -1,24 +1,38 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/HintToast should match snapshot 1`] = `
|
||||
<div
|
||||
className="hint-toast"
|
||||
data-testid="hint-toast"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="hint-toast__message"
|
||||
class="hint-toast"
|
||||
data-testid="hint-toast"
|
||||
>
|
||||
A hint
|
||||
</div>
|
||||
<div
|
||||
className="hint-toast__dismiss"
|
||||
data-testid="dismissHintToast"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<CloseIcon
|
||||
className="close-btn"
|
||||
id="dismissHintToast"
|
||||
/>
|
||||
<div
|
||||
class="hint-toast__message"
|
||||
>
|
||||
A hint
|
||||
</div>
|
||||
<div
|
||||
class="hint-toast__dismiss"
|
||||
data-testid="dismissHintToast"
|
||||
>
|
||||
<span
|
||||
class="close-btn"
|
||||
id="dismissHintToast"
|
||||
>
|
||||
<svg
|
||||
aria-label="Close Icon"
|
||||
height="24px"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
width="24px"
|
||||
>
|
||||
<path
|
||||
d="M18 7.209L16.791 6 12 10.791 7.209 6 6 7.209 10.791 12 6 16.791 7.209 18 12 13.209 16.791 18 18 16.791 13.209 12z"
|
||||
fill-rule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {render, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import {HintToast} from './hint_toast';
|
||||
|
||||
describe('components/HintToast', () => {
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<HintToast
|
||||
onDismiss={jest.fn()}
|
||||
>{'A hint'}</HintToast>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should fire onDismiss callback', () => {
|
||||
test('should fire onDismiss callback', async () => {
|
||||
const dismissHandler = jest.fn();
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<HintToast
|
||||
onDismiss={dismissHandler}
|
||||
>{'A hint'}</HintToast>,
|
||||
);
|
||||
|
||||
wrapper.find('.hint-toast__dismiss').simulate('click');
|
||||
await userEvent.click(screen.getByTestId('dismissHintToast'));
|
||||
|
||||
expect(dismissHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
|
||||
import {renderWithContext, screen, userEvent, waitFor} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import ListModal, {DEFAULT_NUM_PER_PAGE} from './list_modal';
|
||||
@@ -21,7 +21,7 @@ describe('components/ListModal', () => {
|
||||
const totalCount = mockItems.length + mockItemsPage2.length;
|
||||
|
||||
const baseProps = {
|
||||
loadItems: async (pageNumber: number, searchTerm: string) => {
|
||||
loadItems: jest.fn(async (pageNumber: number, searchTerm: string) => {
|
||||
if (searchTerm === mockSearchTerm) {
|
||||
return {items: mockItemsSearch, totalCount};
|
||||
}
|
||||
@@ -29,12 +29,13 @@ describe('components/ListModal', () => {
|
||||
return {items: mockItems, totalCount};
|
||||
}
|
||||
return {items: mockItemsPage2, totalCount};
|
||||
},
|
||||
}),
|
||||
renderRow: (item: Group) => {
|
||||
return (
|
||||
<div
|
||||
className='item'
|
||||
key={item.id}
|
||||
data-testid={`item-${item.id}`}
|
||||
>
|
||||
{item.id}
|
||||
</div>
|
||||
@@ -47,74 +48,151 @@ describe('components/ListModal', () => {
|
||||
titleBarButtonTextOnClick: () => {},
|
||||
};
|
||||
|
||||
it('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
it('should match snapshot', async () => {
|
||||
const {baseElement} = renderWithContext(
|
||||
<ListModal {...baseProps}/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
setTimeout(() => {
|
||||
expect(wrapper.state('items')).toEqual(mockItems);
|
||||
expect(wrapper.state('totalCount')).toEqual(totalCount);
|
||||
expect(wrapper.state('numPerPage')).toEqual(DEFAULT_NUM_PER_PAGE);
|
||||
}, 0);
|
||||
|
||||
// Wait for items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
|
||||
// Verify items are rendered
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('item-234')).toBeInTheDocument();
|
||||
|
||||
// Verify pagination text
|
||||
expect(screen.getByText(/1 - 2 of 3 total/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should update numPerPage', () => {
|
||||
const numPerPage = totalCount - 1;
|
||||
const props = {...baseProps};
|
||||
props.numPerPage = numPerPage;
|
||||
const wrapper = shallow(
|
||||
it('should update numPerPage', async () => {
|
||||
const numPerPage = totalCount - 1; // numPerPage = 2
|
||||
const props = {...baseProps, numPerPage};
|
||||
renderWithContext(
|
||||
<ListModal {...props}/>,
|
||||
);
|
||||
setTimeout(() => {
|
||||
expect(wrapper.state('numPerPage')).toEqual(numPerPage);
|
||||
}, 0);
|
||||
|
||||
// Wait for items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify numPerPage is applied by checking Next button appears
|
||||
// With numPerPage=2 and 2 items loaded, items.length >= numPerPage is true
|
||||
// so Next button should be visible (unlike default numPerPage=50 where it wouldn't)
|
||||
expect(screen.getByRole('button', {name: 'Next'})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should match snapshot with title bar button', () => {
|
||||
const props = {...baseProps};
|
||||
props.titleBarButtonText = 'Add Foo';
|
||||
props.titleBarButtonTextOnClick = () => { };
|
||||
const wrapper = shallow(
|
||||
<ListModal {...baseProps}/>,
|
||||
it('should match snapshot with title bar button', async () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
titleBarButtonText: 'Add Foo',
|
||||
titleBarButtonOnClick: jest.fn(),
|
||||
};
|
||||
const {baseElement} = renderWithContext(
|
||||
<ListModal {...props}/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
// Wait for items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
|
||||
// Verify title bar button is present
|
||||
expect(screen.getByRole('link', {name: 'Add Foo'})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should have called onHide when handleExit is called', () => {
|
||||
test('should have called onHide when handleExit is called', async () => {
|
||||
const onHide = jest.fn();
|
||||
const props = {...baseProps, onHide};
|
||||
const wrapper = shallow(
|
||||
const {baseElement} = renderWithContext(
|
||||
<ListModal {...props}/>,
|
||||
);
|
||||
(wrapper.instance() as ListModal).handleExit();
|
||||
expect(onHide).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Wait for items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Click the modal close button
|
||||
const closeButton = baseElement.querySelector('.close') as HTMLElement;
|
||||
await userEvent.click(closeButton);
|
||||
|
||||
// Wait for onHide to be called (called after exit animation)
|
||||
await waitFor(() => {
|
||||
expect(onHide).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('paging loads new items', () => {
|
||||
const wrapper = shallow(
|
||||
<ListModal {...baseProps}/>,
|
||||
test('paging loads new items', async () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
numPerPage: 2, // Set to 2 so Next button appears when we have 2 items
|
||||
};
|
||||
renderWithContext(
|
||||
<ListModal {...props}/>,
|
||||
);
|
||||
(wrapper.instance() as ListModal).onNext();
|
||||
setTimeout(() => {
|
||||
expect(wrapper.state('page')).toEqual(1);
|
||||
expect(wrapper.state('items')).toEqual(mockItemsPage2);
|
||||
}, 0);
|
||||
(wrapper.instance() as ListModal).onPrev();
|
||||
setTimeout(() => {
|
||||
expect(wrapper.state('page')).toEqual(0);
|
||||
expect(wrapper.state('items')).toEqual(mockItems);
|
||||
}, 0);
|
||||
|
||||
// Wait for initial items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify page 1 items
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('item-234')).toBeInTheDocument();
|
||||
|
||||
// Click Next
|
||||
await userEvent.click(screen.getByRole('button', {name: 'Next'}));
|
||||
|
||||
// Wait for page 2 items
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-345')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify page 1 items are gone and page 2 items are present
|
||||
expect(screen.queryByTestId('item-123')).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId('item-345')).toBeInTheDocument();
|
||||
|
||||
// Click Previous
|
||||
await userEvent.click(screen.getByRole('button', {name: 'Previous'}));
|
||||
|
||||
// Wait for page 1 items again
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify we're back on page 1
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('item-234')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('search input', () => {
|
||||
const wrapper = shallow(
|
||||
test('search input', async () => {
|
||||
renderWithContext(
|
||||
<ListModal {...baseProps}/>,
|
||||
);
|
||||
(wrapper.instance() as ListModal).onSearchInput({target: {value: mockSearchTerm}} as React.ChangeEvent<HTMLInputElement>);
|
||||
setTimeout(() => {
|
||||
expect(wrapper.state('searchTerm')).toEqual(mockSearchTerm);
|
||||
expect(wrapper.state('items')).toEqual(mockItemsSearch);
|
||||
}, 0);
|
||||
|
||||
// Wait for initial items to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Type in search input
|
||||
const searchInput = screen.getByPlaceholderText('search for name');
|
||||
await userEvent.type(searchInput, mockSearchTerm);
|
||||
|
||||
// Wait for filtered items
|
||||
await waitFor(() => {
|
||||
// mockItemsSearch contains items with 'ar3' in name: bar31 and bar3
|
||||
expect(screen.getByTestId('item-123')).toBeInTheDocument(); // bar31 matches
|
||||
});
|
||||
|
||||
// Verify item-234 (bar2) is not present since it doesn't match 'ar3'
|
||||
expect(screen.queryByTestId('item-234')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import LoadingImagePreview from 'components/loading_image_preview';
|
||||
|
||||
describe('components/LoadingImagePreview', () => {
|
||||
test('should match snapshot', () => {
|
||||
const loading = 'Loading';
|
||||
let progress = 50;
|
||||
import {render, screen} from 'tests/react_testing_utils';
|
||||
|
||||
const wrapper = shallow(
|
||||
describe('components/LoadingImagePreview', () => {
|
||||
test('should match snapshot with progress 50%', () => {
|
||||
const {container} = render(
|
||||
<LoadingImagePreview
|
||||
loading={loading}
|
||||
progress={progress}
|
||||
loading='Loading'
|
||||
progress={50}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('span').text()).toBe('Loading 50%');
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(screen.getByText('Loading 50%')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
progress = 90;
|
||||
wrapper.setProps({loading, progress});
|
||||
test('should match snapshot with progress 90%', () => {
|
||||
const {container} = render(
|
||||
<LoadingImagePreview
|
||||
loading='Loading'
|
||||
progress={90}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('span').text()).toBe('Loading 90%');
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(screen.getByText('Loading 90%')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+455
-134
@@ -1,170 +1,491 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/MarkdownImage should match snapshot 1`] = `
|
||||
<Connect(Component)
|
||||
imageMetadata={
|
||||
Object {
|
||||
"format": "png",
|
||||
"frameCount": 0,
|
||||
"height": 90,
|
||||
"width": 1041,
|
||||
}
|
||||
}
|
||||
src="/images/logo.png"
|
||||
>
|
||||
<Component />
|
||||
</Connect(Component)>
|
||||
<div>
|
||||
<div
|
||||
class="image-loading__container markdown-inline-img markdown-inline-img--loading"
|
||||
style="max-width: 1041px;"
|
||||
>
|
||||
<svg
|
||||
style="max-height: 90px; max-width: 1041px; vertical-align: middle;"
|
||||
viewBox="0 0 1041 90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: none;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--loading"
|
||||
height=""
|
||||
src="/images/logo.png"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/images/logo.png"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should match snapshot for SizeAwareImage dimensions 1`] = `
|
||||
<injectIntl(SizeAwareImage)
|
||||
alt="test image"
|
||||
className="markdown-inline-img markdown-inline-img--hover markdown-inline-img--no-border"
|
||||
dimensions={
|
||||
Object {
|
||||
"format": "jpg",
|
||||
"frameCount": 0,
|
||||
"height": 90,
|
||||
"width": 100,
|
||||
}
|
||||
}
|
||||
height=""
|
||||
onClick={[Function]}
|
||||
onImageLoadFail={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={false}
|
||||
src="safeSrc"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--hover markdown-inline-img--no-border"
|
||||
height=""
|
||||
src="path/image"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="path/image"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should match snapshot for broken link 1`] = `
|
||||
<Connect(Component)
|
||||
imageMetadata={
|
||||
Object {
|
||||
"format": "png",
|
||||
"frameCount": 0,
|
||||
"height": 10,
|
||||
"width": 10,
|
||||
}
|
||||
}
|
||||
src="brokenLink"
|
||||
>
|
||||
<Component />
|
||||
</Connect(Component)>
|
||||
<div>
|
||||
<div
|
||||
class="image-loading__container markdown-inline-img markdown-inline-img--loading"
|
||||
style="max-width: 10px;"
|
||||
>
|
||||
<svg
|
||||
style="max-height: 10px; max-width: 10px; vertical-align: middle;"
|
||||
viewBox="0 0 10 10"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: none;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--loading"
|
||||
height=""
|
||||
src="brokenLink"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should provide image src as an alt text for MarkdownImageExpand if image has no own alt text 1`] = `
|
||||
<div>
|
||||
<Connect(MarkdownImageExpand)
|
||||
alt="https://example.com/image.png"
|
||||
imageKey="https://example.com/image.png"
|
||||
postId="post_id"
|
||||
<div
|
||||
class="markdown-image-expand markdown-image-expand--expanded"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
alt=""
|
||||
className="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
dimensions={Object {}}
|
||||
height="250"
|
||||
onClick={[Function]}
|
||||
onImageLoadFail={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={false}
|
||||
src="https://example.com/image.png"
|
||||
title="test title"
|
||||
width="50"
|
||||
/>
|
||||
</Connect(MarkdownImageExpand)>
|
||||
<button
|
||||
class="markdown-image-expand__collapse-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
height="250"
|
||||
src="https://example.com/image.png"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width="50"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="https://example.com/image.png"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should render a link if the source is unsafe 1`] = `
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"display": "inline-block",
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
className="markdown-inline-img broken-image"
|
||||
src=""
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
class="markdown-inline-img broken-image"
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should render an image with no preview if the source is safe and the image is a link 1`] = `
|
||||
<div>
|
||||
<injectIntl(SizeAwareImage)
|
||||
alt="test image"
|
||||
className="markdown-inline-img markdown-inline-img--hover markdown-inline-img--no-border"
|
||||
dimensions={
|
||||
Object {
|
||||
"format": "png",
|
||||
"frameCount": 0,
|
||||
"height": 90,
|
||||
"width": 1041,
|
||||
}
|
||||
}
|
||||
height=""
|
||||
onClick={[Function]}
|
||||
onImageLoadFail={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={false}
|
||||
src="https://example.com/image.png"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--hover markdown-inline-img--no-border"
|
||||
height=""
|
||||
src="https://example.com/image.png"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="https://example.com/image.png"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should render an image with preview modal if the source is safe 1`] = `
|
||||
<div>
|
||||
<injectIntl(SizeAwareImage)
|
||||
alt="test image"
|
||||
className="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
dimensions={
|
||||
Object {
|
||||
"format": "png",
|
||||
"frameCount": 0,
|
||||
"height": 90,
|
||||
"width": 1041,
|
||||
}
|
||||
}
|
||||
height=""
|
||||
onClick={[Function]}
|
||||
onImageLoadFail={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={false}
|
||||
src="https://example.com/image.png"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
height=""
|
||||
src="https://example.com/image.png"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width=""
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="https://example.com/image.png"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MarkdownImage should render image with MarkdownImageExpand if it is taller than 100px 1`] = `
|
||||
<div>
|
||||
<Connect(MarkdownImageExpand)
|
||||
alt="test image"
|
||||
imageKey="https://example.com/image.png"
|
||||
postId="post_id"
|
||||
<div
|
||||
class="markdown-image-expand markdown-image-expand--expanded"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
alt="test image"
|
||||
className="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
dimensions={Object {}}
|
||||
height="250"
|
||||
onClick={[Function]}
|
||||
onImageLoadFail={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={false}
|
||||
src="https://example.com/image.png"
|
||||
title="test title"
|
||||
width="50"
|
||||
/>
|
||||
</Connect(MarkdownImageExpand)>
|
||||
<button
|
||||
class="markdown-image-expand__collapse-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
alt="test image"
|
||||
aria-label="file thumbnail"
|
||||
class="markdown-inline-img markdown-inline-img--hover cursor--pointer a11y--active"
|
||||
height="250"
|
||||
src="https://example.com/image.png"
|
||||
tabindex="0"
|
||||
title="test title"
|
||||
width="50"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy link"
|
||||
class="style--none size-aware-image__copy_link"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="https://example.com/image.png"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import FilePreviewModal from 'components/file_preview_modal';
|
||||
import SizeAwareImage from 'components/size_aware_image';
|
||||
|
||||
import {fireEvent, renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
|
||||
import MarkdownImage from './markdown_image';
|
||||
@@ -36,221 +33,253 @@ describe('components/MarkdownImage', () => {
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const props = {...baseProps, src: '/images/logo.png'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot for broken link', () => {
|
||||
const props = {...baseProps,
|
||||
const props = {
|
||||
...baseProps,
|
||||
imageMetadata: {
|
||||
format: 'png',
|
||||
height: 10,
|
||||
width: 10,
|
||||
frameCount: 0,
|
||||
},
|
||||
src: 'brokenLink'};
|
||||
const wrapper = shallow(
|
||||
src: 'brokenLink',
|
||||
};
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should handle load failure properly', () => {
|
||||
const props = {...baseProps,
|
||||
const props = {
|
||||
...baseProps,
|
||||
imageMetadata: {
|
||||
format: 'png',
|
||||
height: 10,
|
||||
width: 10,
|
||||
frameCount: 0,
|
||||
|
||||
},
|
||||
src: 'brokenLink'};
|
||||
const wrapper = shallow(
|
||||
src: 'brokenLink',
|
||||
};
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.state('loadFailed')).toBe(false);
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toBeInTheDocument();
|
||||
expect(img).not.toHaveClass('broken-image');
|
||||
|
||||
(wrapper.instance() as MarkdownImage).handleLoadFail();
|
||||
// Simulate load failure
|
||||
fireEvent.error(img!);
|
||||
|
||||
expect(wrapper.state('loadFailed')).toBe(true);
|
||||
// After load failure, image should have broken-image class
|
||||
expect(container.querySelector('img')).toHaveClass('broken-image');
|
||||
});
|
||||
|
||||
test('should reset loadFailed state after image source is updated', () => {
|
||||
const props = {...baseProps,
|
||||
const props = {
|
||||
...baseProps,
|
||||
imageMetadata: {
|
||||
format: 'png',
|
||||
height: 10,
|
||||
width: 10,
|
||||
frameCount: 0,
|
||||
|
||||
},
|
||||
src: 'brokenLink'};
|
||||
const nextProps = {...baseProps, src: 'https://example.com/image.png'};
|
||||
const wrapper = shallow(
|
||||
src: 'brokenLink',
|
||||
};
|
||||
const {container, rerender} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().setState({loadFailed: true});
|
||||
const img = container.querySelector('img');
|
||||
|
||||
wrapper.setProps(nextProps);
|
||||
// Simulate load failure
|
||||
fireEvent.error(img!);
|
||||
expect(container.querySelector('img')).toHaveClass('broken-image');
|
||||
|
||||
expect(wrapper.state('loadFailed')).toBe(false);
|
||||
// Update with new source
|
||||
const nextProps = {...baseProps, src: 'https://example.com/image.png'};
|
||||
rerender(<MarkdownImage {...nextProps}/>);
|
||||
|
||||
// After source update, broken-image class should be removed
|
||||
expect(container.querySelector('img')).not.toHaveClass('broken-image');
|
||||
});
|
||||
|
||||
test('should render a link if the source is unsafe', () => {
|
||||
const props = {...baseProps, src: ''};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
expect(wrapper.find('img').props().alt).toBe(props.alt);
|
||||
expect(wrapper.find('img').props().className).toBe(props.className + ' broken-image');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toHaveAttribute('alt', props.alt);
|
||||
expect(img).toHaveClass('broken-image');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should handle not loaded state properly', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.state('loaded')).toBe(false);
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--loading`);
|
||||
// Initially image should have loading class
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toHaveClass('markdown-inline-img--loading');
|
||||
});
|
||||
|
||||
test('should handle not loaded state properly in case of a header change system message', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png', postType: 'system_header_change'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.state('loaded')).toBe(false);
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--scaled-down-loading`);
|
||||
// For header change system message, should have scaled-down-loading class
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toHaveClass('markdown-inline-img--scaled-down-loading');
|
||||
});
|
||||
|
||||
test('should set loaded state when img loads and call onImageLoaded prop', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
const dimensions = {
|
||||
height: props.imageMetadata.height,
|
||||
width: props.imageMetadata.width,
|
||||
};
|
||||
|
||||
expect(wrapper.state('loaded')).toBe(false);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
(wrapper.instance() as MarkdownImage).handleImageLoaded(dimensions);
|
||||
// Initially should have loading class
|
||||
expect(img).toHaveClass('markdown-inline-img--loading');
|
||||
|
||||
expect(wrapper.state('loaded')).toBe(true);
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 1041, configurable: true});
|
||||
|
||||
// Simulate successful load
|
||||
fireEvent.load(img!);
|
||||
|
||||
// After load, should not have loading class and onImageLoaded should be called
|
||||
expect(img).not.toHaveClass('markdown-inline-img--loading');
|
||||
expect(props.onImageLoaded).toHaveBeenCalledTimes(1);
|
||||
expect(props.onImageLoaded).toHaveBeenCalledWith(dimensions);
|
||||
expect(props.onImageLoaded).toHaveBeenCalledWith({height: 90, width: 1041});
|
||||
});
|
||||
|
||||
it('should match snapshot for SizeAwareImage dimensions', () => {
|
||||
const props = {...baseProps,
|
||||
const props = {
|
||||
...baseProps,
|
||||
imageMetadata: {format: 'jpg', frameCount: 0, width: 100, height: 90},
|
||||
src: 'path/image',
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().setState({loaded: true});
|
||||
const img = container.querySelector('img');
|
||||
|
||||
const childrenWrapper = wrapper.props().children('safeSrc');
|
||||
expect(childrenWrapper).toMatchSnapshot();
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 100, configurable: true});
|
||||
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render an image with preview modal if the source is safe', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 1041, configurable: true});
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--hover cursor--pointer a11y--active`);
|
||||
expect(childrenWrapper).toMatchSnapshot();
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
// After load, should have hover and cursor classes for clickable preview
|
||||
expect(img).toHaveClass('markdown-inline-img--hover');
|
||||
expect(img).toHaveClass('cursor--pointer');
|
||||
expect(img).toHaveClass('a11y--active');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render an image with no preview if the source is safe and the image is a link', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png', imageIsLink: true};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 1041, configurable: true});
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--hover markdown-inline-img--no-border`);
|
||||
expect(childrenWrapper.find(FilePreviewModal)).toHaveLength(0);
|
||||
expect(childrenWrapper).toMatchSnapshot();
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
// When imageIsLink, should have no-border class and not cursor--pointer
|
||||
expect(img).toHaveClass('markdown-inline-img--hover');
|
||||
expect(img).toHaveClass('markdown-inline-img--no-border');
|
||||
expect(img).not.toHaveClass('cursor--pointer');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should call openModal when showModal is called', () => {
|
||||
test('should call openModal when showModal is called', async () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
const mockEvent = {
|
||||
preventDefault: () => {},
|
||||
};
|
||||
(wrapper.instance() as MarkdownImage).showModal(mockEvent as unknown as React.MouseEvent<HTMLImageElement>, 'https://example.com/image.png');
|
||||
|
||||
const img = container.querySelector('img');
|
||||
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 1041, configurable: true});
|
||||
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
// Click the image to trigger showModal
|
||||
await userEvent.click(img!);
|
||||
|
||||
expect(props.actions.openModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should properly scale down the image in case of a header change system message', () => {
|
||||
const props = {...baseProps, src: 'https://example.com/image.png', postType: 'system_header_change'};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 90, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 1041, configurable: true});
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--hover cursor--pointer a11y--active markdown-inline-img--scaled-down`);
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
// After load, should have scaled-down class
|
||||
expect(img).toHaveClass('markdown-inline-img--scaled-down');
|
||||
expect(img).not.toHaveClass('markdown-inline-img--scaled-down-loading');
|
||||
});
|
||||
|
||||
test('should render image with title, height, width', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
alt: 'test image',
|
||||
title: 'test title',
|
||||
className: 'markdown-inline-img',
|
||||
@@ -259,32 +288,29 @@ describe('components/MarkdownImage', () => {
|
||||
imageIsLink: false,
|
||||
height: '76',
|
||||
width: '50',
|
||||
actions: baseProps.actions,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 76, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 50, configurable: true});
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage)).toHaveLength(1);
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('className')).
|
||||
toEqual(`${props.className} markdown-inline-img--hover cursor--pointer a11y--active`);
|
||||
// Simulate load to get final state
|
||||
fireEvent.load(img!);
|
||||
|
||||
// These props can be strings since they're passed directly through to HTML tags
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('width')).toEqual('50');
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('height')).toEqual('76');
|
||||
|
||||
expect(childrenWrapper.find(SizeAwareImage).prop('title')).toEqual('test title');
|
||||
expect(img).toHaveAttribute('width', '50');
|
||||
expect(img).toHaveAttribute('height', '76');
|
||||
expect(img).toHaveAttribute('title', 'test title');
|
||||
});
|
||||
|
||||
test(`should render image with MarkdownImageExpand if it is taller than ${Constants.EXPANDABLE_INLINE_IMAGE_MIN_HEIGHT}px`, () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
alt: 'test image',
|
||||
title: 'test title',
|
||||
className: 'markdown-inline-img',
|
||||
@@ -293,23 +319,27 @@ describe('components/MarkdownImage', () => {
|
||||
imageIsLink: false,
|
||||
height: '250',
|
||||
width: '50',
|
||||
actions: baseProps.actions,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
expect(childrenWrapper).toMatchSnapshot();
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 250, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 50, configurable: true});
|
||||
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should provide image src as an alt text for MarkdownImageExpand if image has no own alt text', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
alt: '',
|
||||
title: 'test title',
|
||||
className: 'markdown-inline-img',
|
||||
@@ -318,26 +348,29 @@ describe('components/MarkdownImage', () => {
|
||||
imageIsLink: false,
|
||||
height: '250',
|
||||
width: '50',
|
||||
actions: baseProps.actions,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
wrapper.instance().setState({loaded: true});
|
||||
const childrenNode = wrapper.props().children(props.src);
|
||||
|
||||
// using a div as a workaround because shallow doesn't support react fragments
|
||||
const childrenWrapper = shallow(<div>{childrenNode}</div>);
|
||||
const img = container.querySelector('img');
|
||||
|
||||
expect(childrenWrapper).toMatchSnapshot();
|
||||
// Mock naturalHeight/naturalWidth for SizeAwareImage's onImageLoaded callback
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 250, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 50, configurable: true});
|
||||
|
||||
// Simulate load
|
||||
fireEvent.load(img!);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render a alt text if the link is unsafe', () => {
|
||||
const props = {...baseProps, isUnsafeLinksPost: true};
|
||||
const wrapper = shallow(
|
||||
renderWithContext(
|
||||
<MarkdownImage {...props}/>,
|
||||
);
|
||||
expect(wrapper.text()).toBe(props.alt);
|
||||
expect(screen.getByText(props.alt)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import MessageSubmitError from 'components/message_submit_error';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import MessageSubmitError from './message_submit_error';
|
||||
|
||||
describe('components/MessageSubmitError', () => {
|
||||
const baseProps = {
|
||||
@@ -24,12 +25,13 @@ describe('components/MessageSubmitError', () => {
|
||||
submittedMessage,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
renderWithContext(
|
||||
<MessageSubmitError {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('[id="message_submit_error.invalidCommand"]').exists()).toBe(true);
|
||||
expect(wrapper.text()).not.toEqual('No command found');
|
||||
expect(screen.getByText(/Command with a trigger of/)).toBeInTheDocument();
|
||||
expect(screen.getByText('Click here to send as a message.')).toBeInTheDocument();
|
||||
expect(screen.queryByText('No command found')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not display the submit link if the error is not for an invalid slash command', () => {
|
||||
@@ -45,11 +47,11 @@ describe('components/MessageSubmitError', () => {
|
||||
submittedMessage,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
renderWithContext(
|
||||
<MessageSubmitError {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('[id="message_submit_error.invalidCommand"]').exists()).toBe(false);
|
||||
expect(wrapper.text()).toEqual('Some server error');
|
||||
expect(screen.queryByText('Click here to send as a message.')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Some server error')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +1,29 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/MsgTyping should match snapshot, on multiple users typing 1`] = `
|
||||
<span
|
||||
className="msg-typing"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="{users} and {last} are typing..."
|
||||
id="msg_typing.areTyping"
|
||||
values={
|
||||
Object {
|
||||
"last": "another.user",
|
||||
"users": "test.user, other.test.user",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="msg-typing"
|
||||
>
|
||||
test.user, other.test.user and another.user are typing...
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MsgTyping should match snapshot, on nobody typing 1`] = `
|
||||
<span
|
||||
className="msg-typing"
|
||||
/>
|
||||
<div>
|
||||
<span
|
||||
class="msg-typing"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/MsgTyping should match snapshot, on one user typing 1`] = `
|
||||
<span
|
||||
className="msg-typing"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="{user} is typing..."
|
||||
id="msg_typing.isTyping"
|
||||
values={
|
||||
Object {
|
||||
"user": "test.user",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="msg-typing"
|
||||
>
|
||||
test.user is typing...
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import MsgTyping from 'components/msg_typing/msg_typing';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import MsgTyping from './msg_typing';
|
||||
|
||||
describe('components/MsgTyping', () => {
|
||||
const baseProps = {
|
||||
@@ -16,23 +17,23 @@ describe('components/MsgTyping', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot, on nobody typing', () => {
|
||||
const wrapper = shallow(<MsgTyping {...baseProps}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = renderWithContext(<MsgTyping {...baseProps}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, on one user typing', () => {
|
||||
const typingUsers = ['test.user'];
|
||||
const props = {...baseProps, typingUsers};
|
||||
|
||||
const wrapper = shallow(<MsgTyping {...props}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = renderWithContext(<MsgTyping {...props}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, on multiple users typing', () => {
|
||||
const typingUsers = ['test.user', 'other.test.user', 'another.user'];
|
||||
const props = {...baseProps, typingUsers};
|
||||
|
||||
const wrapper = shallow(<MsgTyping {...props}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = renderWithContext(<MsgTyping {...props}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import type {PDFDocumentProxy, PDFPageProxy} from 'pdfjs-dist';
|
||||
import React from 'react';
|
||||
|
||||
import PDFPreview from 'components/pdf_preview';
|
||||
import type {Props} from 'components/pdf_preview';
|
||||
|
||||
import {render, renderWithContext, waitFor} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
jest.mock('pdfjs-dist', () => ({
|
||||
getDocument: () => Promise.resolve({
|
||||
numPages: 3,
|
||||
getPage: (i: number) => Promise.resolve({
|
||||
pageIndex: i,
|
||||
getContext: (s: string) => Promise.resolve({s}),
|
||||
}),
|
||||
}),
|
||||
const mockGetDocument = jest.fn();
|
||||
|
||||
jest.mock('pdfjs-dist/legacy/build/pdf.mjs', () => ({
|
||||
getDocument: (params: unknown) => mockGetDocument(params),
|
||||
}));
|
||||
|
||||
jest.mock('pdfjs-dist/build/pdf.worker.min.mjs', () => ({}));
|
||||
|
||||
describe('component/PDFPreview', () => {
|
||||
const requiredProps: Props = {
|
||||
fileInfo: TestHelper.getFileInfoMock({extension: 'pdf'}),
|
||||
@@ -28,51 +25,127 @@ describe('component/PDFPreview', () => {
|
||||
handleBgClose: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockGetDocument.mockReset();
|
||||
mockGetDocument.mockReturnValue({
|
||||
promise: Promise.resolve({
|
||||
numPages: 3,
|
||||
getPage: (i: number) => Promise.resolve({
|
||||
pageIndex: i,
|
||||
getViewport: () => ({height: 100, width: 100}),
|
||||
render: () => ({promise: Promise.resolve()}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test('should match snapshot, loading', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<PDFPreview {...requiredProps}/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, not successful', () => {
|
||||
const wrapper = shallow(
|
||||
test('should match snapshot, not successful', async () => {
|
||||
// Mock PDF loading to fail
|
||||
mockGetDocument.mockReturnValue({
|
||||
promise: Promise.reject(new Error('Failed to load PDF')),
|
||||
});
|
||||
|
||||
// Use renderWithContext because FileInfoPreview requires Redux store
|
||||
const {container} = renderWithContext(
|
||||
<PDFPreview {...requiredProps}/>,
|
||||
);
|
||||
wrapper.setState({loading: false});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
// Wait for loading to complete (and fail)
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.view-image__loading')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should update state with new value from props when prop changes', () => {
|
||||
const wrapper = shallow<PDFPreview>(
|
||||
test('should update state with new value from props when prop changes', async () => {
|
||||
const {container, rerender} = render(
|
||||
<PDFPreview {...requiredProps}/>,
|
||||
);
|
||||
|
||||
// Wait for initial PDF to load
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.post-code')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const newFileUrl = 'https://some-new-url';
|
||||
|
||||
wrapper.setProps({fileUrl: newFileUrl});
|
||||
const {prevFileUrl} = wrapper.instance().state;
|
||||
expect(prevFileUrl).toEqual(newFileUrl);
|
||||
// Rerender with new fileUrl - component should show loading state again
|
||||
rerender(
|
||||
<PDFPreview
|
||||
{...requiredProps}
|
||||
fileUrl={newFileUrl}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Verify loading state is shown (state was reset due to new fileUrl)
|
||||
expect(container.querySelector('.view-image__loading')).toBeInTheDocument();
|
||||
|
||||
// Wait for new PDF to load
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.post-code')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify getDocument was called with new URL
|
||||
expect(mockGetDocument).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({url: newFileUrl}),
|
||||
);
|
||||
});
|
||||
|
||||
test('should return correct state when onDocumentLoad is called', () => {
|
||||
const wrapper = shallow<PDFPreview>(
|
||||
test('should return correct state when onDocumentLoad is called', async () => {
|
||||
// Test with 0 pages
|
||||
mockGetDocument.mockReturnValueOnce({
|
||||
promise: Promise.resolve({
|
||||
numPages: 0,
|
||||
getPage: jest.fn(),
|
||||
}),
|
||||
});
|
||||
|
||||
const {container, rerender} = render(
|
||||
<PDFPreview {...requiredProps}/>,
|
||||
);
|
||||
|
||||
let pdf = {numPages: 0} as PDFDocumentProxy;
|
||||
wrapper.instance().onDocumentLoad(pdf);
|
||||
expect(wrapper.state('pdf')).toEqual(pdf);
|
||||
expect(wrapper.state('numPages')).toEqual(pdf.numPages);
|
||||
// Wait for PDF to load with 0 pages
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.view-image__loading')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
pdf = {
|
||||
numPages: 100,
|
||||
getPage: async (i) => {
|
||||
const page = {pageNumber: i} as PDFPageProxy;
|
||||
return Promise.resolve(page);
|
||||
},
|
||||
} as PDFDocumentProxy;
|
||||
wrapper.instance().onDocumentLoad(pdf);
|
||||
expect(wrapper.state('pdf')).toEqual(pdf);
|
||||
expect(wrapper.state('numPages')).toEqual(pdf.numPages);
|
||||
// Should have 0 canvas elements
|
||||
expect(container.querySelectorAll('canvas')).toHaveLength(0);
|
||||
|
||||
// Test with 100 pages
|
||||
mockGetDocument.mockReturnValueOnce({
|
||||
promise: Promise.resolve({
|
||||
numPages: 100,
|
||||
getPage: (i: number) => Promise.resolve({
|
||||
pageIndex: i,
|
||||
getViewport: () => ({height: 100, width: 100}),
|
||||
render: () => ({promise: Promise.resolve()}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const newFileUrl = 'https://another-url';
|
||||
rerender(
|
||||
<PDFPreview
|
||||
{...requiredProps}
|
||||
fileUrl={newFileUrl}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for new PDF to load
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.post-code')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Should have 100 canvas elements
|
||||
expect(container.querySelectorAll('canvas')).toHaveLength(100);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import PostDeletedModal from 'components/post_deleted_modal';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
describe('components/ChannelInfoModal', () => {
|
||||
import PostDeletedModal from './post_deleted_modal';
|
||||
|
||||
describe('components/PostDeletedModal', () => {
|
||||
const baseProps = {
|
||||
onExited: jest.fn(),
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {baseElement} = renderWithContext(
|
||||
<PostDeletedModal {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+155
-71
@@ -1,100 +1,184 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/ProfilePicture should match snapshot, no user specified, default props 1`] = `
|
||||
<span
|
||||
className="status-wrapper style--none"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
className="profile-icon "
|
||||
class="status-wrapper style--none"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="md"
|
||||
url="http://example.com/image.png"
|
||||
/>
|
||||
<span
|
||||
class="profile-icon "
|
||||
>
|
||||
<img
|
||||
alt="user profile image"
|
||||
class="Avatar Avatar-md"
|
||||
loading="lazy"
|
||||
src="http://example.com/image.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
height="100%"
|
||||
role="img"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 1.41421;"
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
class="away--icon"
|
||||
d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10.27,3C10.949,3 11.5,3.586 11.5,4.307L11.5,9.379L15.002,12.881C15.492,13.37 15.499,14.158 15.019,14.638L14.638,15.019C14.158,15.499 13.37,15.492 12.881,15.002L8.887,11.008C8.739,10.861 8.636,10.686 8.576,10.501C8.528,10.402 8.5,10.299 8.5,10.193L8.5,4.307C8.5,3.586 9.051,3 9.73,3L10.27,3Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<Memo(StatusIcon)
|
||||
status="away"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/ProfilePicture should match snapshot, no user specified, overridden props 1`] = `
|
||||
<span
|
||||
className="status-wrapper style--none"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
className="profile-icon "
|
||||
class="status-wrapper style--none"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="xl"
|
||||
url="http://example.com/image.png"
|
||||
/>
|
||||
<span
|
||||
class="profile-icon "
|
||||
>
|
||||
<img
|
||||
alt="user profile image"
|
||||
class="Avatar Avatar-xl"
|
||||
loading="lazy"
|
||||
src="http://example.com/image.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
height="100%"
|
||||
role="img"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 1.41421;"
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
class="away--icon"
|
||||
d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10.27,3C10.949,3 11.5,3.586 11.5,4.307L11.5,9.379L15.002,12.881C15.492,13.37 15.499,14.158 15.019,14.638L14.638,15.019C14.158,15.499 13.37,15.492 12.881,15.002L8.887,11.008C8.739,10.861 8.636,10.686 8.576,10.501C8.528,10.402 8.5,10.299 8.5,10.193L8.5,4.307C8.5,3.586 9.051,3 9.73,3L10.27,3Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<Memo(StatusIcon)
|
||||
status="away"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/ProfilePicture should match snapshot, profile and src, default props 1`] = `
|
||||
<ProfilePopoverController
|
||||
src="http://example.com/image.png"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="status-wrapper style--none"
|
||||
triggerComponentStyle={
|
||||
Object {
|
||||
"borderRadius": "50%",
|
||||
"height": "32px",
|
||||
"width": "32px",
|
||||
}
|
||||
}
|
||||
userId="uid"
|
||||
>
|
||||
<span
|
||||
className="profile-icon "
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="status-wrapper style--none"
|
||||
style="border-radius: 50%; width: 32px; height: 32px;"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
url="http://example.com/emoji.png"
|
||||
/>
|
||||
</span>
|
||||
<Memo(StatusIcon)
|
||||
status="away"
|
||||
/>
|
||||
</ProfilePopoverController>
|
||||
<span
|
||||
class="profile-icon "
|
||||
>
|
||||
<img
|
||||
alt="user profile image"
|
||||
class="Avatar Avatar-md"
|
||||
loading="lazy"
|
||||
src="http://example.com/emoji.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
height="100%"
|
||||
role="img"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 1.41421;"
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
class="away--icon"
|
||||
d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10.27,3C10.949,3 11.5,3.586 11.5,4.307L11.5,9.379L15.002,12.881C15.492,13.37 15.499,14.158 15.019,14.638L14.638,15.019C14.158,15.499 13.37,15.492 12.881,15.002L8.887,11.008C8.739,10.861 8.636,10.686 8.576,10.501C8.528,10.402 8.5,10.299 8.5,10.193L8.5,4.307C8.5,3.586 9.051,3 9.73,3L10.27,3Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/ProfilePicture should match snapshot, user specified 1`] = `
|
||||
<span
|
||||
className="status-wrapper style--none"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
className="profile-icon "
|
||||
class="status-wrapper style--none"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="md"
|
||||
url="http://example.com/image.png"
|
||||
/>
|
||||
<span
|
||||
class="profile-icon "
|
||||
>
|
||||
<img
|
||||
alt="user profile image"
|
||||
class="Avatar Avatar-md"
|
||||
loading="lazy"
|
||||
src="http://example.com/image.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
height="100%"
|
||||
role="img"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 1.41421;"
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
class="away--icon"
|
||||
d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10.27,3C10.949,3 11.5,3.586 11.5,4.307L11.5,9.379L15.002,12.881C15.492,13.37 15.499,14.158 15.019,14.638L14.638,15.019C14.158,15.499 13.37,15.492 12.881,15.002L8.887,11.008C8.739,10.861 8.636,10.686 8.576,10.501C8.528,10.402 8.5,10.299 8.5,10.193L8.5,4.307C8.5,3.586 9.051,3 9.73,3L10.27,3Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<Memo(StatusIcon)
|
||||
status="away"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/ProfilePicture should match snapshot, user specified, overridden props 1`] = `
|
||||
<span
|
||||
className="status-wrapper style--none"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
className="profile-icon "
|
||||
class="status-wrapper style--none"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="xs"
|
||||
url="http://example.com/image.png"
|
||||
/>
|
||||
<span
|
||||
class="profile-icon "
|
||||
>
|
||||
<img
|
||||
alt="user profile image"
|
||||
class="Avatar Avatar-xs"
|
||||
loading="lazy"
|
||||
src="http://example.com/image.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Away"
|
||||
height="100%"
|
||||
role="img"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 1.41421;"
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
class="away--icon"
|
||||
d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10.27,3C10.949,3 11.5,3.586 11.5,4.307L11.5,9.379L15.002,12.881C15.492,13.37 15.499,14.158 15.019,14.638L14.638,15.019C14.158,15.499 13.37,15.492 12.881,15.002L8.887,11.008C8.739,10.861 8.636,10.686 8.576,10.501C8.528,10.402 8.5,10.299 8.5,10.193L8.5,4.307C8.5,3.586 9.051,3 9.73,3L10.27,3Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<Memo(StatusIcon)
|
||||
status="away"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
|
||||
import ProfilePicture from 'components/profile_picture';
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import ProfilePicture from './index';
|
||||
|
||||
type Props = ComponentProps<typeof ProfilePicture>;
|
||||
|
||||
@@ -17,11 +18,11 @@ describe('components/ProfilePicture', () => {
|
||||
|
||||
test('should match snapshot, no user specified, default props', () => {
|
||||
const props: Props = baseProps;
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<ProfilePicture {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, profile and src, default props', () => {
|
||||
@@ -31,11 +32,11 @@ describe('components/ProfilePicture', () => {
|
||||
userId: 'uid',
|
||||
src: 'http://example.com/emoji.png',
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<ProfilePicture {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, no user specified, overridden props', () => {
|
||||
@@ -43,11 +44,11 @@ describe('components/ProfilePicture', () => {
|
||||
...baseProps,
|
||||
size: 'xl',
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<ProfilePicture {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, user specified', () => {
|
||||
@@ -55,11 +56,11 @@ describe('components/ProfilePicture', () => {
|
||||
...baseProps,
|
||||
username: 'username',
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<ProfilePicture {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, user specified, overridden props', () => {
|
||||
@@ -68,10 +69,10 @@ describe('components/ProfilePicture', () => {
|
||||
username: 'username',
|
||||
size: 'xs',
|
||||
};
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<ProfilePicture {...props}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+12
-25
@@ -1,66 +1,53 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import ScrollToBottomToast from './scroll_to_bottom_toast';
|
||||
|
||||
describe('ScrollToBottomToast Component', () => {
|
||||
const mockOnDismiss = jest.fn();
|
||||
const mockOnClick = jest.fn();
|
||||
const mockOnClickEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
stopPropagation: jest.fn(),
|
||||
};
|
||||
|
||||
it('should render ScrollToBottomToast component', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<ScrollToBottomToast
|
||||
onDismiss={mockOnDismiss}
|
||||
onClick={mockOnClick}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Assertions
|
||||
expect(wrapper.find('.scroll-to-bottom-toast')).toHaveLength(1);
|
||||
expect(wrapper.find('UnreadBelowIcon')).toHaveLength(1);
|
||||
expect(wrapper.text()).toContain('Jump to recents');
|
||||
expect(wrapper.find('.scroll-to-bottom-toast__dismiss')).toHaveLength(1);
|
||||
expect(wrapper.find('.close-btn')).toHaveLength(1);
|
||||
expect(container.querySelector('.scroll-to-bottom-toast')).toBeInTheDocument();
|
||||
expect(screen.getByText('Jump to recents')).toBeInTheDocument();
|
||||
expect(container.querySelector('.scroll-to-bottom-toast__dismiss')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call onClick when clicked', () => {
|
||||
const wrapper = shallow(
|
||||
it('should call onClick when clicked', async () => {
|
||||
const {container} = renderWithContext(
|
||||
<ScrollToBottomToast
|
||||
onDismiss={mockOnDismiss}
|
||||
onClick={mockOnClick}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Simulate click
|
||||
wrapper.simulate('click', mockOnClickEvent);
|
||||
await userEvent.click(container.querySelector('.scroll-to-bottom-toast')!);
|
||||
|
||||
// Expect the onClick function to be called
|
||||
expect(mockOnClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call onDismiss when close button is clicked', () => {
|
||||
const wrapper = shallow(
|
||||
it('should call onDismiss when close button is clicked', async () => {
|
||||
const {container} = renderWithContext(
|
||||
<ScrollToBottomToast
|
||||
onDismiss={mockOnDismiss}
|
||||
onClick={mockOnClick}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Simulate click on the close button
|
||||
wrapper.find('.scroll-to-bottom-toast__dismiss').simulate('click', mockOnClickEvent);
|
||||
await userEvent.click(container.querySelector('.scroll-to-bottom-toast__dismiss')!);
|
||||
|
||||
// Expect the onDismiss function to be called
|
||||
expect(mockOnDismiss).toHaveBeenCalled();
|
||||
|
||||
// Expect to stop propagation to avoid scrolling down on dismissing
|
||||
expect(mockOnClickEvent.stopPropagation).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+481
-368
@@ -1,74 +1,109 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/SingleImageView permalink preview should render with permalink styling if in permalink 1`] = `
|
||||
<div
|
||||
className="file-view--single image-permalink"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single image-permalink"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container image-permalink"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded"
|
||||
style={Object {}}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container image-permalink"
|
||||
>
|
||||
<div
|
||||
className="image-permalink"
|
||||
class="image-loaded"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className="image-permalink"
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class="image-permalink"
|
||||
>
|
||||
<div
|
||||
class="image-loading__container image-permalink"
|
||||
style="max-width: 350px;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%;"
|
||||
>
|
||||
<div
|
||||
class="file__image-loading"
|
||||
>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="loader-percent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
style="max-height: 200px; max-width: 350px; vertical-align: middle;"
|
||||
viewBox="0 0 350 200"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: none;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name"
|
||||
class="image-permalink"
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,74 +112,109 @@ exports[`components/SingleImageView permalink preview should render with permali
|
||||
`;
|
||||
|
||||
exports[`components/SingleImageView should match snapshot 1`] = `
|
||||
<div
|
||||
className="file-view--single"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded"
|
||||
style={Object {}}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
class="image-loaded"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className=""
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="image-loading__container "
|
||||
style="max-width: 350px;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%;"
|
||||
>
|
||||
<div
|
||||
class="file__image-loading"
|
||||
>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="loader-percent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
style="max-height: 200px; max-width: 350px; vertical-align: middle;"
|
||||
viewBox="0 0 350 200"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: none;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name"
|
||||
class=""
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,74 +223,78 @@ exports[`components/SingleImageView should match snapshot 1`] = `
|
||||
`;
|
||||
|
||||
exports[`components/SingleImageView should match snapshot 2`] = `
|
||||
<div
|
||||
className="file-view--single"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded image-fade-in"
|
||||
style={Object {}}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
class="image-loaded image-fade-in"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className=""
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name"
|
||||
class=""
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -229,78 +303,111 @@ exports[`components/SingleImageView should match snapshot 2`] = `
|
||||
`;
|
||||
|
||||
exports[`components/SingleImageView should match snapshot, SVG image 1`] = `
|
||||
<div
|
||||
className="file-view--single"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded svg"
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
class="image-loaded svg"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className=""
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "svg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "svg_file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name_svg",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/svg_file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/svg_file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="image-loading__container "
|
||||
style="max-width: 350px;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%;"
|
||||
>
|
||||
<div
|
||||
class="file__image-loading"
|
||||
>
|
||||
<span
|
||||
class="LoadingSpinner"
|
||||
data-testid="loadingSpinner"
|
||||
id="loadingSpinner"
|
||||
>
|
||||
<span
|
||||
class="fa fa-spinner fa-fw fa-pulse spinner"
|
||||
title="Loading Icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="loader-percent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
style="max-height: 200px; max-width: 350px; vertical-align: middle;"
|
||||
viewBox="0 0 350 200"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: none;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name_svg"
|
||||
class=""
|
||||
src="/api/v4/files/svg_file_info_id/preview"
|
||||
style="width: 350px; height: auto;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container image-preview-utility-buttons-container--small-image image-preview-utility-buttons-container--small-image-no-copy-button"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/svg_file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -309,78 +416,80 @@ exports[`components/SingleImageView should match snapshot, SVG image 1`] = `
|
||||
`;
|
||||
|
||||
exports[`components/SingleImageView should match snapshot, SVG image 2`] = `
|
||||
<div
|
||||
className="file-view--single"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded image-fade-in svg"
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
class="image-loaded image-fade-in svg"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className=""
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "svg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "svg_file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name_svg",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/svg_file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/svg_file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name_svg"
|
||||
class=""
|
||||
src="/api/v4/files/svg_file_info_id/preview"
|
||||
style="width: 350px; height: auto;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/svg_file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -389,74 +498,78 @@ exports[`components/SingleImageView should match snapshot, SVG image 2`] = `
|
||||
`;
|
||||
|
||||
exports[`components/SingleImageView should set loaded state on callback of onImageLoaded on SizeAwareImage component 1`] = `
|
||||
<div
|
||||
className="file-view--single"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="file__image"
|
||||
class="file-view--single"
|
||||
>
|
||||
<div
|
||||
className="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
className="style--none single-image-view__toggle"
|
||||
data-expanded={true}
|
||||
key="toggle"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="image-container"
|
||||
style={Object {}}
|
||||
class="file__image"
|
||||
>
|
||||
<div
|
||||
className="image-loaded image-fade-in"
|
||||
style={Object {}}
|
||||
class="image-header image-header--expanded"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle Embed Visibility"
|
||||
class="style--none single-image-view__toggle"
|
||||
data-expanded="true"
|
||||
>
|
||||
<span
|
||||
class="icon icon-menu-down"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="image-container"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
class="image-loaded image-fade-in"
|
||||
>
|
||||
<injectIntl(SizeAwareImage)
|
||||
className=""
|
||||
dimensions={
|
||||
Object {
|
||||
"height": 200,
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
enablePublicLink={false}
|
||||
fileInfo={
|
||||
Object {
|
||||
"archived": false,
|
||||
"channel_id": "channel_id",
|
||||
"clientId": "client_id",
|
||||
"create_at": 1,
|
||||
"delete_at": 1,
|
||||
"extension": "jpg",
|
||||
"has_preview_image": true,
|
||||
"height": 200,
|
||||
"id": "file_info_id",
|
||||
"mime_type": "mime_type",
|
||||
"name": "name",
|
||||
"size": 1,
|
||||
"update_at": 1,
|
||||
"user_id": "user_id",
|
||||
"width": 350,
|
||||
}
|
||||
}
|
||||
fileURL="/api/v4/files/file_info_id"
|
||||
getFilePublicLink={[Function]}
|
||||
handleSmallImageContainer={true}
|
||||
onClick={[Function]}
|
||||
onImageLoaded={[Function]}
|
||||
showLoader={true}
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
/>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="file-preview__button"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<figure
|
||||
class="image-loaded-container"
|
||||
>
|
||||
<img
|
||||
aria-label="file thumbnail name"
|
||||
class=""
|
||||
src="/api/v4/files/file_info_id/preview"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
class="image-preview-utility-buttons-container"
|
||||
>
|
||||
<a
|
||||
aria-label="Download"
|
||||
class="style--none size-aware-image__download"
|
||||
download=""
|
||||
href="/api/v4/files/file_info_id"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
class="style--none"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,18H5v2h14V18z M11,2h2v10.2l4.5-4.5l1.4,1.4L12,16L5.1,9.1l1.4-1.4l4.5,4.5V2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import SingleImageView from 'components/single_image_view/single_image_view';
|
||||
import SizeAwareImage from 'components/size_aware_image';
|
||||
|
||||
import {fireEvent, renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
describe('components/SingleImageView', () => {
|
||||
@@ -24,14 +23,19 @@ describe('components/SingleImageView', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
wrapper.setState({loaded: true});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
// Simulate loaded state by triggering image load
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toBeInTheDocument();
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 100, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 100, configurable: true});
|
||||
fireEvent.load(img!);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, SVG image', () => {
|
||||
@@ -41,27 +45,40 @@ describe('components/SingleImageView', () => {
|
||||
extension: 'svg',
|
||||
});
|
||||
const props = {...baseProps, fileInfo};
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.setState({viewPortWidth: 300});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
wrapper.setState({loaded: true});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
// Simulate loaded state by triggering image load
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toBeInTheDocument();
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 100, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 100, configurable: true});
|
||||
fireEvent.load(img!);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should call openModal on handleImageClick', () => {
|
||||
const wrapper = shallow(
|
||||
test('should call openModal on handleImageClick', async () => {
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView {...baseProps}/>,
|
||||
);
|
||||
|
||||
wrapper.find(SizeAwareImage).at(0).simulate('click', {preventDefault: () => { }});
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toBeInTheDocument();
|
||||
|
||||
// Simulate loaded state
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 100, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 100, configurable: true});
|
||||
fireEvent.load(img!);
|
||||
|
||||
// Click the image
|
||||
await userEvent.click(img!);
|
||||
expect(baseProps.actions.openModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should call toggleEmbedVisibility with post id', () => {
|
||||
test('should call toggleEmbedVisibility with post id', async () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
actions: {
|
||||
@@ -70,59 +87,67 @@ describe('components/SingleImageView', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
renderWithContext(
|
||||
<SingleImageView {...props}/>,
|
||||
);
|
||||
|
||||
const instance = wrapper.instance() as SingleImageView;
|
||||
const event = {
|
||||
stopPropagation: jest.fn(),
|
||||
} as unknown as React.MouseEvent<HTMLButtonElement>;
|
||||
instance.toggleEmbedVisibility(event);
|
||||
await userEvent.click(screen.getByRole('button', {name: 'Toggle Embed Visibility'}));
|
||||
expect(props.actions.toggleEmbedVisibility).toHaveBeenCalledTimes(1);
|
||||
expect(props.actions.toggleEmbedVisibility).toHaveBeenCalledWith('original_post_id');
|
||||
});
|
||||
|
||||
test('should set loaded state on callback of onImageLoaded on SizeAwareImage component', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView {...baseProps}/>,
|
||||
);
|
||||
expect(wrapper.state('loaded')).toEqual(false);
|
||||
wrapper.find(SizeAwareImage).prop('onImageLoaded')?.({height: 0, width: 0});
|
||||
expect(wrapper.state('loaded')).toEqual(true);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
// Initially should not have image-fade-in class (loaded = false)
|
||||
const imageLoadedDiv = container.querySelector('.image-loaded');
|
||||
expect(imageLoadedDiv).not.toHaveClass('image-fade-in');
|
||||
|
||||
// Simulate image loaded
|
||||
const img = container.querySelector('img');
|
||||
expect(img).toBeInTheDocument();
|
||||
Object.defineProperty(img, 'naturalHeight', {value: 100, configurable: true});
|
||||
Object.defineProperty(img, 'naturalWidth', {value: 100, configurable: true});
|
||||
fireEvent.load(img!);
|
||||
|
||||
// After load, should have image-fade-in class (loaded = true)
|
||||
expect(container.querySelector('.image-loaded')).toHaveClass('image-fade-in');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should correctly pass prop down to surround small images with a container', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find(SizeAwareImage).prop('handleSmallImageContainer')).
|
||||
toEqual(true);
|
||||
// The SizeAwareImage component should receive handleSmallImageContainer=true
|
||||
// This is verified by checking that the component renders correctly
|
||||
// The actual prop passing is internal, but we can verify the component structure
|
||||
expect(container.querySelector('.file-preview__button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should not show filename when image is displayed', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView
|
||||
{...baseProps}
|
||||
isEmbedVisible={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.image-header').text()).toHaveLength(0);
|
||||
expect(container.querySelector('.image-header')?.textContent).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('should show filename when image is collapsed', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = renderWithContext(
|
||||
<SingleImageView
|
||||
{...baseProps}
|
||||
isEmbedVisible={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.image-header').text()).
|
||||
toEqual(baseProps.fileInfo.name);
|
||||
expect(container.querySelector('.image-header')?.textContent).toEqual(baseProps.fileInfo.name);
|
||||
});
|
||||
|
||||
describe('permalink preview', () => {
|
||||
@@ -132,10 +157,10 @@ describe('components/SingleImageView', () => {
|
||||
isInPermalink: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<SingleImageView {...props}/>);
|
||||
const {container} = renderWithContext(<SingleImageView {...props}/>);
|
||||
|
||||
expect(wrapper.find('.image-permalink').exists()).toBe(true);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container.querySelector('.image-permalink')).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/timestamp/SemanticTime should support custom label 1`] = `
|
||||
<Memo(SemanticTime)
|
||||
aria-label="A custom label"
|
||||
value={2020-06-05T10:20:30.000Z}
|
||||
>
|
||||
<div>
|
||||
<time
|
||||
aria-label="A custom label"
|
||||
dateTime="2020-06-05T10:20:30.000"
|
||||
datetime="2020-06-05T10:20:30.000"
|
||||
/>
|
||||
</Memo(SemanticTime)>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,44 +1,42 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {mount} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import {render, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import SemanticTime from './semantic_time';
|
||||
|
||||
describe('components/timestamp/SemanticTime', () => {
|
||||
test('should render time semantically', () => {
|
||||
const date = new Date('2020-06-05T10:20:30Z');
|
||||
const wrapper = mount(
|
||||
render(
|
||||
<SemanticTime
|
||||
value={date}
|
||||
value={new Date('2020-06-05T10:20:30Z')}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('time').prop('dateTime')).toBe('2020-06-05T10:20:30.000');
|
||||
expect(screen.getByRole('time')).toHaveAttribute('datetime', '2020-06-05T10:20:30.000');
|
||||
});
|
||||
|
||||
test('should support passthrough children', () => {
|
||||
const date = new Date('2020-06-05T10:20:30Z');
|
||||
const wrapper = mount(
|
||||
render(
|
||||
<SemanticTime
|
||||
value={date}
|
||||
value={new Date('2020-06-05T10:20:30Z')}
|
||||
>
|
||||
{'10:20'}
|
||||
</SemanticTime>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('time').text()).toBe('10:20');
|
||||
expect(screen.getByRole('time')).toHaveTextContent('10:20');
|
||||
});
|
||||
|
||||
test('should support custom label', () => {
|
||||
const date = new Date('2020-06-05T10:20:30Z');
|
||||
const wrapper = mount(
|
||||
const {container} = render(
|
||||
<SemanticTime
|
||||
value={date}
|
||||
value={new Date('2020-06-05T10:20:30Z')}
|
||||
aria-label='A custom label'
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+35
-49
@@ -1,74 +1,60 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`components/UserProfile should match snapshot 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
hideStatus={false}
|
||||
overwriteName=""
|
||||
src="/api/v4/users/undefined/image?_=0"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="user-popover style--none"
|
||||
userId="user_id"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="user-popover style--none"
|
||||
>
|
||||
nickname
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/UserProfile should match snapshot, when displayUsername is enabled 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
hideStatus={false}
|
||||
overwriteName=""
|
||||
src="/api/v4/users/undefined/image?_=0"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="user-popover style--none"
|
||||
userId="user_id"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="user-popover style--none"
|
||||
>
|
||||
@username
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/UserProfile should match snapshot, when popover is disabled 1`] = `
|
||||
<div
|
||||
className="user-popover"
|
||||
>
|
||||
nickname
|
||||
<div>
|
||||
<div
|
||||
class="user-popover"
|
||||
>
|
||||
nickname
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/UserProfile should match snapshot, when user is shared 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
hideStatus={false}
|
||||
overwriteName=""
|
||||
src="/api/v4/users/undefined/image?_=0"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="user-popover style--none"
|
||||
userId="user_id"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="user-popover style--none"
|
||||
>
|
||||
nickname
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/UserProfile should match snapshot, with colorization 1`] = `
|
||||
<Fragment>
|
||||
<ProfilePopoverController
|
||||
hideStatus={false}
|
||||
overwriteName=""
|
||||
src="/api/v4/users/undefined/image?_=0"
|
||||
triggerComponentAs="button"
|
||||
triggerComponentClass="user-popover style--none"
|
||||
triggerComponentStyle={
|
||||
Object {
|
||||
"color": "#bbd279",
|
||||
}
|
||||
}
|
||||
userId="user_id"
|
||||
<div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="user-popover style--none"
|
||||
style="color: rgb(187, 210, 121);"
|
||||
>
|
||||
nickname
|
||||
</ProfilePopoverController>
|
||||
</Fragment>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import type {UserProfile as UserProfileType} from '@mattermost/types/users';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
|
||||
import UserProfile from './user_profile';
|
||||
|
||||
describe('components/UserProfile', () => {
|
||||
@@ -27,8 +28,8 @@ describe('components/UserProfile', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallow(<UserProfile {...baseProps}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(<UserProfile {...baseProps}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, with colorization', () => {
|
||||
@@ -37,8 +38,8 @@ describe('components/UserProfile', () => {
|
||||
colorize: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<UserProfile {...props}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(<UserProfile {...props}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, when user is shared', () => {
|
||||
@@ -47,27 +48,27 @@ describe('components/UserProfile', () => {
|
||||
isShared: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<UserProfile {...props}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
const {container} = render(<UserProfile {...props}/>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, when popover is disabled', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<UserProfile
|
||||
{...baseProps}
|
||||
disablePopover={true}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, when displayUsername is enabled', () => {
|
||||
const wrapper = shallow(
|
||||
const {container} = render(
|
||||
<UserProfile
|
||||
{...baseProps}
|
||||
displayUsername={true}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
+124
-174
@@ -1,157 +1,103 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`YoutubeVideo should match init snapshot 1`] = `
|
||||
<Provider
|
||||
store={
|
||||
Object {
|
||||
"clearActions": [Function],
|
||||
"dispatch": [Function],
|
||||
"getActions": [Function],
|
||||
"getState": [Function],
|
||||
"replaceReducer": [Function],
|
||||
"subscribe": [Function],
|
||||
}
|
||||
}
|
||||
>
|
||||
<YoutubeVideo
|
||||
googleDeveloperKey="googledevkey"
|
||||
hasImageProxy={false}
|
||||
link="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
metadata={
|
||||
Object {
|
||||
"images": Array [
|
||||
Object {
|
||||
"secure_url": "linkForThumbnail",
|
||||
"url": "linkForThumbnail",
|
||||
},
|
||||
],
|
||||
"title": "Youtube title",
|
||||
}
|
||||
}
|
||||
postId="post_id_1"
|
||||
show={true}
|
||||
youtubeReferrerPolicy={false}
|
||||
<div>
|
||||
<div
|
||||
class="post__embed-container"
|
||||
>
|
||||
<div
|
||||
className="post__embed-container"
|
||||
>
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
className="video-type"
|
||||
>
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
className="video-title"
|
||||
>
|
||||
<ForwardRef
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Youtube title
|
||||
</a>
|
||||
</ForwardRef>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
className="video-div embed-responsive-item"
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
class="video-type"
|
||||
>
|
||||
<YouTubeThumbnail
|
||||
onError={[Function]}
|
||||
play={[Function]}
|
||||
thumbnailUrl="https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg"
|
||||
videoTitle="Youtube title"
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
class="video-title"
|
||||
>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<div
|
||||
aria-label="Play Youtube title on YouTube"
|
||||
className="video-thumbnail__container"
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<Connect(Component)
|
||||
src="https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg"
|
||||
>
|
||||
<Memo(ExternalImage)
|
||||
dispatch={[Function]}
|
||||
enableSVGs={false}
|
||||
hasImageProxy={false}
|
||||
src="https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg"
|
||||
>
|
||||
<img
|
||||
alt="Thumbnail for Youtube title on YouTube"
|
||||
className="video-thumbnail"
|
||||
onError={[Function]}
|
||||
src="https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg"
|
||||
/>
|
||||
</Memo(ExternalImage)>
|
||||
</Connect(Component)>
|
||||
<div
|
||||
aria-label="Play video"
|
||||
className="play-button"
|
||||
role="presentation"
|
||||
>
|
||||
<i
|
||||
aria-hidden="true"
|
||||
className="icon-play"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</YouTubeThumbnail>
|
||||
Youtube title
|
||||
</a>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
class="video-div embed-responsive-item"
|
||||
>
|
||||
<div
|
||||
aria-label="Play Youtube title on YouTube"
|
||||
class="video-thumbnail__container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<img
|
||||
alt="Thumbnail for Youtube title on YouTube"
|
||||
class="video-thumbnail"
|
||||
src="https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg"
|
||||
/>
|
||||
<div
|
||||
aria-label="Play video"
|
||||
class="play-button"
|
||||
role="presentation"
|
||||
>
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="icon-play"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</YoutubeVideo>
|
||||
</Provider>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`YoutubeVideo should match snapshot for playing state 1`] = `
|
||||
<div
|
||||
className="post__embed-container"
|
||||
>
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
className="video-type"
|
||||
>
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
className="video-title"
|
||||
>
|
||||
<ForwardRef
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
<div>
|
||||
<div
|
||||
class="post__embed-container"
|
||||
>
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
class="video-type"
|
||||
>
|
||||
Youtube title
|
||||
</ForwardRef>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
className="video-div embed-responsive-item"
|
||||
>
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
class="video-title"
|
||||
>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Youtube title
|
||||
</a>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
className="video-playing"
|
||||
class="video-div embed-responsive-item"
|
||||
>
|
||||
<iframe
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen={true}
|
||||
frameBorder="0"
|
||||
height="100%"
|
||||
sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
|
||||
src="https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1"
|
||||
title="Youtube title"
|
||||
width="100%"
|
||||
/>
|
||||
<div
|
||||
class="video-playing"
|
||||
>
|
||||
<iframe
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen=""
|
||||
frameborder="0"
|
||||
height="100%"
|
||||
sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
|
||||
src="https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1"
|
||||
title="Youtube title"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -159,44 +105,48 @@ exports[`YoutubeVideo should match snapshot for playing state 1`] = `
|
||||
`;
|
||||
|
||||
exports[`YoutubeVideo should match snapshot for playing state and \`youtubeReferrerPolicy = true\` 1`] = `
|
||||
<div
|
||||
className="post__embed-container"
|
||||
>
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
className="video-type"
|
||||
>
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
className="video-title"
|
||||
>
|
||||
<ForwardRef
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
<div>
|
||||
<div
|
||||
class="post__embed-container"
|
||||
>
|
||||
<div>
|
||||
<h4>
|
||||
<span
|
||||
class="video-type"
|
||||
>
|
||||
Youtube title
|
||||
</ForwardRef>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
className="video-div embed-responsive-item"
|
||||
>
|
||||
YouTube -
|
||||
</span>
|
||||
<span
|
||||
class="video-title"
|
||||
>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=xqCoNej8Zxo"
|
||||
location="youtube_video"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Youtube title
|
||||
</a>
|
||||
</span>
|
||||
</h4>
|
||||
<div
|
||||
className="video-playing"
|
||||
class="video-div embed-responsive-item"
|
||||
>
|
||||
<iframe
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen={true}
|
||||
frameBorder="0"
|
||||
height="100%"
|
||||
referrerPolicy="origin"
|
||||
sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
|
||||
src="https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1"
|
||||
title="Youtube title"
|
||||
width="100%"
|
||||
/>
|
||||
<div
|
||||
class="video-playing"
|
||||
>
|
||||
<iframe
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen=""
|
||||
frameborder="0"
|
||||
height="100%"
|
||||
referrerpolicy="origin"
|
||||
sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
|
||||
src="https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1"
|
||||
title="Youtube title"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {mount, shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import mockStore from 'tests/test_store';
|
||||
import {fireEvent, renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
@@ -47,40 +45,51 @@ describe('YoutubeVideo', () => {
|
||||
};
|
||||
|
||||
test('should match init snapshot', () => {
|
||||
const store = mockStore(initialState);
|
||||
const wrapper = mount(
|
||||
<Provider store={store}>
|
||||
<YoutubeVideo {...baseProps}/>
|
||||
</Provider>,
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
// Verify that useMaxResThumbnail is true by default
|
||||
expect((wrapper.find('YoutubeVideo').instance() as YoutubeVideo).state.useMaxResThumbnail).toBe(true);
|
||||
expect(wrapper.find('h4').text()).toEqual('YouTube - Youtube title');
|
||||
// Verify that maxresdefault thumbnail is used by default (useMaxResThumbnail = true)
|
||||
expect(container.querySelector('.video-thumbnail')).toHaveAttribute(
|
||||
'src',
|
||||
'https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg',
|
||||
);
|
||||
expect(screen.getByRole('heading', {level: 4})).toHaveTextContent('YouTube - Youtube title');
|
||||
});
|
||||
|
||||
test('should match snapshot for playing state', () => {
|
||||
const wrapper = shallow(<YoutubeVideo {...baseProps}/>);
|
||||
wrapper.setState({playing: true});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
test('should match snapshot for playing state', async () => {
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
// Click the play button to set playing state
|
||||
await userEvent.click(screen.getByRole('button', {name: /Play Youtube title on YouTube/}));
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot for playing state and `youtubeReferrerPolicy = true`', () => {
|
||||
const wrapper = shallow(
|
||||
test('should match snapshot for playing state and `youtubeReferrerPolicy = true`', async () => {
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo
|
||||
{...baseProps}
|
||||
youtubeReferrerPolicy={true}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
wrapper.setState({playing: true});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
// Click the play button to set playing state
|
||||
await userEvent.click(screen.getByRole('button', {name: /Play Youtube title on YouTube/}));
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
// Verify that the iframe has a referrerPolicy attribute (set to 'origin') when youtubeReferrerPolicy is true.
|
||||
expect(wrapper.find('.video-playing iframe').prop('referrerPolicy')).toEqual('origin');
|
||||
expect(container.querySelector('.video-playing iframe')).toHaveAttribute('referrerPolicy', 'origin');
|
||||
|
||||
// Verify that the iframe src includes the new parameters
|
||||
expect(wrapper.find('.video-playing iframe').prop('src')).toEqual('https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1');
|
||||
expect(container.querySelector('.video-playing iframe')).toHaveAttribute('src', 'https://www.youtube.com/embed/xqCoNej8Zxo?autoplay=1&rel=0&fs=1&enablejsapi=1');
|
||||
});
|
||||
|
||||
test('should use url if secure_url is not present', () => {
|
||||
@@ -93,28 +102,56 @@ describe('YoutubeVideo', () => {
|
||||
}],
|
||||
},
|
||||
};
|
||||
const wrapper = shallow(<YoutubeVideo {...props}/>);
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
// Verify that useMaxResThumbnail is true by default
|
||||
expect(wrapper.state('useMaxResThumbnail')).toBe(true);
|
||||
// Verify that maxresdefault thumbnail is used by default (useMaxResThumbnail = true)
|
||||
expect(container.querySelector('.video-thumbnail')).toHaveAttribute(
|
||||
'src',
|
||||
'https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg',
|
||||
);
|
||||
});
|
||||
|
||||
describe('thumbnail fallback', () => {
|
||||
it('should fallback to hqdefault.jpg on image error', () => {
|
||||
const wrapper = shallow(<YoutubeVideo {...baseProps}/>);
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
// Simulate an image error by calling handleImageError.
|
||||
(wrapper.instance() as YoutubeVideo).handleImageError();
|
||||
const thumbnail = container.querySelector('.video-thumbnail');
|
||||
expect(thumbnail).toBeInTheDocument();
|
||||
|
||||
// Verify that useMaxResThumbnail is now false (will use hqdefault.jpg).
|
||||
expect(wrapper.state('useMaxResThumbnail')).toBe(false);
|
||||
// Verify that maxresdefault is used initially
|
||||
expect(thumbnail).toHaveAttribute(
|
||||
'src',
|
||||
'https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg',
|
||||
);
|
||||
|
||||
// Simulate an image error
|
||||
fireEvent.error(thumbnail!);
|
||||
|
||||
// Verify that hqdefault is used after error (useMaxResThumbnail is now false)
|
||||
expect(container.querySelector('.video-thumbnail')).toHaveAttribute(
|
||||
'src',
|
||||
'https://img.youtube.com/vi/xqCoNej8Zxo/hqdefault.jpg',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should initialize with useMaxResThumbnail set to true', () => {
|
||||
const wrapper = shallow(<YoutubeVideo {...baseProps}/>);
|
||||
const {container} = renderWithContext(
|
||||
<YoutubeVideo {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
// Verify that the component initializes with useMaxResThumbnail = true
|
||||
expect(wrapper.state('useMaxResThumbnail')).toBe(true);
|
||||
// Verify that the component initializes with useMaxResThumbnail = true by checking
|
||||
// that maxresdefault.jpg is used for the thumbnail
|
||||
expect(container.querySelector('.video-thumbnail')).toHaveAttribute(
|
||||
'src',
|
||||
'https://img.youtube.com/vi/xqCoNej8Zxo/maxresdefault.jpg',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,6 +25,11 @@ import type {GlobalState} from 'types/store';
|
||||
export * from '@testing-library/react';
|
||||
export {userEvent};
|
||||
|
||||
export type IntlOptions = {
|
||||
messages?: Record<string, string>;
|
||||
locale?: string;
|
||||
}
|
||||
|
||||
export type FullContextOptions = {
|
||||
intlMessages?: Record<string, string>;
|
||||
locale?: string;
|
||||
|
||||
Reference in New Issue
Block a user