mirror of
https://github.com/wassname/talk.git
synced 2026-08-05 13:30:26 +08:00
[CORL-159, CORL-160] Stream Config Tab (#2219)
* feat: Implement stream configuration tab * feat: split profile & configure into separate bundles * chore: better role logic * fix+chore: add test cases, implement expectAndFail, refactor tests * chore: add some comments * chore: Update src/core/client/framework/lib/form/helpers.tsx Co-Authored-By: cvle <vinh@wikiwi.io> * feat: support new graphql mutations/schema * fix: ci fixes * fix: improvement to revision loading * fix: updated some tests * fix: adapt client to changes * fix: remove obsolote isClosed in UpdateStory * ci: increase no_output_timeout for build
This commit is contained in:
@@ -8,8 +8,9 @@ import Configure from "./Configure";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof Configure> = {
|
||||
onSave: noop,
|
||||
onSubmit: noop,
|
||||
onChange: noop,
|
||||
children: <span />,
|
||||
};
|
||||
const renderer = createRenderer();
|
||||
renderer.render(<Configure {...props} />);
|
||||
|
||||
@@ -12,17 +12,18 @@ import { Link, Navigation } from "./Navigation";
|
||||
import SideBar from "./SideBar";
|
||||
|
||||
interface Props {
|
||||
onSave: (settings: any, form: FormApi) => void;
|
||||
onSubmit: (settings: any, form: FormApi) => void;
|
||||
onChange: (formState: FormState) => void;
|
||||
children: React.ReactElement;
|
||||
}
|
||||
|
||||
const Configure: StatelessComponent<Props> = ({
|
||||
onSave,
|
||||
onSubmit,
|
||||
onChange,
|
||||
children,
|
||||
}) => (
|
||||
<MainLayout data-testid="configure-container">
|
||||
<Form onSubmit={onSave}>
|
||||
<Form onSubmit={onSubmit}>
|
||||
{({ handleSubmit, submitting, pristine, form, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit} id="configure-form">
|
||||
<FormSpy onChange={onChange} />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { FormApi, FormState } from "final-form";
|
||||
import { Router } from "found";
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
@@ -7,117 +6,54 @@ import {
|
||||
UpdateSettingsMutation,
|
||||
withUpdateSettingsMutation,
|
||||
} from "talk-admin/mutations";
|
||||
import { TalkContext, withContext } from "talk-framework/lib/bootstrap";
|
||||
import { InvalidRequestError } from "talk-framework/lib/errors";
|
||||
import { getMessage } from "talk-framework/lib/i18n";
|
||||
import { SubmitHookHandler } from "talk-framework/lib/form";
|
||||
|
||||
import Configure from "../components/Configure";
|
||||
import {
|
||||
AddSubmitHook,
|
||||
SubmitHook,
|
||||
SubmitHookContextProvider,
|
||||
} from "../submitHook";
|
||||
import NavigationWarningContainer from "./NavigationWarningContainer";
|
||||
|
||||
interface Props {
|
||||
localeBundles: TalkContext["localeBundles"];
|
||||
router: Router;
|
||||
updateSettings: UpdateSettingsMutation;
|
||||
children: React.ReactNode;
|
||||
children: React.ReactElement;
|
||||
}
|
||||
|
||||
class ConfigureContainer extends React.Component<Props> {
|
||||
private dirty = false;
|
||||
private removeTransitionHook: () => void;
|
||||
private submitHooks: SubmitHook[] = [];
|
||||
interface State {
|
||||
dirty: boolean;
|
||||
}
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
class ConfigureContainer extends React.Component<Props, State> {
|
||||
public state: State = {
|
||||
dirty: false,
|
||||
};
|
||||
|
||||
this.dirty = false;
|
||||
|
||||
const warningMessage = getMessage(
|
||||
props.localeBundles,
|
||||
"configure-unsavedInputWarning",
|
||||
"You have unsaved input. Are you sure you want to leave this page?"
|
||||
);
|
||||
|
||||
this.removeTransitionHook = props.router.addTransitionHook(
|
||||
() => (this.dirty ? warningMessage : true)
|
||||
);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.removeTransitionHook();
|
||||
}
|
||||
|
||||
private handleSave = async (
|
||||
private handleExecute = async (
|
||||
data: UpdateSettingsInput["settings"],
|
||||
form: FormApi
|
||||
) => {
|
||||
let cancelled = false;
|
||||
let formErrors: Record<string, React.ReactNode> = {};
|
||||
const executeCallbacks: Array<() => Promise<any>> = [];
|
||||
const cancel = (errors: Record<string, React.ReactNode>) => {
|
||||
cancelled = true;
|
||||
formErrors = { ...errors, ...formErrors };
|
||||
};
|
||||
const onExecute = (cb: () => Promise<any>) => {
|
||||
executeCallbacks.push(cb);
|
||||
};
|
||||
try {
|
||||
// Call submit hooks, that can manipulate what
|
||||
// we send as the mutation.
|
||||
let nextData = data;
|
||||
for (const hook of this.submitHooks) {
|
||||
const result = await hook(nextData, { cancel, onExecute });
|
||||
if (result) {
|
||||
nextData = result;
|
||||
}
|
||||
}
|
||||
if (cancelled) {
|
||||
return formErrors;
|
||||
}
|
||||
|
||||
executeCallbacks.push(() =>
|
||||
this.props.updateSettings({ settings: nextData })
|
||||
);
|
||||
for (const c of executeCallbacks.map(cb => cb())) {
|
||||
await c;
|
||||
}
|
||||
form.initialize(data);
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidRequestError) {
|
||||
return error.invalidArgs;
|
||||
}
|
||||
// tslint:disable-next-line:no-console
|
||||
console.error(error);
|
||||
}
|
||||
return undefined;
|
||||
await this.props.updateSettings({ settings: data });
|
||||
form.initialize(data);
|
||||
};
|
||||
|
||||
private handleChange = ({ dirty }: FormState) => {
|
||||
this.dirty = dirty;
|
||||
};
|
||||
|
||||
private addSubmitHook: AddSubmitHook = hook => {
|
||||
this.submitHooks.push(hook);
|
||||
return () => {
|
||||
this.submitHooks = this.submitHooks.filter(h => h !== hook);
|
||||
};
|
||||
if (dirty !== this.state.dirty) {
|
||||
this.setState({ dirty });
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<SubmitHookContextProvider value={this.addSubmitHook}>
|
||||
<Configure onChange={this.handleChange} onSave={this.handleSave}>
|
||||
{this.props.children}
|
||||
</Configure>
|
||||
</SubmitHookContextProvider>
|
||||
<>
|
||||
<NavigationWarningContainer active={this.state.dirty} />
|
||||
<SubmitHookHandler onExecute={this.handleExecute}>
|
||||
{({ onSubmit }) => (
|
||||
<Configure onChange={this.handleChange} onSubmit={onSubmit}>
|
||||
{this.props.children}
|
||||
</Configure>
|
||||
)}
|
||||
</SubmitHookHandler>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withContext(({ localeBundles }) => ({ localeBundles }))(
|
||||
withUpdateSettingsMutation(ConfigureContainer)
|
||||
);
|
||||
const enhanced = withUpdateSettingsMutation(ConfigureContainer);
|
||||
export default enhanced;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Match, Router, withRouter } from "found";
|
||||
import React from "react";
|
||||
|
||||
import { TalkContext, withContext } from "talk-framework/lib/bootstrap";
|
||||
import { getMessage } from "talk-framework/lib/i18n";
|
||||
|
||||
interface Props {
|
||||
localeBundles: TalkContext["localeBundles"];
|
||||
router: Router;
|
||||
active: boolean;
|
||||
match: Match;
|
||||
}
|
||||
|
||||
class NavigationWarningContainer extends React.Component<Props> {
|
||||
private removeTransitionHook: () => void;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
const warningMessage = getMessage(
|
||||
props.localeBundles,
|
||||
"configure-unsavedInputWarning",
|
||||
"You have unsaved input. Are you sure you want to leave this page?"
|
||||
);
|
||||
|
||||
this.removeTransitionHook = props.router.addTransitionHook(
|
||||
() => (this.props.active ? warningMessage : true)
|
||||
);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.removeTransitionHook();
|
||||
}
|
||||
|
||||
public render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withContext(({ localeBundles }) => ({ localeBundles }))(
|
||||
withRouter(NavigationWarningContainer)
|
||||
);
|
||||
export default enhanced;
|
||||
+2
-3
@@ -1,6 +1,7 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field } from "react-final-form";
|
||||
import { parseBool } from "talk-framework/lib/form";
|
||||
|
||||
import { CheckBox, FormField } from "talk-ui/components";
|
||||
|
||||
@@ -14,8 +15,6 @@ interface Props {
|
||||
children: (disabledInside: boolean) => React.ReactNode;
|
||||
}
|
||||
|
||||
const bool = (v: any) => !!v;
|
||||
|
||||
const ConfigBoxWithToggleField: StatelessComponent<Props> = ({
|
||||
id,
|
||||
name,
|
||||
@@ -24,7 +23,7 @@ const ConfigBoxWithToggleField: StatelessComponent<Props> = ({
|
||||
children,
|
||||
...rest
|
||||
}) => (
|
||||
<Field name={name} type="checkbox" parse={bool}>
|
||||
<Field name={name} type="checkbox" parse={parseBool}>
|
||||
{({ input }) => (
|
||||
<ConfigBox
|
||||
{...rest}
|
||||
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field } from "react-final-form";
|
||||
import { parseBool } from "talk-framework/lib/form";
|
||||
|
||||
import { CheckBox, Flex, FormField, InputLabel } from "talk-ui/components";
|
||||
|
||||
const bool = (v: any) => !!v;
|
||||
|
||||
interface Props {
|
||||
label: React.ReactNode;
|
||||
name: string;
|
||||
@@ -20,7 +19,7 @@ const TargetFilterField: StatelessComponent<Props> = ({
|
||||
<FormField>
|
||||
<InputLabel>{label}</InputLabel>
|
||||
<Flex direction="row" itemGutter="double">
|
||||
<Field name={`${name}.admin`} type="checkbox" parse={bool}>
|
||||
<Field name={`${name}.admin`} type="checkbox" parse={parseBool}>
|
||||
{({ input, meta }) => (
|
||||
<Localized id="configure-auth-targetFilterTalkAdmin">
|
||||
<CheckBox
|
||||
@@ -35,7 +34,7 @@ const TargetFilterField: StatelessComponent<Props> = ({
|
||||
</Localized>
|
||||
)}
|
||||
</Field>
|
||||
<Field name={`${name}.stream`} type="checkbox" parse={bool}>
|
||||
<Field name={`${name}.stream`} type="checkbox" parse={parseBool}>
|
||||
{({ input }) => (
|
||||
<Localized id="configure-auth-targetFilterCommentStream">
|
||||
<CheckBox
|
||||
|
||||
+4
-4
@@ -7,15 +7,15 @@ import { graphql } from "react-relay";
|
||||
|
||||
import { AuthConfigContainer_auth as AuthData } from "talk-admin/__generated__/AuthConfigContainer_auth.graphql";
|
||||
import { TalkContext, withContext } from "talk-framework/lib/bootstrap";
|
||||
import { getMessage } from "talk-framework/lib/i18n";
|
||||
|
||||
import { withFragmentContainer } from "talk-framework/lib/relay";
|
||||
import {
|
||||
AddSubmitHook,
|
||||
RemoveSubmitHook,
|
||||
SubmitHook,
|
||||
withSubmitHookContext,
|
||||
} from "../../../submitHook";
|
||||
} from "talk-framework/lib/form";
|
||||
import { getMessage } from "talk-framework/lib/i18n";
|
||||
import { withFragmentContainer } from "talk-framework/lib/relay";
|
||||
|
||||
import AuthConfig from "../components/AuthConfig";
|
||||
|
||||
interface Props {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ const ClosedStreamMessageConfig: StatelessComponent<Props> = ({ disabled }) => (
|
||||
Write a message to appear after a story is closed for commenting.
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Field name="closedMessage">
|
||||
<Field name="closeCommenting.message">
|
||||
{({ input, meta }) => (
|
||||
<>
|
||||
<Suspense fallback={<Spinner />}>
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ const ClosingCommentStreamsConfig: StatelessComponent<Props> = ({
|
||||
<Localized id="configure-general-closingCommentStreams-closeCommentsAutomatically">
|
||||
<InputLabel container="legend">Close Comments Automatically</InputLabel>
|
||||
</Localized>
|
||||
<OnOffField name="autoCloseStream" disabled={disabled} />
|
||||
<OnOffField name="closeCommenting.auto" disabled={disabled} />
|
||||
</FormField>
|
||||
<FormField container={<FieldSet />}>
|
||||
<Localized id="configure-general-closingCommentStreams-closeCommentsAfter">
|
||||
@@ -53,7 +53,7 @@ const ClosingCommentStreamsConfig: StatelessComponent<Props> = ({
|
||||
</Localized>
|
||||
|
||||
<Field
|
||||
name="closedTimeout"
|
||||
name="closeCommenting.timeout"
|
||||
validate={composeValidators(
|
||||
required,
|
||||
validateWholeNumberGreaterThan(0)
|
||||
|
||||
+3
-1
@@ -27,7 +27,9 @@ class ClosedStreamMessageConfigContainer extends React.Component<Props> {
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment ClosedStreamMessageConfigContainer_settings on Settings {
|
||||
closedMessage
|
||||
closeCommenting {
|
||||
message
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(ClosedStreamMessageConfigContainer);
|
||||
|
||||
+4
-2
@@ -27,8 +27,10 @@ class ClosingCommentStreamsConfigContainer extends React.Component<Props> {
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment ClosingCommentStreamsConfigContainer_settings on Settings {
|
||||
autoCloseStream
|
||||
closedTimeout
|
||||
closeCommenting {
|
||||
auto
|
||||
timeout
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(ClosingCommentStreamsConfigContainer);
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ const OrganizationNameConfig: StatelessComponent<Props> = ({ disabled }) => (
|
||||
<Localized id="configure-organization-email">
|
||||
<Header
|
||||
container={
|
||||
<label htmlFor="configure-organization-organizationContactEmail" />
|
||||
<label htmlFor="configure-organization-organization.contactEmail" />
|
||||
}
|
||||
>
|
||||
Organization Email
|
||||
@@ -35,7 +35,7 @@ const OrganizationNameConfig: StatelessComponent<Props> = ({ disabled }) => (
|
||||
>
|
||||
<Typography variant="detail">This E-Mail will be used</Typography>
|
||||
</Localized>
|
||||
<Field name="organizationContactEmail" validate={required}>
|
||||
<Field name="organization.contactEmail" validate={required}>
|
||||
{({ input, meta }) => (
|
||||
<>
|
||||
<TextField
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ const OrganizationNameConfig: StatelessComponent<Props> = ({ disabled }) => (
|
||||
<Localized id="configure-organization-name">
|
||||
<Header
|
||||
container={
|
||||
<label htmlFor="configure-organization-organizationName" />
|
||||
<label htmlFor="configure-organization-organization.name" />
|
||||
}
|
||||
>
|
||||
Organization Name
|
||||
@@ -38,7 +38,7 @@ const OrganizationNameConfig: StatelessComponent<Props> = ({ disabled }) => (
|
||||
community and organization members
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Field name="organizationName" validate={required}>
|
||||
<Field name="organization.name" validate={required}>
|
||||
{({ input, meta }) => (
|
||||
<>
|
||||
<TextField
|
||||
|
||||
+3
-1
@@ -27,7 +27,9 @@ class OrganizationContactEmailConfigContainer extends React.Component<Props> {
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment OrganizationContactEmailConfigContainer_settings on Settings {
|
||||
organizationContactEmail
|
||||
organization {
|
||||
contactEmail
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(OrganizationContactEmailConfigContainer);
|
||||
|
||||
+3
-1
@@ -27,7 +27,9 @@ class OrganizationNameConfigContainer extends React.Component<Props> {
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment OrganizationNameConfigContainer_settings on Settings {
|
||||
organizationName
|
||||
organization {
|
||||
name
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(OrganizationNameConfigContainer);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { noop } from "lodash";
|
||||
import React from "react";
|
||||
|
||||
export type SubmitHook = (
|
||||
data: any,
|
||||
actions: {
|
||||
// Callback will be called after all validations has passed and
|
||||
// the submit has not been cancelled.
|
||||
onExecute: (cb: () => Promise<any>) => void;
|
||||
cancel: (errors?: Record<string, React.ReactNode>) => void;
|
||||
}
|
||||
) => Promise<any> | any;
|
||||
export type RemoveSubmitHook = () => void;
|
||||
export type AddSubmitHook = (hook: SubmitHook) => RemoveSubmitHook;
|
||||
export type SubmitHookContext = AddSubmitHook;
|
||||
|
||||
const { Provider, Consumer } = React.createContext<SubmitHookContext>(
|
||||
() => noop
|
||||
);
|
||||
|
||||
export const SubmitHookContextProvider = Provider;
|
||||
export const SubmitHookContextConsumer = Consumer;
|
||||
@@ -1,9 +0,0 @@
|
||||
export {
|
||||
AddSubmitHook,
|
||||
SubmitHook,
|
||||
RemoveSubmitHook,
|
||||
SubmitHookContext,
|
||||
SubmitHookContextConsumer,
|
||||
SubmitHookContextProvider,
|
||||
} from "./SubmitHookContext";
|
||||
export { default as withSubmitHookContext } from "./withSubmitHookContext";
|
||||
@@ -1,12 +0,0 @@
|
||||
import { createContextHOC } from "talk-framework/helpers";
|
||||
import {
|
||||
SubmitHookContext,
|
||||
SubmitHookContextConsumer,
|
||||
} from "./SubmitHookContext";
|
||||
|
||||
const withSubmitHookContext = createContextHOC<SubmitHookContext>(
|
||||
"withSubmitHookContext",
|
||||
SubmitHookContextConsumer
|
||||
);
|
||||
|
||||
export default withSubmitHookContext;
|
||||
@@ -90,83 +90,6 @@ exports[`accepts valid email 1`] = `
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`accepts valid email confirmation 1`] = `
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-oneAndAHalf"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
For your added security, we require users to add an email address to their accounts.
|
||||
</p>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
htmlFor="email"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<div
|
||||
className="TextField-root TextField-fullWidth"
|
||||
>
|
||||
<input
|
||||
className="TextField-input TextField-colorRegular"
|
||||
disabled={true}
|
||||
id="email"
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
htmlFor="confirmEmail"
|
||||
>
|
||||
Confirm Email Address
|
||||
</label>
|
||||
<div
|
||||
className="TextField-root TextField-fullWidth"
|
||||
>
|
||||
<input
|
||||
className="TextField-input TextField-colorRegular"
|
||||
disabled={true}
|
||||
id="confirmEmail"
|
||||
name="confirmEmail"
|
||||
onChange={[Function]}
|
||||
placeholder="Confirm Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Add Email Address
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`checks for invalid email 1`] = `
|
||||
<form
|
||||
autoComplete="off"
|
||||
|
||||
@@ -1,63 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`accepts valid username 1`] = `
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-oneAndAHalf"
|
||||
>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Your username is an identifier that will appear on all of your comments.
|
||||
</p>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
htmlFor="username"
|
||||
>
|
||||
Username
|
||||
</label>
|
||||
<p
|
||||
className="Typography-root Typography-detail Typography-colorTextSecondary"
|
||||
>
|
||||
You may use “_” and “.” Spaces not permitted.
|
||||
</p>
|
||||
<div
|
||||
className="TextField-root TextField-fullWidth"
|
||||
>
|
||||
<input
|
||||
className="TextField-input TextField-colorRegular"
|
||||
disabled={true}
|
||||
id="username"
|
||||
name="username"
|
||||
onChange={[Function]}
|
||||
placeholder="Username"
|
||||
type="text"
|
||||
value="hans"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Create Username
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`checks for invalid username 1`] = `
|
||||
<form
|
||||
autoComplete="off"
|
||||
|
||||
@@ -92,20 +92,6 @@ it("accepts valid email", async () => {
|
||||
expect(toJSON(form)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid email confirmation", async () => {
|
||||
const {
|
||||
form,
|
||||
emailAddressField,
|
||||
confirmEmailAddressField,
|
||||
} = await createTestRenderer();
|
||||
emailAddressField.props.onChange({ target: { value: "hans@test.com" } });
|
||||
confirmEmailAddressField.props.onChange({
|
||||
target: { value: "hans@test.com" },
|
||||
});
|
||||
form.props.onSubmit();
|
||||
expect(toJSON(form)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const email = "hans@test.com";
|
||||
const setEmail = sinon.stub().callsFake((_: any, data: any) => {
|
||||
@@ -145,7 +131,7 @@ it("shows server error", async () => {
|
||||
it("successfully sets email", async () => {
|
||||
const email = "hans@test.com";
|
||||
const setEmail = sinon.stub().callsFake((_: any, data: any) => {
|
||||
expect(data.input).toEqual({
|
||||
expectAndFail(data.input).toEqual({
|
||||
email,
|
||||
clientMutationId: data.input.clientMutationId,
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ it("shows server error", async () => {
|
||||
it("successfully sets password", async () => {
|
||||
const password = "secretpassword";
|
||||
const setPassword = sinon.stub().callsFake((_: any, data: any) => {
|
||||
expect(data.input).toEqual({
|
||||
expectAndFail(data.input).toEqual({
|
||||
password,
|
||||
clientMutationId: data.input.clientMutationId,
|
||||
});
|
||||
|
||||
@@ -73,13 +73,6 @@ it("checks for invalid username", async () => {
|
||||
expect(toJSON(form)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid username", async () => {
|
||||
const { form, usernameField } = await createTestRenderer();
|
||||
usernameField.props.onChange({ target: { value: "hans" } });
|
||||
form.props.onSubmit();
|
||||
expect(toJSON(form)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const username = "hans";
|
||||
const setUsername = sinon.stub().callsFake((_: any, data: any) => {
|
||||
@@ -111,7 +104,7 @@ it("shows server error", async () => {
|
||||
it("successfully sets username", async () => {
|
||||
const username = "hans";
|
||||
const setUsername = sinon.stub().callsFake((_: any, data: any) => {
|
||||
expect(data.input).toEqual({
|
||||
expectAndFail(data.input).toEqual({
|
||||
username,
|
||||
clientMutationId: data.input.clientMutationId,
|
||||
});
|
||||
|
||||
@@ -568,8 +568,8 @@ moderation panel.
|
||||
checked={false}
|
||||
className="RadioButton-input"
|
||||
disabled={false}
|
||||
id="autoCloseStream-true"
|
||||
name="autoCloseStream"
|
||||
id="closeCommenting.auto-true"
|
||||
name="closeCommenting.auto"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
@@ -578,7 +578,7 @@ moderation panel.
|
||||
/>
|
||||
<label
|
||||
className="RadioButton-label"
|
||||
htmlFor="autoCloseStream-true"
|
||||
htmlFor="closeCommenting.auto-true"
|
||||
>
|
||||
<span>
|
||||
On
|
||||
@@ -592,8 +592,8 @@ moderation panel.
|
||||
checked={true}
|
||||
className="RadioButton-input"
|
||||
disabled={false}
|
||||
id="autoCloseStream-false"
|
||||
name="autoCloseStream"
|
||||
id="closeCommenting.auto-false"
|
||||
name="closeCommenting.auto"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
@@ -602,7 +602,7 @@ moderation panel.
|
||||
/>
|
||||
<label
|
||||
className="RadioButton-label"
|
||||
htmlFor="autoCloseStream-false"
|
||||
htmlFor="closeCommenting.auto-false"
|
||||
>
|
||||
<span>
|
||||
Off
|
||||
@@ -632,7 +632,7 @@ moderation panel.
|
||||
autoCorrect="off"
|
||||
className="TextField-input TextField-colorRegular TextField-textAlignCenter"
|
||||
disabled={false}
|
||||
name="closedTimeout-value"
|
||||
name="closeCommenting.timeout-value"
|
||||
onChange={[Function]}
|
||||
placeholder=""
|
||||
spellCheck={false}
|
||||
@@ -647,7 +647,7 @@ moderation panel.
|
||||
aria-label="unit"
|
||||
className="SelectField-select DurationField-unit"
|
||||
disabled={false}
|
||||
name="closedTimeout-unit"
|
||||
name="closeCommenting.timeout-unit"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
@@ -703,7 +703,7 @@ moderation panel.
|
||||
>
|
||||
<textarea
|
||||
id="configure-general-closedStreamMessage-content"
|
||||
name="closedMessage"
|
||||
name="closeCommenting.message"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
|
||||
@@ -115,7 +115,7 @@ exports[`renders configure organization 1`] = `
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Header-root"
|
||||
htmlFor="configure-organization-organizationName"
|
||||
htmlFor="configure-organization-organization.name"
|
||||
>
|
||||
Organization Name
|
||||
</label>
|
||||
@@ -133,8 +133,8 @@ exports[`renders configure organization 1`] = `
|
||||
autoCorrect="off"
|
||||
className="TextField-input TextField-colorRegular"
|
||||
disabled={false}
|
||||
id="configure-organization-organizationName"
|
||||
name="organizationName"
|
||||
id="configure-organization-organization.name"
|
||||
name="organization.name"
|
||||
onChange={[Function]}
|
||||
placeholder=""
|
||||
spellCheck={false}
|
||||
@@ -152,7 +152,7 @@ exports[`renders configure organization 1`] = `
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Header-root"
|
||||
htmlFor="configure-organization-organizationContactEmail"
|
||||
htmlFor="configure-organization-organization.contactEmail"
|
||||
>
|
||||
Organization Email
|
||||
</label>
|
||||
@@ -173,8 +173,8 @@ status of their accounts or moderation questions.
|
||||
autoCorrect="off"
|
||||
className="TextField-input TextField-colorRegular"
|
||||
disabled={false}
|
||||
id="configure-organization-organizationContactEmail"
|
||||
name="organizationContactEmail"
|
||||
id="configure-organization-organization.contactEmail"
|
||||
name="organization.contactEmail"
|
||||
onChange={[Function]}
|
||||
placeholder=""
|
||||
spellCheck={false}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mockConsole from "jest-mock-console";
|
||||
import { cloneDeep, get, merge } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -15,16 +14,6 @@ import { settings, users } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
replaceHistoryLocation("http://localhost/admin/configure/advanced");
|
||||
// Test might pass even when it fails with errors in the log due to:
|
||||
// https://github.com/facebook/jest/issues/3917
|
||||
// We check the console to be error free..
|
||||
mockConsole("error");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Check that there are no errors in the console.
|
||||
// tslint:disable-next-line: no-console
|
||||
expect(console.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const createTestRenderer = async (resolver: any = {}) => {
|
||||
@@ -72,7 +61,7 @@ it("change custom css", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.customCSSURL).toEqual("./custom.css");
|
||||
expectAndFail(data.input.settings.customCSSURL).toEqual("./custom.css");
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
@@ -117,7 +106,7 @@ it("change permitted domains to be empty", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.domains).toEqual([]);
|
||||
expectAndFail(data.input.settings.domains).toEqual([]);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
@@ -164,7 +153,7 @@ it("change permitted domains to include more domains", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.domains).toEqual([
|
||||
expectAndFail(data.input.settings.domains).toEqual([
|
||||
"localhost:8080",
|
||||
"localhost:3000",
|
||||
]);
|
||||
|
||||
@@ -112,7 +112,7 @@ it("prevents stream lock out", async () => {
|
||||
Mutation: {
|
||||
updateSettings: createSinonStub(s =>
|
||||
s.callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.auth.integrations.local).toEqual({
|
||||
expectAndFail(data.input.settings.auth.integrations.local).toEqual({
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
targetFilter: {
|
||||
@@ -172,7 +172,7 @@ it("change settings", async () => {
|
||||
Query: {
|
||||
discoverOIDCConfiguration: createSinonStub(s =>
|
||||
s.callsFake((_: any, data: any) => {
|
||||
expect(data).toEqual({ issuer: "http://issuer.com" });
|
||||
expectAndFail(data).toEqual({ issuer: "http://issuer.com" });
|
||||
return {
|
||||
issuer: "http://issuer.com",
|
||||
tokenURL: "http://issuer.com/tokenURL",
|
||||
@@ -186,7 +186,9 @@ it("change settings", async () => {
|
||||
updateSettings: createSinonStub(
|
||||
s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.auth.integrations.facebook).toEqual({
|
||||
expectAndFail(
|
||||
data.input.settings.auth.integrations.facebook
|
||||
).toEqual({
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
targetFilter: {
|
||||
@@ -204,7 +206,7 @@ it("change settings", async () => {
|
||||
}),
|
||||
s =>
|
||||
s.onSecondCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.auth.integrations.oidc).toEqual({
|
||||
expectAndFail(data.input.settings.auth.integrations.oidc).toEqual({
|
||||
enabled: true,
|
||||
allowRegistration: false,
|
||||
targetFilter: {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mockConsole from "jest-mock-console";
|
||||
import { cloneDeep, get, merge } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -17,16 +16,6 @@ import { settings, users } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
replaceHistoryLocation("http://localhost/admin/configure/general");
|
||||
// Test might pass even when it fails with errors in the log due to:
|
||||
// https://github.com/facebook/jest/issues/3917
|
||||
// We check the console to be error free..
|
||||
mockConsole("error");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Check that there are no errors in the console.
|
||||
// tslint:disable-next-line: no-console
|
||||
expect(console.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const createTestRenderer = async (
|
||||
@@ -78,7 +67,7 @@ it("change site wide commenting", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.disableCommenting).toEqual({
|
||||
expectAndFail(data.input.settings.disableCommenting).toEqual({
|
||||
enabled: true,
|
||||
message: "Closing message",
|
||||
});
|
||||
@@ -139,10 +128,12 @@ it("change community guidlines", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.communityGuidelines.content).toEqual(
|
||||
expectAndFail(data.input.settings.communityGuidelines.content).toEqual(
|
||||
"This is the community guidlines summary"
|
||||
);
|
||||
expect(data.input.settings.communityGuidelines.enabled).toEqual(true);
|
||||
expectAndFail(data.input.settings.communityGuidelines.enabled).toEqual(
|
||||
true
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
@@ -198,7 +189,7 @@ it("change closed stream message", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.closedMessage).toEqual(
|
||||
expectAndFail(data.input.settings.closeCommenting.message).toEqual(
|
||||
"The stream has been closed"
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
@@ -243,7 +234,9 @@ it("change comment editing time", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.editCommentWindowLength).toEqual(108000);
|
||||
expectAndFail(data.input.settings.editCommentWindowLength).toEqual(
|
||||
108000
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
@@ -311,7 +304,7 @@ it("change comment length limitations", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.charCount).toEqual({
|
||||
expectAndFail(data.input.settings.charCount).toEqual({
|
||||
enabled: true,
|
||||
min: null,
|
||||
max: 3000,
|
||||
@@ -403,8 +396,10 @@ it("change closing comment streams", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.autoCloseStream).toEqual(true);
|
||||
expect(data.input.settings.closedTimeout).toEqual(2592000);
|
||||
expectAndFail(data.input.settings.closeCommenting.auto).toEqual(true);
|
||||
expectAndFail(data.input.settings.closeCommenting.timeout).toEqual(
|
||||
2592000
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mockConsole from "jest-mock-console";
|
||||
import { cloneDeep, get, merge } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -15,16 +14,6 @@ import { settings, users } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
replaceHistoryLocation("http://localhost/admin/configure/moderation");
|
||||
// Test might pass even when it fails with errors in the log due to:
|
||||
// https://github.com/facebook/jest/issues/3917
|
||||
// We check the console to be error free..
|
||||
mockConsole("error");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Check that there are no errors in the console.
|
||||
// tslint:disable-next-line: no-console
|
||||
expect(console.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const createTestRenderer = async (resolver: any = {}) => {
|
||||
@@ -72,7 +61,7 @@ it("change akismet settings", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.integrations.akismet).toEqual({
|
||||
expectAndFail(data.input.settings.integrations.akismet).toEqual({
|
||||
enabled: true,
|
||||
key: "my api key",
|
||||
site: "https://coralproject.net",
|
||||
@@ -156,7 +145,7 @@ it("change perspective settings", async () => {
|
||||
const updateSettingsStub = createSinonStub(
|
||||
s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.integrations.perspective).toEqual({
|
||||
expectAndFail(data.input.settings.integrations.perspective).toEqual({
|
||||
doNotStore: false,
|
||||
enabled: true,
|
||||
endpoint: "https://custom-endpoint.net",
|
||||
@@ -171,7 +160,7 @@ it("change perspective settings", async () => {
|
||||
}),
|
||||
s =>
|
||||
s.onSecondCall().callsFake((_: any, data: any) => {
|
||||
expect(
|
||||
expectAndFail(
|
||||
data.input.settings.integrations.perspective.threshold
|
||||
).toBeNull();
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mockConsole from "jest-mock-console";
|
||||
import { cloneDeep, get, merge } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -15,16 +14,6 @@ import { settings, users } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
replaceHistoryLocation("http://localhost/admin/configure/organization");
|
||||
// Test might pass even when it fails with errors in the log due to:
|
||||
// https://github.com/facebook/jest/issues/3917
|
||||
// We check the console to be error free..
|
||||
mockConsole("error");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Check that there are no errors in the console.
|
||||
// tslint:disable-next-line: no-console
|
||||
expect(console.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const createTestRenderer = async (resolver: any = {}) => {
|
||||
@@ -72,7 +61,9 @@ it("change organization name", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.organizationName).toEqual("Coral Test");
|
||||
expectAndFail(data.input.settings.organization.name).toEqual(
|
||||
"Coral Test"
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
return {
|
||||
settings: settingsRecord,
|
||||
@@ -135,7 +126,7 @@ it("change organization contact email", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.organizationContactEmail).toEqual(
|
||||
expectAndFail(data.input.settings.organization.contactEmail).toEqual(
|
||||
"test@coralproject.net"
|
||||
);
|
||||
settingsRecord = merge(settingsRecord, data.input.settings);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mockConsole from "jest-mock-console";
|
||||
import { cloneDeep, get, merge } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -15,16 +14,6 @@ import { settings, users } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
replaceHistoryLocation("http://localhost/admin/configure/wordList");
|
||||
// Test might pass even when it fails with errors in the log due to:
|
||||
// https://github.com/facebook/jest/issues/3917
|
||||
// We check the console to be error free..
|
||||
mockConsole("error");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Check that there are no errors in the console.
|
||||
// tslint:disable-next-line: no-console
|
||||
expect(console.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const createTestRenderer = async (resolver: any = {}) => {
|
||||
@@ -72,7 +61,7 @@ it("change banned and suspect words", async () => {
|
||||
let settingsRecord = cloneDeep(settings);
|
||||
const updateSettingsStub = createSinonStub(s =>
|
||||
s.onFirstCall().callsFake((_: any, data: any) => {
|
||||
expect(data.input.settings.wordList).toEqual({
|
||||
expectAndFail(data.input.settings.wordList).toEqual({
|
||||
banned: ["Fuck", "Asshole"],
|
||||
suspect: ["idiot", "shame"],
|
||||
});
|
||||
|
||||
@@ -14,9 +14,10 @@ export const settings = {
|
||||
disableCommenting: {
|
||||
enabled: false,
|
||||
},
|
||||
closedTimeout: 604800,
|
||||
autoCloseStream: false,
|
||||
closedMessage: null,
|
||||
closeCommenting: {
|
||||
auto: false,
|
||||
timeout: 604800,
|
||||
},
|
||||
customCSSURL: null,
|
||||
domains: ["localhost:8080"],
|
||||
editCommentWindowLength: 30000,
|
||||
@@ -24,8 +25,11 @@ export const settings = {
|
||||
enabled: false,
|
||||
content: "",
|
||||
},
|
||||
organizationContactEmail: "coral@test.com",
|
||||
organizationName: "Coral",
|
||||
organization: {
|
||||
name: "Coral",
|
||||
url: "https://test.com/",
|
||||
contactEmail: "coral@test.com",
|
||||
},
|
||||
integrations: {
|
||||
akismet: {
|
||||
enabled: false,
|
||||
|
||||
@@ -83,7 +83,7 @@ describe("reported queue", () => {
|
||||
reported: {
|
||||
count: 2,
|
||||
comments: sinon.stub().callsFake(data => {
|
||||
expect(data).toEqual({ first: 5 });
|
||||
expectAndFail(data).toEqual({ first: 5 });
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -119,7 +119,7 @@ describe("reported queue", () => {
|
||||
comments: createSinonStub(
|
||||
s =>
|
||||
s.onFirstCall().callsFake(data => {
|
||||
expect(data).toEqual({ first: 5 });
|
||||
expectAndFail(data).toEqual({ first: 5 });
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -139,7 +139,7 @@ describe("reported queue", () => {
|
||||
}),
|
||||
s =>
|
||||
s.onSecondCall().callsFake(data => {
|
||||
expect(data).toEqual({
|
||||
expectAndFail(data).toEqual({
|
||||
first: 10,
|
||||
after: reportedComments[1].createdAt,
|
||||
});
|
||||
@@ -195,7 +195,7 @@ describe("reported queue", () => {
|
||||
|
||||
it("accepts comment in reported queue", async () => {
|
||||
const acceptCommentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toMatchObject({
|
||||
expectAndFail(data).toMatchObject({
|
||||
input: {
|
||||
commentID: reportedComments[0].id,
|
||||
commentRevisionID: reportedComments[0].revision.id,
|
||||
@@ -221,7 +221,7 @@ describe("reported queue", () => {
|
||||
reported: {
|
||||
count: 2,
|
||||
comments: sinon.stub().callsFake(data => {
|
||||
expect(data).toEqual({ first: 5 });
|
||||
expectAndFail(data).toEqual({ first: 5 });
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -272,7 +272,7 @@ describe("reported queue", () => {
|
||||
|
||||
it("rejects comment in reported queue", async () => {
|
||||
const rejectCommentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toMatchObject({
|
||||
expectAndFail(data).toMatchObject({
|
||||
input: {
|
||||
commentID: reportedComments[0].id,
|
||||
commentRevisionID: reportedComments[0].revision.id,
|
||||
@@ -298,7 +298,7 @@ describe("reported queue", () => {
|
||||
reported: {
|
||||
count: 2,
|
||||
comments: sinon.stub().callsFake(data => {
|
||||
expect(data).toEqual({ first: 5 });
|
||||
expectAndFail(data).toEqual({ first: 5 });
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -357,7 +357,10 @@ describe("rejected queue", () => {
|
||||
const testRenderer = await createTestRenderer({
|
||||
Query: {
|
||||
comments: sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toEqual({ first: 5, status: "REJECTED" });
|
||||
expectAndFail(data).toEqual({
|
||||
first: 5,
|
||||
status: "REJECTED",
|
||||
});
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -388,7 +391,7 @@ describe("rejected queue", () => {
|
||||
comments: createSinonStub(
|
||||
s =>
|
||||
s.onFirstCall().callsFake((_, data) => {
|
||||
expect(data).toEqual({
|
||||
expectAndFail(data).toEqual({
|
||||
first: 5,
|
||||
status: "REJECTED",
|
||||
});
|
||||
@@ -411,7 +414,7 @@ describe("rejected queue", () => {
|
||||
}),
|
||||
s =>
|
||||
s.onSecondCall().callsFake((_, data) => {
|
||||
expect(data).toEqual({
|
||||
expectAndFail(data).toEqual({
|
||||
first: 10,
|
||||
after: rejectedComments[1].createdAt,
|
||||
status: "REJECTED",
|
||||
@@ -467,7 +470,7 @@ describe("rejected queue", () => {
|
||||
|
||||
it("accepts comment in rejected queue", async () => {
|
||||
const acceptCommentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toMatchObject({
|
||||
expectAndFail(data).toMatchObject({
|
||||
input: {
|
||||
commentID: rejectedComments[0].id,
|
||||
commentRevisionID: rejectedComments[0].revision.id,
|
||||
@@ -490,7 +493,10 @@ describe("rejected queue", () => {
|
||||
const testRenderer = await createTestRenderer({
|
||||
Query: {
|
||||
comments: sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toEqual({ first: 5, status: "REJECTED" });
|
||||
expectAndFail(data).toEqual({
|
||||
first: 5,
|
||||
status: "REJECTED",
|
||||
});
|
||||
return {
|
||||
edges: [
|
||||
{
|
||||
@@ -541,7 +547,7 @@ describe("rejected queue", () => {
|
||||
describe("single comment view", () => {
|
||||
const comment = rejectedComments[0];
|
||||
const commentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toEqual({ id: comment.id });
|
||||
expectAndFail(data).toEqual({ id: comment.id });
|
||||
return reportedComments[0];
|
||||
});
|
||||
|
||||
@@ -566,7 +572,7 @@ describe("single comment view", () => {
|
||||
|
||||
it("accepts single comment", async () => {
|
||||
const acceptCommentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toMatchObject({
|
||||
expectAndFail(data).toMatchObject({
|
||||
input: {
|
||||
commentID: comment.id,
|
||||
commentRevisionID: comment.revision.id,
|
||||
@@ -604,7 +610,7 @@ describe("single comment view", () => {
|
||||
|
||||
it("rejects single comment", async () => {
|
||||
const rejectCommentStub = sinon.stub().callsFake((_, data) => {
|
||||
expect(data).toMatchObject({
|
||||
expectAndFail(data).toMatchObject({
|
||||
input: {
|
||||
commentID: comment.id,
|
||||
commentRevisionID: comment.revision.id,
|
||||
|
||||
Reference in New Issue
Block a user