Skip to content

Commit

Permalink
Merge pull request #4156 from coralproject/develop
Browse files Browse the repository at this point in the history
v7.4.7
  • Loading branch information
tessalt authored Feb 16, 2023
2 parents f160450 + 58b1851 commit 249013a
Show file tree
Hide file tree
Showing 141 changed files with 3,023 additions and 1,544 deletions.
2 changes: 2 additions & 0 deletions docs/docs/cms.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ The URL will be used by Coral to build user facing links, and should reference t

To more tightly couple Coral with your CMS you can provide your CMS's unique identifier to Coral by including a `storyID` parameter in the render function. Doing so will allow you to target the `Story` for later updates via Coral's Graphql API, such as updating the URL if it changes.

Instructions for integrating the API are at https://docs.coralproject.net/api/schema and the mutation to call for URL updates is https://docs.coralproject.net/api/mutations/update-story

## Integration via API

Story creation can also be controlled by direct calls to Coral's API. When Lazy Story Creation is disabled embed streams can only be created by data migration or API POST request.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coralproject/talk",
"version": "7.4.6",
"version": "7.4.7",
"author": "The Coral Project",
"homepage": "https://coralproject.net/",
"sideEffects": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { graphql } from "react-relay";

import { Ability, can } from "coral-admin/permissions";
import { Ability, can } from "coral-admin/permissions/tenant";
import { withFragmentContainer } from "coral-framework/lib/relay";
import {
SignOutMutation,
Expand Down
41 changes: 41 additions & 0 deletions src/core/client/admin/components/BanDomainMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { graphql } from "react-relay";
import { Environment } from "relay-runtime";

import {
commitMutationPromiseNormalized,
createMutation,
MutationInput,
} from "coral-framework/lib/relay";

import { BanDomainMutation } from "coral-admin/__generated__/BanDomainMutation.graphql";
import { GQLNEW_USER_MODERATION } from "coral-framework/schema";

type MutationTypes = Omit<
MutationInput<BanDomainMutation>,
"newUserModeration"
>;
let clientMutationId = 0;

const BanDomainMutation = createMutation(
"banDomain",
(environment: Environment, input: MutationTypes) => {
return commitMutationPromiseNormalized<BanDomainMutation>(environment, {
mutation: graphql`
mutation BanDomainMutation($input: CreateEmailDomainInput!) {
createEmailDomain(input: $input) {
clientMutationId
}
}
`,
variables: {
input: {
domain: input.domain,
newUserModeration: GQLNEW_USER_MODERATION.BAN,
clientMutationId: (clientMutationId++).toString(),
},
},
});
}
);

export default BanDomainMutation;
163 changes: 163 additions & 0 deletions src/core/client/admin/components/BanModal.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { fireEvent, screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import {
createResolversStub,
CreateTestRendererParams,
replaceHistoryLocation,
} from "coral-framework/testHelpers";

import { pureMerge } from "coral-common/utils";
import {
GQLNEW_USER_MODERATION,
GQLResolver,
GQLSettings,
GQLUSER_STATUS,
} from "coral-framework/schema";

import { createContext } from "../test/create";
import customRenderAppWithContext from "../test/customRenderAppWithContext";

import {
communityUsers,
settings,
site,
siteConnection,
users,
} from "../test/fixtures";

const commenter = pureMerge(
{
email: `${users.commenters[0].username!}@test.com`,
},
users.commenters[0]
);

async function createTestRenderer(
params: CreateTestRendererParams<GQLResolver> = {}
) {
const resolvers = createResolversStub<GQLResolver>({
Query: {
users: () => communityUsers,
settings: () => settings,
site: () => site,
viewer: () => users.admins[0],
sites: () => siteConnection,
},
Mutation: {
createEmailDomain: ({ variables }) => {
expectAndFail(variables).toMatchObject({
domain: "test.com",
newUserModeration: GQLNEW_USER_MODERATION.BAN,
});
return {};
},
updateUserBan: ({ variables }) => {
return {};
},
banUser: ({ variables }) => {
expectAndFail(variables).toMatchObject({
userID: commenter.id,
});
const userRecord = pureMerge<typeof commenter>(commenter, {
status: {
current: commenter.status.current.concat(GQLUSER_STATUS.BANNED),
ban: { active: true },
},
});
return {
user: userRecord,
};
},
},
});

const { context } = createContext({
...params,
resolvers: pureMerge(resolvers, params.resolvers),
initLocalState: (localRecord, source, environmenet) => {},
});

customRenderAppWithContext(context);
const container = await screen.findByTestId("community-container");
return { container, resolvers };
}

beforeEach(async () => {
replaceHistoryLocation("http://localhost/admin/community");
});
afterEach(jest.clearAllMocks);

it("creates domain ban for unmoderated domain while updating user ban status", async () => {
const { container, resolvers } = await createTestRenderer();

const userRow = within(container).getByRole("row", {
name: "Isabelle [email protected] 07/06/18, 06:24 PM Commenter Active",
});
userEvent.click(
within(userRow).getByRole("button", { name: "Change user status" })
);

const dropdown = within(userRow).getByLabelText(
"A dropdown to change the user status"
);
fireEvent.click(within(dropdown).getByRole("button", { name: "Manage Ban" }));

const modal = screen.getByLabelText("Are you sure you want to ban Isabelle?");

const banDomainButton = within(modal).getByLabelText(
`Ban all new accounts on test.com`
);
userEvent.click(banDomainButton);
screen.debug(banDomainButton);
userEvent.click(within(modal).getByRole("button", { name: "Ban" }));

await waitFor(() =>
expect(resolvers.Mutation!.createEmailDomain!.called).toBeTruthy()
);

expect(within(userRow).getByText("Banned")).toBeVisible();
expect(resolvers.Mutation!.banUser!.called).toBe(true);
expect(resolvers.Mutation!.createEmailDomain!.called).toBeTruthy();
});

it("does not display ban domain option for moderated domain", async () => {
const moderatedSettings: GQLSettings = {
...settings,
emailDomainModeration: [
{
id: "test-id",
domain: "test.com",
newUserModeration: GQLNEW_USER_MODERATION.BAN,
},
],
};

const moderatedResolvers = createResolversStub<GQLResolver>({
Query: {
settings: () => moderatedSettings,
},
});

const { container } = await createTestRenderer({
resolvers: moderatedResolvers,
});

const userRow = within(container).getByRole("row", {
name: "Isabelle [email protected] 07/06/18, 06:24 PM Commenter Active",
});
userEvent.click(
within(userRow).getByRole("button", { name: "Change user status" })
);

const dropdown = within(userRow).getByLabelText(
"A dropdown to change the user status"
);
fireEvent.click(within(dropdown).getByRole("button", { name: "Manage Ban" }));
const modal = screen.getByLabelText("Are you sure you want to ban Isabelle?");

const banDomainButton = within(modal).queryByText(
`Ban all new accounts on test.com`
);

expect(banDomainButton).not.toBeInTheDocument();
});
Loading

0 comments on commit 249013a

Please sign in to comment.