[CORL-239, CORL-128] Support disabled commenting and closed stories in Stream (#2205)

* feat: closed story + disabled commenting

* test: add feature test and fix bugs

* fix: snapshot

* fix: isClosed can't be null

* fix: remove duplicate DeepPartial type

* fix: border color
This commit is contained in:
Kiwi
2019-03-04 23:27:46 +01:00
committed by GitHub
parent 625809b42c
commit 4e043638f6
52 changed files with 1974 additions and 1246 deletions
@@ -74,6 +74,7 @@ exports[`cancel edit 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -752,6 +753,7 @@ exports[`edit a comment: render comment with edit button 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -941,6 +943,7 @@ exports[`edit a comment: server response 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -1121,6 +1124,7 @@ exports[`shows expiry message: edit form closed 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -70,6 +70,7 @@ exports[`renders comment stream with load more button 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -219,6 +220,7 @@ exports[`renders comment stream with load more button 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -157,6 +157,7 @@ exports[`renders permalink view 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -323,6 +324,7 @@ exports[`renders permalink view 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-2"
onBlur={[Function]}
onClick={[Function]}
@@ -487,6 +489,7 @@ exports[`renders permalink view 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-replies"
onBlur={[Function]}
onClick={[Function]}
@@ -647,6 +650,7 @@ exports[`renders permalink view 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-3"
onBlur={[Function]}
onClick={[Function]}
@@ -796,6 +800,7 @@ exports[`renders permalink view 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-4"
onBlur={[Function]}
onClick={[Function]}
@@ -180,6 +180,7 @@ exports[`renders conversation thread 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -359,6 +360,7 @@ exports[`shows more of this conversation 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -525,6 +527,7 @@ exports[`shows more of this conversation 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-2"
onBlur={[Function]}
onClick={[Function]}
@@ -689,6 +692,7 @@ exports[`shows more of this conversation 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -74,6 +74,7 @@ exports[`post a comment: optimistic response 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-uuid-0"
onBlur={[Function]}
onClick={[Function]}
@@ -60,6 +60,7 @@ exports[`post a reply: open reply form 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost Button-active"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -579,6 +580,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies"
onBlur={[Function]}
onClick={[Function]}
@@ -751,6 +753,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-1"
onBlur={[Function]}
onClick={[Function]}
@@ -923,6 +926,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-2"
onBlur={[Function]}
onClick={[Function]}
@@ -1095,6 +1099,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-3"
onBlur={[Function]}
onClick={[Function]}
@@ -1267,6 +1272,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-4"
onBlur={[Function]}
onClick={[Function]}
@@ -1439,6 +1445,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -1,323 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`post a reply and handle server error: open reply form 1`] = `
<div
data-testid="comment-comment-0"
>
<div
className="HorizontalGutter-root HorizontalGutter-full"
>
<div
className="Indent-root"
>
<div
className=""
>
<div
className="Comment-root"
role="article"
>
<div
className="Flex-root Flex-flex Flex-justifySpaceBetween Flex-directionRow"
>
<div
className="Flex-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
>
<span
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
>
Markus
</span>
<div
className="Flex-root Flex-flex Flex-itemGutter Flex-alignBaseline Flex-directionRow"
>
<time
className="Timestamp-root RelativeTime-root"
dateTime="2018-07-06T18:24:00.000Z"
title="2018-07-06T18:24:00.000Z"
>
2018-07-06T18:24:00.000Z
</time>
</div>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
>
<div
className="HTMLContent-root"
dangerouslySetInnerHTML={
Object {
"__html": "Joining Too",
}
}
/>
<div
className="Flex-root Flex-flex Flex-justifySpaceBetween"
>
<div
className="Flex-root Flex-flex Flex-halfItemGutter Flex-directionRow"
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost Button-active"
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
<span>
Reply
</span>
</button>
<div
className="Popover-root"
>
<button
aria-controls="permalink-popover-comment-0"
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
<span>
Share
</span>
</button>
<div
aria-hidden={true}
aria-labelledby="permalink-popover-comment-0-ariainfo"
id="permalink-popover-comment-0"
role="popup"
>
<div
className="AriaInfo-root"
id="permalink-popover-comment-0-ariainfo"
>
A dialog showing a permalink to the comment
</div>
</div>
</div>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
<span>
Respect
</span>
</button>
</div>
<div
className="Flex-root Flex-flex Flex-halfItemGutter Flex-directionRow"
>
<div
className="Popover-root"
>
<button
aria-controls="report-popover-comment-0"
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
<span>
Report
</span>
</button>
<div
aria-hidden={true}
aria-labelledby="report-popover-comment-0-ariainfo"
id="report-popover-comment-0"
role="popup"
>
<div
className="AriaInfo-root"
id="report-popover-comment-0-ariainfo"
>
A dialog for reporting comments
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<form
autoComplete="off"
id="comments-replyCommentForm-form-comment-0"
onSubmit={[Function]}
>
<div
className="HorizontalGutter-root HorizontalGutter-full"
>
<div
className="HorizontalGutter-root HorizontalGutter-half"
>
<div>
<label
className="AriaInfo-root"
htmlFor="comments-replyCommentForm-rte-comment-0"
>
Write a reply
</label>
<div
className="Flex-root ReplyTo-root Flex-flex Flex-alignCenter"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
reply
</span>
<span>
 
</span>
<span
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary ReplyTo-text"
>
Replying to:
<span
className="Typography-root Typography-heading4 Typography-colorTextPrimary ReplyTo-username"
>
Markus
</span>
</span>
</div>
<div>
<div
className=""
>
<div
aria-hidden="true"
className="RTE-placeholder RTE-placeholder"
>
Write a reply
</div>
<div
aria-placeholder="Write a reply"
className="RTE-contentEditable RTE-content"
contentEditable={true}
dangerouslySetInnerHTML={
Object {
"__html": "",
}
}
disabled={false}
id="comments-replyCommentForm-rte-comment-0"
onBlur={[Function]}
onChange={[Function]}
onCut={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
onPaste={[Function]}
onSelect={[Function]}
/>
<div
className="RTE-toolbar RTE-toolbarBottom Toolbar-toolbar"
>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Bold"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_bold
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Italic"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_italic
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Blockquote"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_quote
</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div
className="Flex-root Flex-flex Flex-halfItemGutter Flex-justifyFlexEnd Flex-directionRow"
>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantOutlined"
disabled={false}
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Cancel
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-disabled"
disabled={true}
onBlur={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="submit"
>
Submit
</button>
</div>
</div>
</form>
</div>
</div>
`;
exports[`post a reply: open reply form 1`] = `
<div
data-testid="comment-comment-0"
@@ -378,6 +60,7 @@ exports[`post a reply: open reply form 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost Button-active"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -719,6 +402,7 @@ exports[`post a reply: optimistic response 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-uuid-0"
onBlur={[Function]}
onClick={[Function]}
@@ -12,146 +12,142 @@ exports[`renders comment stream with community guidelines 1`] = `
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
>
<div
className="HorizontalGutter-root HorizontalGutter-full"
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Sign in
</button>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Register
</button>
</div>
<div
className="CallOut-root CallOut-colorPrimary"
>
<div
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Sign in
</button>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Register
</button>
</div>
<div
className="CallOut-root CallOut-colorPrimary"
>
<div
className="Markdown-root"
dangerouslySetInnerHTML={
Object {
"__html": "<h2 id=\\"community-guidelines\\">Community Guidelines</h2>
className="Markdown-root"
dangerouslySetInnerHTML={
Object {
"__html": "<h2 id=\\"community-guidelines\\">Community Guidelines</h2>
",
}
}
/>
</div>
}
/>
</div>
<div
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
>
<div
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
aria-hidden="true"
>
<div
aria-hidden="true"
>
<div>
<div>
<div
className=""
>
<div
className=""
aria-hidden="true"
className="RTE-placeholder RTE-placeholder "
>
<div
aria-hidden="true"
className="RTE-placeholder RTE-placeholder "
>
Post a comment
</div>
<div
aria-placeholder="Post a comment"
className="RTE-contentEditable RTE-content RTE-contentEditableDisabled"
contentEditable={false}
dangerouslySetInnerHTML={
Object {
"__html": "",
}
Post a comment
</div>
<div
aria-placeholder="Post a comment"
className="RTE-contentEditable RTE-content RTE-contentEditableDisabled"
contentEditable={false}
dangerouslySetInnerHTML={
Object {
"__html": "",
}
disabled={true}
onBlur={[Function]}
onChange={[Function]}
onCut={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
onPaste={[Function]}
onSelect={[Function]}
/>
<div
className="RTE-toolbar RTE-toolbarDisabled RTE-toolbarBottom Toolbar-toolbar"
}
disabled={true}
onBlur={[Function]}
onChange={[Function]}
onCut={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
onPaste={[Function]}
onSelect={[Function]}
/>
<div
className="RTE-toolbar RTE-toolbarDisabled RTE-toolbarBottom Toolbar-toolbar"
>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Bold"
type="button"
>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Bold"
type="button"
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_bold
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Italic"
type="button"
format_bold
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Italic"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_italic
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Blockquote"
type="button"
format_italic
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Blockquote"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_quote
</span>
</button>
</div>
format_quote
</span>
</button>
</div>
</div>
</div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
disabled={true}
onBlur={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="submit"
>
Sign in and Join the Conversation
</button>
</div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
disabled={true}
onBlur={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="submit"
>
Sign in and Join the Conversation
</button>
</div>
<div>
<div
@@ -281,6 +277,7 @@ exports[`renders comment stream with community guidelines 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -430,6 +427,7 @@ exports[`renders comment stream with community guidelines 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -69,6 +69,7 @@ exports[`renders reply list 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-replies"
onBlur={[Function]}
onClick={[Function]}
@@ -223,6 +224,7 @@ exports[`renders reply list 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-3"
onBlur={[Function]}
onClick={[Function]}
@@ -372,6 +374,7 @@ exports[`renders reply list 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-4"
onBlur={[Function]}
onClick={[Function]}
@@ -523,6 +526,7 @@ exports[`renders reply list 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-5"
onBlur={[Function]}
onClick={[Function]}
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders app with comment stream 1`] = `
exports[`renders comment stream 1`] = `
<div
className="HorizontalGutter-root App-root HorizontalGutter-full"
>
@@ -43,133 +43,129 @@ exports[`renders app with comment stream 1`] = `
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
>
<div
className="HorizontalGutter-root HorizontalGutter-full"
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Sign in
</button>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Register
</button>
</div>
<div
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
>
<div
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
aria-hidden="true"
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Sign in
</button>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Register
</button>
</div>
<div
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
>
<div
aria-hidden="true"
>
<div>
<div>
<div
className=""
>
<div
className=""
aria-hidden="true"
className="RTE-placeholder RTE-placeholder "
>
<div
aria-hidden="true"
className="RTE-placeholder RTE-placeholder "
>
Post a comment
</div>
<div
aria-placeholder="Post a comment"
className="RTE-contentEditable RTE-content RTE-contentEditableDisabled"
contentEditable={false}
dangerouslySetInnerHTML={
Object {
"__html": "",
}
Post a comment
</div>
<div
aria-placeholder="Post a comment"
className="RTE-contentEditable RTE-content RTE-contentEditableDisabled"
contentEditable={false}
dangerouslySetInnerHTML={
Object {
"__html": "",
}
disabled={true}
onBlur={[Function]}
onChange={[Function]}
onCut={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
onPaste={[Function]}
onSelect={[Function]}
/>
<div
className="RTE-toolbar RTE-toolbarDisabled RTE-toolbarBottom Toolbar-toolbar"
}
disabled={true}
onBlur={[Function]}
onChange={[Function]}
onCut={[Function]}
onFocus={[Function]}
onInput={[Function]}
onKeyDown={[Function]}
onPaste={[Function]}
onSelect={[Function]}
/>
<div
className="RTE-toolbar RTE-toolbarDisabled RTE-toolbarBottom Toolbar-toolbar"
>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Bold"
type="button"
>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Bold"
type="button"
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_bold
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Italic"
type="button"
format_bold
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Italic"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_italic
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Blockquote"
type="button"
format_italic
</span>
</button>
<button
className="Button-button"
disabled={false}
onClick={[Function]}
title="Blockquote"
type="button"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
<span
aria-hidden="true"
className="Icon-root Icon-md"
>
format_quote
</span>
</button>
</div>
format_quote
</span>
</button>
</div>
</div>
</div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
disabled={true}
onBlur={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="submit"
>
Sign in and Join the Conversation
</button>
</div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
disabled={true}
onBlur={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="submit"
>
Sign in and Join the Conversation
</button>
</div>
<div>
<div
@@ -299,6 +295,7 @@ exports[`renders app with comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-0"
onBlur={[Function]}
onClick={[Function]}
@@ -448,6 +445,7 @@ exports[`renders app with comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -69,6 +69,7 @@ exports[`renders comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-1"
onBlur={[Function]}
onClick={[Function]}
@@ -60,6 +60,7 @@ exports[`renders deepest comment with link 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -70,6 +70,7 @@ exports[`renders app with comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-2"
onBlur={[Function]}
onClick={[Function]}
@@ -219,6 +220,7 @@ exports[`renders app with comment stream 1`] = `
>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorRegular Button-variantGhost"
disabled={false}
id="comments-commentContainer-replyButton-comment-3"
onBlur={[Function]}
onClick={[Function]}
@@ -0,0 +1,99 @@
import sinon from "sinon";
import { waitForElement, within } from "talk-framework/testHelpers";
import { settings, stories } from "../fixtures";
import create from "./create";
afterEach(() => jest.useRealTimers());
async function createTestRenderer(
resolver: any = {},
options: { muteNetworkErrors?: boolean } = {}
) {
const resolvers = {
...resolver,
Query: {
settings: sinon.stub().returns(settings),
story: sinon.stub().callsFake((_: any, variables: any) => {
expect(variables.id).toBe(stories[0].id);
return stories[0];
}),
...resolver.Query,
},
};
const { testRenderer, context } = create({
// Set this to true, to see graphql responses.
logNetwork: false,
muteNetworkErrors: options.muteNetworkErrors,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(stories[0].id, "storyID");
},
});
return {
testRenderer,
context,
};
}
it("renders disabled comment stream", async () => {
const { testRenderer } = await createTestRenderer({
Query: {
settings: sinon.stub().callsFake(() => ({
...settings,
disableCommenting: {
enabled: true,
message: "commenting disabled",
},
})),
},
});
await waitForElement(() =>
within(testRenderer.root).getByText("commenting disabled")
);
});
it("renders closed comment stream", async () => {
const { testRenderer } = await createTestRenderer({
Query: {
story: sinon.stub().callsFake(() => ({
...stories[0],
isClosed: true,
})),
},
});
await waitForElement(() =>
within(testRenderer.root).getByText("Story is closed")
);
});
it("auto close comment stream when story closed at has been reached", async () => {
const closeIn = 360000;
const now = new Date();
const later = new Date(now.valueOf() + closeIn);
jest.useFakeTimers();
const { testRenderer } = await createTestRenderer({
Query: {
story: sinon.stub().callsFake(() => ({
...stories[0],
closedAt: later.toISOString(),
isClosed: false,
})),
},
});
expect(within(testRenderer.root).queryByText("Story is closed")).toBeNull();
await waitForElement(() =>
within(testRenderer.root).getByTestID("comments-stream-log")
);
jest.advanceTimersByTime(closeIn);
await waitForElement(() =>
within(testRenderer.root).getByText("Story is closed")
);
});
@@ -5,14 +5,16 @@ import { ERROR_CODES } from "talk-common/errors";
import { InvalidRequestError } from "talk-framework/lib/errors";
import {
createSinonStub,
findParentWithType,
waitForElement,
within,
} from "talk-framework/testHelpers";
import RTE from "@coralproject/rte";
import { baseComment, settings, stories, users } from "../fixtures";
import create from "./create";
function createTestRenderer(
async function createTestRenderer(
resolver: any,
options: { muteNetworkErrors?: boolean } = {}
) {
@@ -21,17 +23,15 @@ function createTestRenderer(
Query: {
settings: sinon.stub().returns(settings),
me: sinon.stub().returns(users[0]),
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
story: sinon.stub().callsFake((_: any, variables: any) => {
expect(variables.id).toBe(stories[0].id);
return stories[0];
}),
...resolver.Query,
},
};
return create({
const { testRenderer, context } = create({
// Set this to true, to see graphql responses.
logNetwork: false,
muteNetworkErrors: options.muteNetworkErrors,
@@ -41,10 +41,34 @@ function createTestRenderer(
localRecord.setValue(true, "loggedIn");
},
});
const tabPane = await waitForElement(() =>
within(testRenderer.root).getByTestID("current-tab-pane")
);
const rte = await waitForElement(
() =>
findParentWithType(
within(tabPane).getByLabelText("Post a comment"),
// We'll use the RTE component here as an exception because the
// jsdom does not support all of what is needed for rendering the
// Rich Text Editor.
RTE
)!
);
const form = findParentWithType(rte, "form")!;
return {
testRenderer,
context,
tabPane,
rte,
form,
};
}
it("post a comment", async () => {
const { testRenderer } = createTestRenderer({
const { rte, form, tabPane } = await createTestRenderer({
Mutation: {
createComment: sinon.stub().callsFake((_, data) => {
expect(data).toEqual({
@@ -70,20 +94,10 @@ it("post a comment", async () => {
},
});
const tabPane = await waitForElement(() =>
within(testRenderer.root).getByTestID("current-tab-pane")
);
testRenderer.root
.findByProps({ inputId: "comments-postCommentForm-field" })
.props.onChange({ html: "<b>Hello world!</b>" });
rte.props.onChange({ html: "<b>Hello world!</b>" });
timekeeper.freeze(new Date(baseComment.createdAt));
testRenderer.root
.findByProps({ id: "comments-postCommentForm-form" })
.props.onSubmit();
form.props.onSubmit();
timekeeper.reset();
// Test optimistic response.
@@ -100,7 +114,7 @@ it("post a comment", async () => {
});
it("post a comment and handle server error", async () => {
const { testRenderer } = createTestRenderer(
const { form, rte, tabPane } = await createTestRenderer(
{
Mutation: {
createComment: sinon.stub().callsFake(() => {
@@ -111,22 +125,74 @@ it("post a comment and handle server error", async () => {
{ muteNetworkErrors: true }
);
const tabPane = await waitForElement(() =>
within(testRenderer.root).getByTestID("current-tab-pane")
);
testRenderer.root
.findByProps({ inputId: "comments-postCommentForm-field" })
.props.onChange({ html: "<b>Hello world!</b>" });
rte.props.onChange({ html: "<b>Hello world!</b>" });
timekeeper.freeze(new Date(baseComment.createdAt));
testRenderer.root
.findByProps({ id: "comments-postCommentForm-form" })
.props.onSubmit();
form.props.onSubmit();
timekeeper.reset();
// Look for internal error being displayed.
await waitForElement(() => within(tabPane).getByText("INTERNAL_ERROR"));
});
it("handle disabled commenting error", async () => {
const { rte, form } = await createTestRenderer(
{
Mutation: {
createComment: sinon.stub().callsFake(() => {
throw new InvalidRequestError({
code: ERROR_CODES.COMMENTING_DISABLED,
});
}),
},
Query: {
settings: createSinonStub(
s => s.onFirstCall().returns(settings),
s =>
s.onSecondCall().returns({
...settings,
disableCommenting: {
enabled: true,
message: "commenting disabled",
},
})
),
},
},
{ muteNetworkErrors: true }
);
rte.props.onChange({ html: "abc" });
form.props.onSubmit();
await waitForElement(() => within(form).getByText("commenting disabled"));
expect(rte.props.disabled).toBe(true);
expect(within(form).getByText("Submit").props.disabled).toBe(true);
});
it("handle story closed", async () => {
let returnStory = stories[0];
const { rte, form } = await createTestRenderer(
{
Mutation: {
createComment: sinon.stub().callsFake(() => {
throw new InvalidRequestError({
code: ERROR_CODES.STORY_CLOSED,
});
}),
},
Query: {
story: sinon.stub().callsFake(() => returnStory),
},
},
{ muteNetworkErrors: true }
);
rte.props.onChange({ html: "abc" });
form.props.onSubmit();
// Change the story that we return to be closed.
returnStory = { ...stories[0], isClosed: true };
await waitForElement(() => within(form).getByText("Story is closed"));
expect(rte.props.disabled).toBe(true);
expect(within(form).getByText("Submit").props.disabled).toBe(true);
});
@@ -4,15 +4,16 @@ import timekeeper from "timekeeper";
import { ERROR_CODES } from "talk-common/errors";
import { InvalidRequestError } from "talk-framework/lib/errors";
import {
createSinonStub,
findParentWithType,
waitForElement,
within,
} from "talk-framework/testHelpers";
import RTE from "@coralproject/rte";
import { baseComment, settings, stories, users } from "../fixtures";
import create from "./create";
function createTestRenderer(
async function createTestRenderer(
resolver: any,
options: { muteNetworkErrors?: boolean } = {}
) {
@@ -21,17 +22,15 @@ function createTestRenderer(
Query: {
settings: sinon.stub().returns(settings),
me: sinon.stub().returns(users[0]),
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
story: sinon.stub().callsFake((_: any, variables: any) => {
expect(variables.id).toBe(stories[0].id);
return stories[0];
}),
...resolver.Query,
},
};
return create({
const { testRenderer, context } = create({
// Set this to true, to see graphql responses.
logNetwork: false,
muteNetworkErrors: options.muteNetworkErrors,
@@ -41,10 +40,39 @@ function createTestRenderer(
localRecord.setValue(true, "loggedIn");
},
});
const comment = await waitForElement(() =>
within(testRenderer.root).getByTestID("comment-comment-0")
);
// Open reply form.
within(comment)
.getByText("Reply", { selector: "button" })
.props.onClick();
const rte = await waitForElement(
() =>
findParentWithType(
within(comment).getByLabelText("Write a reply"),
// We'll use the RTE component here as an exception because the
// jsdom does not support all of what is needed for rendering the
// Rich Text Editor.
RTE
)!
);
const form = findParentWithType(rte, "form")!;
return {
testRenderer,
context,
comment,
rte,
form,
};
}
it("post a reply", async () => {
const { testRenderer } = createTestRenderer({
const { testRenderer, comment, rte, form } = await createTestRenderer({
Mutation: {
createCommentReply: sinon.stub().callsFake((_, data) => {
expect(data).toEqual({
@@ -71,29 +99,16 @@ it("post a reply", async () => {
}),
},
});
const streamLog = await waitForElement(() =>
within(testRenderer.root).getByTestID("comments-stream-log")
);
const comment = within(streamLog).getByTestID("comment-comment-0");
// Open reply form.
within(comment)
.getByText("Reply", { selector: "button" })
.props.onClick();
const form = await waitForElement(() => within(comment).getByType("form"));
expect(within(comment).toJSON()).toMatchSnapshot("open reply form");
// Write reply .
testRenderer.root
.findByProps({ inputId: "comments-replyCommentForm-rte-comment-0" })
.props.onChange({ html: "<b>Hello world!</b>" });
rte.props.onChange({ html: "<b>Hello world!</b>" });
timekeeper.freeze(new Date(baseComment.createdAt));
form.props.onSubmit();
const commentReplyList = within(streamLog).getByTestID(
const commentReplyList = within(testRenderer.root).getByTestID(
"commentReplyList-comment-0"
);
@@ -110,7 +125,7 @@ it("post a reply", async () => {
});
it("post a reply and handle server error", async () => {
const { testRenderer } = createTestRenderer(
const { rte, form, comment } = await createTestRenderer(
{
Mutation: {
createCommentReply: sinon.stub().callsFake(() => {
@@ -120,24 +135,9 @@ it("post a reply and handle server error", async () => {
},
{ muteNetworkErrors: true }
);
const streamLog = await waitForElement(() =>
within(testRenderer.root).getByTestID("comments-stream-log")
);
const comment = within(streamLog).getByTestID("comment-comment-0");
// Open reply form.
within(comment)
.getByText("Reply", { selector: "button" })
.props.onClick();
const form = await waitForElement(() => within(comment).getByType("form"));
expect(within(comment).toJSON()).toMatchSnapshot("open reply form");
// Write reply .
testRenderer.root
.findByProps({ inputId: "comments-replyCommentForm-rte-comment-0" })
.props.onChange({ html: "<b>Hello world!</b>" });
rte.props.onChange({ html: "<b>Hello world!</b>" });
timekeeper.freeze(new Date(baseComment.createdAt));
form.props.onSubmit();
@@ -145,3 +145,67 @@ it("post a reply and handle server error", async () => {
// Look for internal error being displayed.
await waitForElement(() => within(comment).getByText("INTERNAL_ERROR"));
});
it("handle disabled commenting error", async () => {
let returnSettings = settings;
const { rte, form } = await createTestRenderer(
{
Mutation: {
createCommentReply: sinon.stub().callsFake(() => {
throw new InvalidRequestError({
code: ERROR_CODES.COMMENTING_DISABLED,
});
}),
},
Query: {
settings: sinon.stub().callsFake(() => returnSettings),
},
},
{ muteNetworkErrors: true }
);
rte.props.onChange({ html: "abc" });
form.props.onSubmit();
// Change the settings that we return to be closed.
returnSettings = {
...settings,
disableCommenting: {
enabled: true,
message: "commenting disabled",
},
};
await waitForElement(() => within(form).getByText("commenting disabled"));
expect(rte.props.disabled).toBe(true);
expect(within(form).getByText("Submit").props.disabled).toBe(true);
});
it("handle story closed error", async () => {
let returnStory = stories[0];
const { rte, form } = await createTestRenderer(
{
Mutation: {
createCommentReply: sinon.stub().callsFake(() => {
throw new InvalidRequestError({
code: ERROR_CODES.STORY_CLOSED,
});
}),
},
Query: {
story: sinon.stub().callsFake(() => returnStory),
},
},
{ muteNetworkErrors: true }
);
rte.props.onChange({ html: "abc" });
form.props.onSubmit();
// Change the story that we return to be closed.
returnStory = { ...stories[0], isClosed: true };
await waitForElement(() => within(form).getByText("Story is closed"));
expect(rte.props.disabled).toBe(true);
expect(within(form).getByText("Submit").props.disabled).toBe(true);
});
@@ -1,41 +1,44 @@
import { ReactTestRenderer } from "react-test-renderer";
import sinon from "sinon";
import {
createSinonStub,
waitForElement,
within,
} from "talk-framework/testHelpers";
import { waitForElement, within } from "talk-framework/testHelpers";
import { settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
async function createTestRenderer(
resolver: any = {},
options: { muteNetworkErrors?: boolean } = {}
) {
const resolvers = {
...resolver,
Query: {
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
settings: sinon.stub().returns(settings),
story: sinon.stub().callsFake((_: any, variables: any) => {
expect(variables.id).toBe(stories[0].id);
return stories[0];
}),
...resolver.Query,
},
};
({ testRenderer } = create({
const { testRenderer, context } = create({
// Set this to true, to see graphql responses.
logNetwork: false,
muteNetworkErrors: options.muteNetworkErrors,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
});
it("renders app with comment stream", async () => {
return {
testRenderer,
context,
};
}
it("renders comment stream", async () => {
const { testRenderer } = await createTestRenderer();
await waitForElement(() =>
within(testRenderer.root).getByTestID("comments-stream-log")
);
+6
View File
@@ -11,6 +11,12 @@ export const settings = {
enabled: false,
content: "",
},
disableCommenting: {
enabled: false,
message: "Commenting has been disabled",
},
closedAt: null,
closedMessage: "Story is closed",
auth: {
integrations: {
facebook: {