[CORL-218] In Stream Approve and Reject (#2340)

* feat: instream moderation

* fix: tests

* test: add tests for in stream moderation

* fix: lint

* fix: snapshots
This commit is contained in:
Kiwi
2019-06-04 19:27:15 +02:00
committed by GitHub
parent 1cf2f61bfb
commit 593d94ddbb
74 changed files with 1106 additions and 297 deletions
@@ -170,6 +170,11 @@ exports[`renders permalink view 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -371,6 +376,11 @@ exports[`renders permalink view 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -570,6 +580,11 @@ exports[`renders permalink view 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -765,6 +780,11 @@ exports[`renders permalink view 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -949,6 +969,11 @@ exports[`renders permalink view 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -204,6 +204,11 @@ exports[`renders conversation thread 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -418,6 +423,11 @@ exports[`shows more of this conversation 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -624,6 +634,11 @@ exports[`shows more of this conversation 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -823,6 +838,11 @@ exports[`shows more of this conversation 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -74,18 +74,22 @@ exports[`cancel edit 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -805,18 +809,22 @@ exports[`edit a comment: render comment with edit button 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -1029,18 +1037,22 @@ exports[`edit a comment: server response 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -1244,18 +1256,22 @@ exports[`shows expiry message: edit form closed 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -83,6 +83,11 @@ exports[`renders comment stream with load more button 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -267,6 +272,11 @@ exports[`renders comment stream with load more button 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -74,18 +74,22 @@ exports[`post a comment: optimistic response 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -73,6 +73,11 @@ exports[`post a reply: open reply form 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -455,18 +460,22 @@ exports[`post a reply: optimistic response 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -665,6 +674,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -872,6 +886,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -1079,6 +1098,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -1286,6 +1310,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -1493,6 +1522,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -1700,6 +1734,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -73,6 +73,11 @@ exports[`post a reply: open reply form 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -440,18 +445,22 @@ exports[`post a reply: optimistic response 1`] = `
</div>
</div>
<div>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
<div
className="Flex-root Flex-flex Flex-itemGutter"
>
Edit
</button>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
Edit
</button>
</div>
</div>
</div>
<div
@@ -295,6 +295,11 @@ exports[`renders comment stream with community guidelines 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -479,6 +484,11 @@ exports[`renders comment stream with community guidelines 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -82,6 +82,11 @@ exports[`renders reply list 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -271,6 +276,11 @@ exports[`renders reply list 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -455,6 +465,11 @@ exports[`renders reply list 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -641,6 +656,11 @@ exports[`renders reply list 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -313,6 +313,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -502,6 +507,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -82,6 +82,11 @@ exports[`renders comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -73,6 +73,11 @@ exports[`renders deepest comment with link 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -83,6 +83,11 @@ exports[`renders app with comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -267,6 +272,11 @@ exports[`renders app with comment stream 1`] = `
</time>
</div>
</div>
<div>
<div
className="Flex-root Flex-flex Flex-itemGutter"
/>
</div>
</div>
<div
className="HorizontalGutter-root HorizontalGutter-full"
@@ -0,0 +1,135 @@
import { pureMerge } from "coral-common/utils";
import { GQLCOMMENT_STATUS, GQLResolver } from "coral-framework/schema";
import {
createResolversStub,
CreateTestRendererParams,
waitForElement,
within,
} from "coral-framework/testHelpers";
import { moderators, settings, stories } from "../../fixtures";
import create from "../create";
const story = stories[0];
const firstComment = story.comments.edges[0].node;
const viewer = moderators[0];
async function createTestRenderer(
params: CreateTestRendererParams<GQLResolver> = {}
) {
const { testRenderer, context } = create({
...params,
resolvers: pureMerge(
createResolversStub<GQLResolver>({
Query: {
settings: () => settings,
viewer: () => viewer,
story: () => story,
},
}),
params.resolvers
),
initLocalState: (localRecord, source, environment) => {
localRecord.setValue(story.id, "storyID");
localRecord.setValue(true, "loggedIn");
if (params.initLocalState) {
params.initLocalState(localRecord, source, environment);
}
},
});
const tabPane = await waitForElement(() =>
within(testRenderer.root).getByTestID("current-tab-pane")
);
return {
testRenderer,
context,
tabPane,
};
}
it("render go to moderate link", async () => {
const { testRenderer } = await createTestRenderer();
const comment = await waitForElement(() =>
within(testRenderer.root).getByTestID(`comment-${firstComment.id}`)
);
const caretButton = within(comment).getByLabelText("Moderate");
caretButton.props.onClick();
const link = within(comment).getByText("Go to Moderate", {
selector: "a",
exact: false,
});
expect(link.props.href).toBe(`/admin/moderate/comment/${firstComment.id}`);
});
it("accept comment", async () => {
const { testRenderer } = await createTestRenderer({
resolvers: createResolversStub<GQLResolver>({
Mutation: {
acceptComment: ({ variables }) => {
expectAndFail(variables).toMatchObject({
commentID: firstComment.id,
commentRevisionID: firstComment.revision.id,
});
return {
comment: pureMerge<typeof firstComment>(firstComment, {
status: GQLCOMMENT_STATUS.ACCEPTED,
}),
};
},
},
}),
});
const comment = await waitForElement(() =>
within(testRenderer.root).getByTestID(`comment-${firstComment.id}`)
);
const caretButton = within(comment).getByLabelText("Moderate");
caretButton.props.onClick();
const approveButton = within(comment).getByText("Approve", {
selector: "button",
});
approveButton.props.onClick();
await waitForElement(() =>
within(comment).getByText("Approved", { exact: false })
);
});
it("reject comment", async () => {
const { testRenderer, tabPane } = await createTestRenderer({
resolvers: createResolversStub<GQLResolver>({
Mutation: {
rejectComment: ({ variables }) => {
expectAndFail(variables).toMatchObject({
commentID: firstComment.id,
commentRevisionID: firstComment.revision.id,
});
return {
comment: pureMerge<typeof firstComment>(firstComment, {
status: GQLCOMMENT_STATUS.REJECTED,
}),
};
},
},
}),
});
const comment = await waitForElement(() =>
within(testRenderer.root).getByTestID(`comment-${firstComment.id}`)
);
const caretButton = within(comment).getByLabelText("Moderate");
caretButton.props.onClick();
const rejectButton = within(comment).getByText("Reject", {
selector: "button",
});
rejectButton.props.onClick();
await waitForElement(() =>
within(tabPane).getByText("You have rejected this comment", {
exact: false,
})
);
const link = within(tabPane).getByText(
"Go to Moderate to review this decision",
{ selector: "a", exact: false }
);
expect(link.props.href).toBe(`/admin/moderate/comment/${firstComment.id}`);
});