Merge branch 'next' into next-auth

This commit is contained in:
Wyatt Johnson
2018-10-29 17:39:06 -06:00
121 changed files with 904 additions and 972 deletions
-69
View File
@@ -1,69 +0,0 @@
# Design
## HTTP Routes
### Stream API
/api/tenant/graphql
/api/tenant/auth
### Tenant Management API
/api/management/graphql
/api/management/auth
## Folder structure
```text
/graph/tenant <-- tenant's api (comments, assets, ...)
/graph/management <-- tenant management api
```
1. No tenants
2. Create a tenant <-- consuming the TMA
## Database connections
### Redis Clients
1. Tenant RedisPubSub Subscriber *
2. Tenant RedisPubSub Publisher
3. Queue Subscriber *
4. Queue Publisher
5. Queue Client
6. Queue Blocking Client
## Scripts
### Embed
Embed Script - Renders the iFrame <-- does not have a html page in production (should be on server?)
/dist/static/assets/embed.js /static/embed.js
### Stream
Stream - Renders the comment stream <-- data
/dist/static/assets/stream.<HASH>.css /static/assets/stream.<HASH>.css
/dist/static/assets/stream.<HASH>.js /static/assets/stream.<HASH>.js
/dist/static/stream.html /embed/stream
### Admin
Admin - Renders the Admin page <-- data
/dist/static/assets/admin.<HASH>.css /static/assets/admin.<HASH>.css
/dist/static/assets/admin.<HASH>.js /static/assets/admin.<HASH>.js
/dist/static/admin.html /admin
## Development Routes
localhost:3000
/ -> /admin
/dev <-- server side html for dev/iframe integration
localhost:8080
/ -> localhost:3000/dev
/embed/stream <-- stream html (now is at /)
/admin <-- stream html (now is not there)
+4 -4
View File
@@ -560,14 +560,14 @@ export default function createWebpackConfig({
...htmlWebpackConfig,
}),
new HtmlWebpackPlugin({
filename: "article.html",
template: paths.appEmbedArticleHTML,
filename: "story.html",
template: paths.appEmbedStoryHTML,
inject: "head",
...htmlWebpackConfig,
}),
new HtmlWebpackPlugin({
filename: "articleButton.html",
template: paths.appEmbedArticleButtonHTML,
filename: "storyButton.html",
template: paths.appEmbedStoryButtonHTML,
inject: "head",
...htmlWebpackConfig,
}),
+2 -2
View File
@@ -40,8 +40,8 @@ export default {
appEmbedIndex: resolveSrc("core/client/embed/index.ts"),
appEmbedHTML: resolveSrc("core/client/embed/index.html"),
appEmbedArticleHTML: resolveSrc("core/client/embed/article.html"),
appEmbedArticleButtonHTML: resolveSrc("core/client/embed/articleButton.html"),
appEmbedStoryHTML: resolveSrc("core/client/embed/story.html"),
appEmbedStoryButtonHTML: resolveSrc("core/client/embed/storyButton.html"),
appDistStatic: resolveApp("dist/static"),
appPublic: resolveApp("public"),
+2 -2
View File
@@ -129,8 +129,8 @@ it("should pass correct values to pymControl", () => {
id: "container-id",
rootURL: "http://localhost/",
commentID: "comment-id",
assetID: "asset-id",
assetURL: "asset-url",
storyID: "story-id",
storyURL: "story-url",
};
let pymControlConfig: PymControlConfig | null = null;
const fakeFactory: any = (cfg: PymControlConfig) => {
+4 -4
View File
@@ -24,8 +24,8 @@ import { ensureNoEndSlash } from "./utils";
import urls from "../framework/helpers/urls";
export interface StreamEmbedConfig {
assetID?: string;
assetURL?: string;
storyID?: string;
storyURL?: string;
commentID?: string;
autoRender?: boolean;
title: string;
@@ -112,8 +112,8 @@ export class StreamEmbed {
];
const query = qs.stringify({
assetID: this.config.assetID,
assetURL: this.config.assetURL,
storyID: this.config.storyID,
storyURL: this.config.storyURL,
commentID: this.config.commentID,
});
+6 -6
View File
@@ -4,8 +4,8 @@ import qs from "query-string";
import { default as create, StreamEmbed } from "./StreamEmbed";
export interface Config {
assetID?: string;
assetURL?: string;
storyID?: string;
storyURL?: string;
commentID?: string;
rootURL?: string;
id?: string;
@@ -22,7 +22,7 @@ function getLocationOrigin() {
);
}
function resolveAssetURL() {
function resolveStoryURL() {
const canonical = document.querySelector(
'link[rel="canonical"]'
) as HTMLLinkElement;
@@ -32,7 +32,7 @@ function resolveAssetURL() {
// tslint:disable-next-line:no-console
console.warn(
"This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages."
"This page does not include a canonical link tag. Talk has inferred this story_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages."
);
return getLocationOrigin() + window.location.pathname;
@@ -49,8 +49,8 @@ export function createStreamEmbed(config: Config): StreamEmbed {
return create({
title: "Talk Embed Stream",
assetID: config.assetID || query.assetID,
assetURL: config.assetURL || resolveAssetURL(),
storyID: config.storyID || query.storyID,
storyURL: config.storyURL || resolveStoryURL(),
commentID: config.commentID || query.commentID,
id: config.id || "talk-embed-stream",
rootURL: config.rootURL || getLocationOrigin(),
@@ -4,7 +4,7 @@ exports[`should pass correct values to pymControl 1`] = `
Object {
"id": "container-id",
"title": "StreamEmbed",
"url": "http://localhost/embed/stream?assetID=asset-id&assetURL=asset-url&commentID=comment-id",
"url": "http://localhost/embed/stream?commentID=comment-id&storyID=story-id&storyURL=story-url",
}
`;
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Basic integration test should render iframe 1`] = `"<iframe src=\\"http://localhost/embed/stream?assetURL=http%3A%2F%2Flocalhost%2F&amp;initialWidth=0&amp;childId=basic-integration-test-id&amp;parentTitle=&amp;parentUrl=http%3A%2F%2Flocalhost%2F\\" width=\\"100%\\" scrolling=\\"no\\" marginheight=\\"0\\" frameborder=\\"0\\" title=\\"Talk Embed Stream\\" id=\\"basic-integration-test-id_iframe\\" name=\\"basic-integration-test-id_iframe\\" style=\\"width: 1px; min-width: 100%;\\"></iframe>"`;
exports[`Basic integration test should render iframe 1`] = `"<iframe src=\\"http://localhost/embed/stream?storyURL=http%3A%2F%2Flocalhost%2F&amp;initialWidth=0&amp;childId=basic-integration-test-id&amp;parentTitle=&amp;parentUrl=http%3A%2F%2Flocalhost%2F\\" width=\\"100%\\" scrolling=\\"no\\" marginheight=\\"0\\" frameborder=\\"0\\" title=\\"Talk Embed Stream\\" id=\\"basic-integration-test-id_iframe\\" name=\\"basic-integration-test-id_iframe\\" style=\\"width: 1px; min-width: 100%;\\"></iframe>"`;
exports[`Basic integration test should use canonical link 1`] = `"<iframe src=\\"http://localhost/embed/stream?assetURL=http%3A%2F%2Flocalhost%2Fcanonical&amp;initialWidth=0&amp;childId=basic-integration-test-id&amp;parentTitle=&amp;parentUrl=http%3A%2F%2Flocalhost%2F\\" width=\\"100%\\" scrolling=\\"no\\" marginheight=\\"0\\" frameborder=\\"0\\" title=\\"Talk Embed Stream\\" name=\\"basic-integration-test-id_iframe\\" style=\\"width: 1px; min-width: 100%;\\"></iframe>"`;
exports[`Basic integration test should use canonical link 1`] = `"<iframe src=\\"http://localhost/embed/stream?storyURL=http%3A%2F%2Flocalhost%2Fcanonical&amp;initialWidth=0&amp;childId=basic-integration-test-id&amp;parentTitle=&amp;parentUrl=http%3A%2F%2Flocalhost%2F\\" width=\\"100%\\" scrolling=\\"no\\" marginheight=\\"0\\" frameborder=\\"0\\" title=\\"Talk Embed Stream\\" name=\\"basic-integration-test-id_iframe\\" style=\\"width: 1px; min-width: 100%;\\"></iframe>"`;
+1 -1
View File
@@ -16,7 +16,7 @@
<body>
<p style="text-align: center">
<a href="/article.html">Article</a> | <a href="/articleButton.html">Article With Button</a>
<a href="/story.html">Story</a> | <a href="/storyButton.html">Story With Button</a>
</p>
<h1 style="text-align: center">Talk 5.0 Embed Stream</h1>
<div id="coralStreamEmbed" style="max-width: 640px; margin: 0 auto"></div>
@@ -16,9 +16,9 @@
<body>
<p style="text-align: center">
<a href="/">Default</a> | <a href="/articleButton.html">Article With Button</a>
<a href="/">Default</a> | <a href="/storyButton.html">Story With Button</a>
</p>
<h1 style="text-align: center">Talk 5.0 Article</h1>
<h1 style="text-align: center">Talk 5.0 Story</h1>
<p>Dismember a mouse and then regurgitate parts of it on the family room floor. Dont wait for the storm to pass,
dance in the rain stand in front of the computer screen, so stares at human while pushing stuff off a table chew
the plant meow hiss at vacuum cleaner. Terrorize the hundred-and-twenty-pound rottweiler and steal his bed, not
@@ -16,9 +16,9 @@
<body>
<p style="text-align: center">
<a href="/">Default</a> | <a href="/article.html">Article</a>
<a href="/">Default</a> | <a href="/story.html">Story</a>
</p>
<h1 style="text-align: center">Talk 5.0 Article with Button</h1>
<h1 style="text-align: center">Talk 5.0 Story with Button</h1>
<p>Dismember a mouse and then regurgitate parts of it on the family room floor. Dont wait for the storm to pass,
dance in the rain stand in front of the computer screen, so stares at human while pushing stuff off a table chew
the plant meow hiss at vacuum cleaner. Terrorize the hundred-and-twenty-pound rottweiler and steal his bed, not
@@ -9,10 +9,10 @@ it("should parse hash", () => {
},
],
[
"#commentID=comment-id&assetURL=asset-url",
"#commentID=comment-id&storyURL=story-url",
{
commentID: "comment-id",
assetURL: "asset-url",
storyURL: "story-url",
},
],
["#", {}],
@@ -1,8 +1,8 @@
import { modifyQuery } from "talk-framework/utils";
export default function getURLWithCommentID(
assetURL: string,
storyURL: string,
commentID?: string
) {
return modifyQuery(assetURL, { commentID });
return modifyQuery(storyURL, { commentID });
}
@@ -25,20 +25,20 @@ export function denormalizeComments(commentList: any[]) {
return commentList.map(c => denormalizeComment(c));
}
export function denormalizeAsset(asset: any) {
export function denormalizeStory(story: any) {
const commentNodes =
(asset.comments &&
asset.comments.edges.map((edge: any) => ({
(story.comments &&
story.comments.edges.map((edge: any) => ({
...edge,
node: denormalizeComment(edge.node),
}))) ||
[];
const commentsPageInfo = (asset.comments && asset.comments.pageInfo) || {
const commentsPageInfo = (story.comments && story.comments.pageInfo) || {
endCursor: null,
hasNextPage: false,
};
return {
...asset,
...story,
comments: { edges: commentNodes, pageInfo: commentsPageInfo },
commentCounts: {
totalVisible: commentNodes.length,
@@ -46,6 +46,6 @@ export function denormalizeAsset(asset: any) {
};
}
export function denormalizeAssets(assetList: any[]) {
return assetList.map(a => denormalizeAsset(a));
export function denormalizeStories(storyList: any[]) {
return storyList.map(a => denormalizeStory(a));
}
@@ -9,10 +9,10 @@ it("should parse hash", () => {
},
],
[
"#commentID=comment-id&assetURL=asset-url",
"#commentID=comment-id&storyURL=story-url",
{
commentID: "comment-id",
assetURL: "asset-url",
storyURL: "story-url",
},
],
["#", {}],
@@ -28,20 +28,20 @@ it("init local state", async () => {
expect(JSON.stringify(source.toJSON(), null, 2)).toMatchSnapshot();
});
it("set assetID from query", async () => {
it("set storyID from query", async () => {
const context: Partial<TalkContext> = {
localStorage: createPromisifiedStorage(),
};
const assetID = "asset-id";
const storyID = "story-id";
const previousLocation = location.toString();
const previousState = window.history.state;
window.history.replaceState(
previousState,
document.title,
`http://localhost/?assetID=${assetID}`
`http://localhost/?storyID=${storyID}`
);
await initLocalState(environment, context as any);
expect(source.get(LOCAL_ID)!.assetID).toBe(assetID);
expect(source.get(LOCAL_ID)!.storyID).toBe(storyID);
window.history.replaceState(previousState, document.title, previousLocation);
});
@@ -38,12 +38,12 @@ export default async function initLocalState(
// Parse query params
const query = qs.parse(location.search);
if (query.assetID) {
localRecord.setValue(query.assetID, "assetID");
if (query.storyID) {
localRecord.setValue(query.storyID, "storyID");
}
if (query.assetURL) {
localRecord.setValue(query.assetURL, "assetURL");
if (query.storyURL) {
localRecord.setValue(query.storyURL, "storyURL");
}
if (query.commentID) {
+2 -2
View File
@@ -29,8 +29,8 @@ extend type Comment {
type Local {
network: Network!
assetID: String
assetURL: String
storyID: String
storyURL: String
commentID: String
authPopup: AuthPopup!
authToken: String
@@ -25,7 +25,7 @@ function sharedUpdater(
store: RecordSourceSelectorProxy,
input: CreateCommentInput
) {
updateAsset(store, input);
updateStory(store, input);
if (input.local) {
localUpdate(store, input);
} else {
@@ -34,14 +34,14 @@ function sharedUpdater(
updateProfile(environment, store, input);
}
function updateAsset(
function updateStory(
store: RecordSourceSelectorProxy,
input: CreateCommentInput
) {
// Updating Comment Count
const asset = store.get(input.assetID);
if (asset) {
const record = asset.getLinkedRecord("commentCounts");
const story = store.get(input.storyID);
if (story) {
const record = story.getLinkedRecord("commentCounts");
if (record) {
// TODO: when we have moderation, we'll need to be careful here.
const currentCount = record.getValue("totalVisible");
@@ -63,7 +63,7 @@ function update(store: RecordSourceSelectorProxy, input: CreateCommentInput) {
// Get parent proxy.
const parentProxy = input.parentID
? store.get(input.parentID)
: store.get(input.assetID);
: store.get(input.storyID);
const connectionKey = input.parentID
? "ReplyList_replies"
@@ -171,7 +171,7 @@ function commit(
mutation,
variables: {
input: {
assetID: input.assetID,
storyID: input.storyID,
parentID: input.parentID,
body: input.body,
clientMutationId: clientMutationId.toString(),
@@ -17,13 +17,13 @@ interface InnerProps extends PropTypesOf<typeof Tab> {
class CommentsCountQuery extends Component<InnerProps> {
public render() {
const { assetID, assetURL } = this.props.local;
const { storyID, storyURL } = this.props.local;
const { local: _, ...rest } = this.props;
return (
<QueryRenderer<QueryTypes>
query={graphql`
query CommentsCountQuery($assetID: ID, $assetURL: String) {
asset(id: $assetID, url: $assetURL) {
query CommentsCountQuery($storyID: ID, $storyURL: String) {
story(id: $storyID, url: $storyURL) {
commentCounts {
totalVisible
}
@@ -31,18 +31,18 @@ class CommentsCountQuery extends Component<InnerProps> {
}
`}
variables={{
assetID,
assetURL,
storyID,
storyURL,
}}
render={({ error, props }) => {
if (error) {
return <div>{error.message}</div>;
}
if (props && props.asset) {
if (props && props.story) {
return (
<CommentCountTab
commentCount={props.asset.commentCounts.totalVisible}
commentCount={props.story.commentCounts.totalVisible}
{...rest}
/>
);
@@ -58,8 +58,8 @@ class CommentsCountQuery extends Component<InnerProps> {
const enhanced = withLocalStateContainer(
graphql`
fragment CommentsCountQueryLocal on Local {
assetID
assetURL
storyID
storyURL
}
`
)(CommentsCountQuery);
@@ -14,7 +14,7 @@ describe("with 2 remaining parent comments", () => {
const props: PropTypesOf<typeof ConversationThreadN> = {
className: "root",
me: {},
asset: {},
story: {},
settings: {},
comment: {},
disableLoadMore: false,
@@ -34,7 +34,7 @@ describe("with 2 remaining parent comments", () => {
const props: PropTypesOf<typeof ConversationThreadN> = {
className: "root",
me: {},
asset: {},
story: {},
settings: {},
comment: {},
disableLoadMore: true,
@@ -56,7 +56,7 @@ it("renders with no parent comments", () => {
const props: PropTypesOf<typeof ConversationThreadN> = {
className: "root",
me: {},
asset: {},
story: {},
settings: {},
comment: {},
disableLoadMore: false,
@@ -16,8 +16,8 @@ export interface ConversationThreadProps {
className?: string;
me: PropTypesOf<typeof CommentContainer>["me"] &
(PropTypesOf<typeof LocalReplyListContainer>["me"] | null);
asset: PropTypesOf<typeof CommentContainer>["asset"] &
PropTypesOf<typeof LocalReplyListContainer>["asset"];
story: PropTypesOf<typeof CommentContainer>["story"] &
PropTypesOf<typeof LocalReplyListContainer>["story"];
settings: PropTypesOf<typeof CommentContainer>["settings"] &
PropTypesOf<typeof LocalReplyListContainer>["settings"];
comment: PropTypesOf<typeof CommentContainer>["comment"];
@@ -43,7 +43,7 @@ const ConversationThread: StatelessComponent<
<div className={cn(props.className, styles.root)}>
<CommentContainer
comment={props.comment}
asset={props.asset}
story={props.story}
settings={props.settings}
me={props.me}
highlight
@@ -89,14 +89,14 @@ const ConversationThread: StatelessComponent<
<Circle key={parent.id} hollow={!!props.remaining || i > 0}>
<CommentContainer
comment={parent}
asset={props.asset}
story={props.story}
me={props.me}
settings={props.settings}
localReply
/>
{props.me && (
<LocalReplyListContainer
asset={props.asset}
story={props.story}
me={props.me}
settings={props.settings}
comment={parent}
@@ -108,7 +108,7 @@ const ConversationThread: StatelessComponent<
<Circle end>
<CommentContainer
comment={props.comment}
asset={props.asset}
story={props.story}
settings={props.settings}
me={props.me}
highlight
@@ -12,7 +12,7 @@ const PermalinkViewN = removeFragmentRefs(PermalinkView);
it("renders correctly", () => {
const props: PropTypesOf<typeof PermalinkViewN> = {
me: {},
asset: {},
story: {},
settings: {},
comment: {},
showAllCommentsHref: "http://localhost/link",
@@ -25,7 +25,7 @@ it("renders correctly", () => {
it("renders comment not found", () => {
const props: PropTypesOf<typeof PermalinkViewN> = {
me: {},
asset: {},
story: {},
settings: {},
comment: null,
showAllCommentsHref: "http://localhost/link",
@@ -13,8 +13,8 @@ export interface PermalinkViewProps {
me: PropTypesOf<typeof ConversationThreadContainer>["me"] &
PropTypesOf<typeof ReplyListContainer>["me"] &
PropTypesOf<typeof UserBoxContainer>["me"];
asset: PropTypesOf<typeof ConversationThreadContainer>["asset"] &
PropTypesOf<typeof ReplyListContainer>["asset"];
story: PropTypesOf<typeof ConversationThreadContainer>["story"] &
PropTypesOf<typeof ReplyListContainer>["story"];
comment:
| PropTypesOf<typeof ConversationThreadContainer>["comment"] &
PropTypesOf<typeof ReplyListContainer>["comment"]
@@ -29,7 +29,7 @@ const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
showAllCommentsHref,
comment,
settings,
asset,
story,
onShowAllComments,
me,
}) => {
@@ -71,14 +71,14 @@ const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
<ConversationThreadContainer
me={me}
comment={comment}
asset={asset}
story={story}
settings={settings}
/>
<div className={styles.replyList}>
<ReplyListContainer
me={me}
comment={comment}
asset={asset}
story={story}
settings={settings}
/>
</div>
@@ -12,7 +12,7 @@ const ReplyListN = removeFragmentRefs(ReplyList);
it("renders correctly", () => {
const props: PropTypesOf<typeof ReplyListN> = {
asset: { id: "asset-id" },
story: { id: "story-id" },
comment: { id: "comment-id" },
comments: [
{ id: "comment-1" },
@@ -38,7 +38,7 @@ it("renders correctly", () => {
describe("when there is more", () => {
const props: PropTypesOf<typeof ReplyListN> = {
asset: { id: "asset-id" },
story: { id: "story-id" },
comment: { id: "comment-id" },
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onShowAll: sinon.spy(),
@@ -9,7 +9,7 @@ import CommentContainer from "../containers/CommentContainer";
import Indent from "./Indent";
export interface ReplyListProps {
asset: PropTypesOf<typeof CommentContainer>["asset"];
story: PropTypesOf<typeof CommentContainer>["story"];
me: PropTypesOf<typeof CommentContainer>["me"];
comment: {
id: string;
@@ -42,7 +42,7 @@ const ReplyList: StatelessComponent<ReplyListProps> = props => {
key={comment.id}
me={props.me}
comment={comment}
asset={props.asset}
story={props.story}
settings={props.settings}
indentLevel={props.indentLevel}
localReply={props.localReply}
@@ -12,8 +12,8 @@ const StreamN = removeFragmentRefs(Stream);
it("renders correctly", () => {
const props: PropTypesOf<typeof StreamN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
isClosed: false,
},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
@@ -35,8 +35,8 @@ it("renders correctly", () => {
describe("when use is logged in", () => {
it("renders correctly", () => {
const props: PropTypesOf<typeof StreamN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
isClosed: false,
},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
@@ -58,8 +58,8 @@ describe("when use is logged in", () => {
describe("when there is more", () => {
const props: PropTypesOf<typeof StreamN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
isClosed: false,
},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
@@ -13,11 +13,11 @@ import PostCommentFormFake from "./PostCommentFormFake";
import * as styles from "./Stream.css";
export interface StreamProps {
asset: {
story: {
id: string;
isClosed?: boolean;
} & PropTypesOf<typeof CommentContainer>["asset"] &
PropTypesOf<typeof ReplyListContainer>["asset"];
} & PropTypesOf<typeof CommentContainer>["story"] &
PropTypesOf<typeof ReplyListContainer>["story"];
settings: PropTypesOf<typeof CommentContainer>["settings"] &
PropTypesOf<typeof ReplyListContainer>["settings"];
comments: ReadonlyArray<
@@ -40,7 +40,7 @@ const Stream: StatelessComponent<StreamProps> = props => {
<HorizontalGutter size="half">
<UserBoxContainer me={props.me} />
{props.me ? (
<PostCommentFormContainer assetID={props.asset.id} />
<PostCommentFormContainer storyID={props.story.id} />
) : (
<PostCommentFormFake />
)}
@@ -56,13 +56,13 @@ const Stream: StatelessComponent<StreamProps> = props => {
me={props.me}
settings={props.settings}
comment={comment}
asset={props.asset}
story={props.story}
/>
<ReplyListContainer
settings={props.settings}
me={props.me}
comment={comment}
asset={props.asset}
story={props.story}
/>
</HorizontalGutter>
))}
@@ -5,11 +5,11 @@ exports[`renders with no parent comments 1`] = `
className="root ConversationThread-root"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={Object {}}
comment={Object {}}
highlight={true}
me={Object {}}
settings={Object {}}
story={Object {}}
/>
</div>
`;
@@ -66,11 +66,11 @@ exports[`with 2 remaining parent comments renders correctly 1`] = `
end={true}
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={Object {}}
comment={Object {}}
highlight={true}
me={Object {}}
settings={Object {}}
story={Object {}}
/>
</Circle>
</withPropsOnChange(HorizontalGutter)>
@@ -129,11 +129,11 @@ exports[`with 2 remaining parent comments renders with disabled load more 1`] =
end={true}
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={Object {}}
comment={Object {}}
highlight={true}
me={Object {}}
settings={Object {}}
story={Object {}}
/>
</Circle>
</withPropsOnChange(HorizontalGutter)>
@@ -106,19 +106,19 @@ exports[`renders correctly 1`] = `
</withPropsOnChange(Flex)>
<withPropsOnChange(HorizontalGutter)>
<withContext(withContext(createMutationContainer(Relay(ConversationThreadContainer))))
asset={Object {}}
comment={Object {}}
me={Object {}}
settings={Object {}}
story={Object {}}
/>
<div
className="PermalinkView-replyList"
>
<withProps(Relay(ReplyListContainer))
asset={Object {}}
comment={Object {}}
me={Object {}}
settings={Object {}}
story={Object {}}
/>
</div>
</withPropsOnChange(HorizontalGutter)>
@@ -9,11 +9,6 @@ exports[`renders correctly 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-1",
@@ -33,17 +28,17 @@ exports[`renders correctly 1`] = `
}
}
showConversationLink={false}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-2",
@@ -64,6 +59,11 @@ exports[`renders correctly 1`] = `
}
}
showConversationLink={true}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
</withPropsOnChange(HorizontalGutter)>
@@ -78,11 +78,6 @@ exports[`when there is more disables load more button 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-1",
@@ -100,17 +95,17 @@ exports[`when there is more disables load more button 1`] = `
}
}
showConversationLink={false}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-2",
@@ -128,6 +123,11 @@ exports[`when there is more disables load more button 1`] = `
}
}
showConversationLink={false}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<Indent
@@ -161,11 +161,6 @@ exports[`when there is more renders a load more button 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-1",
@@ -183,17 +178,17 @@ exports[`when there is more renders a load more button 1`] = `
}
}
showConversationLink={false}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-2",
@@ -211,6 +206,11 @@ exports[`when there is more renders a load more button 1`] = `
}
}
showConversationLink={false}
story={
Object {
"id": "story-id",
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<Indent
@@ -22,12 +22,6 @@ exports[`renders correctly 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -42,14 +36,14 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -64,18 +58,18 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -90,14 +84,14 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -112,6 +106,12 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
</withPropsOnChange(HorizontalGutter)>
@@ -140,12 +140,6 @@ exports[`when there is more disables load more button 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -160,14 +154,14 @@ exports[`when there is more disables load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -182,18 +176,18 @@ exports[`when there is more disables load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -208,14 +202,14 @@ exports[`when there is more disables load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -230,6 +224,12 @@ exports[`when there is more disables load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<Localized
@@ -272,12 +272,6 @@ exports[`when there is more renders a load more button 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -292,14 +286,14 @@ exports[`when there is more renders a load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -314,18 +308,18 @@ exports[`when there is more renders a load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -340,14 +334,14 @@ exports[`when there is more renders a load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -362,6 +356,12 @@ exports[`when there is more renders a load more button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<Localized
@@ -394,7 +394,7 @@ exports[`when use is logged in renders correctly 1`] = `
me={Object {}}
/>
<withContext(withContext(createMutationContainer(PostCommentFormContainer)))
assetID="asset-id"
storyID="story-id"
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
@@ -406,12 +406,6 @@ exports[`when use is logged in renders correctly 1`] = `
key="comment-1"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -426,14 +420,14 @@ exports[`when use is logged in renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-1",
@@ -448,18 +442,18 @@ exports[`when use is logged in renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
<withPropsOnChange(HorizontalGutter)
key="comment-2"
>
<withContext(createMutationContainer(withContext(createMutationContainer(Relay(CommentContainer)))))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -474,14 +468,14 @@ exports[`when use is logged in renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
<withProps(Relay(ReplyListContainer))
asset={
Object {
"id": "asset-id",
"isClosed": false,
}
}
comment={
Object {
"id": "comment-2",
@@ -496,6 +490,12 @@ exports[`when use is logged in renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
"isClosed": false,
}
}
/>
</withPropsOnChange(HorizontalGutter)>
</withPropsOnChange(HorizontalGutter)>
@@ -13,8 +13,8 @@ const CommentContainerN = removeFragmentRefs(CommentContainer);
it("renders username and body", () => {
const props: PropTypesOf<typeof CommentContainerN> = {
me: null,
asset: {
url: "http://localhost/asset",
story: {
url: "http://localhost/story",
},
comment: {
id: "comment-id",
@@ -51,8 +51,8 @@ it("renders username and body", () => {
it("renders body only", () => {
const props: PropTypesOf<typeof CommentContainerN> = {
me: null,
asset: {
url: "http://localhost/asset",
story: {
url: "http://localhost/story",
},
comment: {
id: "comment-id",
@@ -87,8 +87,8 @@ it("renders body only", () => {
it("hide reply button", () => {
const props: PropTypesOf<typeof CommentContainerN> = {
me: null,
asset: {
url: "http://localhost/asset",
story: {
url: "http://localhost/story",
},
comment: {
id: "comment-id",
@@ -125,8 +125,8 @@ it("hide reply button", () => {
it("shows conversation link", () => {
const props: PropTypesOf<typeof CommentContainerN> = {
me: null,
asset: {
url: "http://localhost/asset",
story: {
url: "http://localhost/story",
},
settings: {
reaction: {
@@ -165,8 +165,8 @@ it("shows conversation link", () => {
it("renders in reply to", () => {
const props: PropTypesOf<typeof CommentContainerN> = {
me: null,
asset: {
url: "http://localhost/asset",
story: {
url: "http://localhost/story",
},
comment: {
id: "comment-id",
@@ -6,10 +6,10 @@ import { isBeforeDate } from "talk-common/utils";
import { getURLWithCommentID } from "talk-framework/helpers";
import withFragmentContainer from "talk-framework/lib/relay/withFragmentContainer";
import { PropTypesOf } from "talk-framework/types";
import { CommentContainer_asset as AssetData } from "talk-stream/__generated__/CommentContainer_asset.graphql";
import { CommentContainer_comment as CommentData } from "talk-stream/__generated__/CommentContainer_comment.graphql";
import { CommentContainer_me as MeData } from "talk-stream/__generated__/CommentContainer_me.graphql";
import { CommentContainer_settings as SettingsData } from "talk-stream/__generated__/CommentContainer_settings.graphql";
import { CommentContainer_story as StoryData } from "talk-stream/__generated__/CommentContainer_story.graphql";
import {
SetCommentIDMutation,
ShowAuthPopupMutation,
@@ -32,7 +32,7 @@ import ReplyCommentFormContainer from "./ReplyCommentFormContainer";
interface InnerProps {
me: MeData | null;
comment: CommentData;
asset: AssetData;
story: StoryData;
settings: SettingsData;
indentLevel?: number;
showAuthPopup: ShowAuthPopupMutation;
@@ -137,7 +137,7 @@ export class CommentContainer extends Component<InnerProps, State> {
const {
comment,
settings,
asset,
story,
indentLevel,
localReply,
disableReplies,
@@ -196,7 +196,7 @@ export class CommentContainer extends Component<InnerProps, State> {
/>
)}
<PermalinkButtonContainer
asset={asset}
story={story}
commentID={comment.id}
/>
<ReactionButtonContainer
@@ -212,7 +212,7 @@ export class CommentContainer extends Component<InnerProps, State> {
}`}
onClick={this.handleShowConversation}
href={getURLWithCommentID(
this.props.asset.url,
this.props.story.url,
this.props.comment.id
)}
/>
@@ -223,7 +223,7 @@ export class CommentContainer extends Component<InnerProps, State> {
{showReplyDialog && (
<ReplyCommentFormContainer
comment={comment}
asset={asset}
story={story}
onClose={this.closeReplyDialog}
localReply={localReply}
/>
@@ -242,11 +242,11 @@ const enhanced = withSetCommentIDMutation(
...ReactionButtonContainer_me
}
`,
asset: graphql`
fragment CommentContainer_asset on Asset {
story: graphql`
fragment CommentContainer_story on Story {
url
...ReplyCommentFormContainer_asset
...PermalinkButtonContainer_asset
...ReplyCommentFormContainer_story
...PermalinkButtonContainer_story
}
`,
comment: graphql`
@@ -4,10 +4,10 @@ import { graphql, RelayPaginationProp } from "react-relay";
import { withContext } from "talk-framework/lib/bootstrap";
import { withPaginationContainer } from "talk-framework/lib/relay";
import { ConversationThreadContainer_asset as AssetData } from "talk-stream/__generated__/ConversationThreadContainer_asset.graphql";
import { ConversationThreadContainer_comment as CommentData } from "talk-stream/__generated__/ConversationThreadContainer_comment.graphql";
import { ConversationThreadContainer_me as MeData } from "talk-stream/__generated__/ConversationThreadContainer_me.graphql";
import { ConversationThreadContainer_settings as SettingsData } from "talk-stream/__generated__/ConversationThreadContainer_settings.graphql";
import { ConversationThreadContainer_story as StoryData } from "talk-stream/__generated__/ConversationThreadContainer_story.graphql";
import { ConversationThreadContainerPaginationQueryVariables } from "talk-stream/__generated__/ConversationThreadContainerPaginationQuery.graphql";
import {
SetCommentIDMutation,
@@ -18,7 +18,7 @@ import ConversationThread from "../components/ConversationThread";
interface ConversationThreadContainerProps {
comment: CommentData;
asset: AssetData;
story: StoryData;
settings: SettingsData;
me: MeData | null;
setCommentID: SetCommentIDMutation;
@@ -51,12 +51,12 @@ class ConversationThreadContainer extends React.Component<
};
public render() {
const { comment, asset, me, settings } = this.props;
const { comment, story, me, settings } = this.props;
const hasMore = this.props.relay.hasMore();
return (
<ConversationThread
me={me}
asset={asset}
story={story}
comment={comment}
settings={settings}
parents={comment.parents.edges.map(edge => edge.node)}
@@ -95,10 +95,10 @@ const enhanced = withContext(ctx => ({
FragmentVariables
>(
{
asset: graphql`
fragment ConversationThreadContainer_asset on Asset {
...CommentContainer_asset
...LocalReplyListContainer_asset
story: graphql`
fragment ConversationThreadContainer_story on Story {
...CommentContainer_story
...LocalReplyListContainer_story
}
`,
settings: graphql`
@@ -3,17 +3,17 @@ import { graphql } from "react-relay";
import withFragmentContainer from "talk-framework/lib/relay/withFragmentContainer";
import { PropTypesOf } from "talk-framework/types";
import { LocalReplyListContainer_asset as AssetData } from "talk-stream/__generated__/LocalReplyListContainer_asset.graphql";
import { LocalReplyListContainer_comment as CommentData } from "talk-stream/__generated__/LocalReplyListContainer_comment.graphql";
import { LocalReplyListContainer_me as MeData } from "talk-stream/__generated__/LocalReplyListContainer_me.graphql";
import { LocalReplyListContainer_settings as SettingsData } from "talk-stream/__generated__/LocalReplyListContainer_settings.graphql";
import { LocalReplyListContainer_story as StoryData } from "talk-stream/__generated__/LocalReplyListContainer_story.graphql";
import ReplyList from "../components/ReplyList";
interface InnerProps {
indentLevel: number;
me: MeData;
asset: AssetData;
story: StoryData;
comment: CommentData;
settings: SettingsData;
}
@@ -35,7 +35,7 @@ export class LocalReplyListContainer extends Component<InnerProps> {
settings={this.props.settings}
comment={this.props.comment}
comments={this.props.comment.localReplies}
asset={this.props.asset}
story={this.props.story}
indentLevel={this.props.indentLevel}
disableReplies
/>
@@ -49,9 +49,9 @@ const enhanced = withFragmentContainer<InnerProps>({
...CommentContainer_me
}
`,
asset: graphql`
fragment LocalReplyListContainer_asset on Asset {
...CommentContainer_asset
story: graphql`
fragment LocalReplyListContainer_story on Story {
...CommentContainer_story
}
`,
comment: graphql`
@@ -2,30 +2,30 @@ import React, { StatelessComponent } from "react";
import { graphql } from "react-relay";
import { getURLWithCommentID } from "talk-framework/helpers";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { PermalinkButtonContainer_asset as AssetData } from "talk-stream/__generated__/PermalinkButtonContainer_asset.graphql";
import { PermalinkButtonContainer_story as StoryData } from "talk-stream/__generated__/PermalinkButtonContainer_story.graphql";
import PermalinkButton from "../components/PermalinkButton";
interface InnerProps {
asset: AssetData;
story: StoryData;
commentID: string;
}
export const PermalinkButtonContainerProps: StatelessComponent<InnerProps> = ({
asset,
story,
commentID,
}) => {
return (
<PermalinkButton
commentID={commentID}
url={getURLWithCommentID(asset.url, commentID)}
url={getURLWithCommentID(story.url, commentID)}
/>
);
};
const enhanced = withFragmentContainer<InnerProps>({
asset: graphql`
fragment PermalinkButtonContainer_asset on Asset {
story: graphql`
fragment PermalinkButtonContainer_story on Story {
url
}
`,
@@ -5,10 +5,10 @@ import { graphql } from "react-relay";
import { getURLWithCommentID } from "talk-framework/helpers";
import { withContext } from "talk-framework/lib/bootstrap";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { PermalinkViewContainer_asset as AssetData } from "talk-stream/__generated__/PermalinkViewContainer_asset.graphql";
import { PermalinkViewContainer_comment as CommentData } from "talk-stream/__generated__/PermalinkViewContainer_comment.graphql";
import { PermalinkViewContainer_me as MeData } from "talk-stream/__generated__/PermalinkViewContainer_me.graphql";
import { PermalinkViewContainer_settings as SettingsData } from "talk-stream/__generated__/PermalinkViewContainer_settings.graphql";
import { PermalinkViewContainer_story as StoryData } from "talk-stream/__generated__/PermalinkViewContainer_story.graphql";
import {
SetCommentIDMutation,
withSetCommentIDMutation,
@@ -18,7 +18,7 @@ import PermalinkView from "../components/PermalinkView";
interface PermalinkViewContainerProps {
comment: CommentData | null;
asset: AssetData;
story: StoryData;
settings: SettingsData;
me: MeData | null;
setCommentID: SetCommentIDMutation;
@@ -45,11 +45,11 @@ class PermalinkViewContainer extends React.Component<
}
public render() {
const { comment, asset, me, settings } = this.props;
const { comment, story, me, settings } = this.props;
return (
<PermalinkView
me={me}
asset={asset}
story={story}
comment={comment}
settings={settings}
showAllCommentsHref={this.getShowAllCommentsHref()}
@@ -64,10 +64,10 @@ const enhanced = withContext(ctx => ({
}))(
withSetCommentIDMutation(
withFragmentContainer<PermalinkViewContainerProps>({
asset: graphql`
fragment PermalinkViewContainer_asset on Asset {
...ConversationThreadContainer_asset
...ReplyListContainer1_asset
story: graphql`
fragment PermalinkViewContainer_story on Story {
...ConversationThreadContainer_story
...ReplyListContainer1_story
}
`,
comment: graphql`
@@ -14,7 +14,7 @@ it("renders correctly", async () => {
const props: PropTypesOf<typeof PostCommentFormContainer> = {
// tslint:disable-next-line:no-empty
createComment: (() => {}) as any,
assetID: "asset-id",
storyID: "story-id",
sessionStorage: createPromisifiedStorage(),
};
@@ -28,7 +28,7 @@ it("renders with initialValues", async () => {
const props: PropTypesOf<typeof PostCommentFormContainer> = {
// tslint:disable-next-line:no-empty
createComment: (() => {}) as any,
assetID: "asset-id",
storyID: "story-id",
sessionStorage: createPromisifiedStorage(),
};
@@ -44,7 +44,7 @@ it("save values", async () => {
const props: PropTypesOf<typeof PostCommentFormContainer> = {
// tslint:disable-next-line:no-empty
createComment: (() => {}) as any,
assetID: "asset-id",
storyID: "story-id",
sessionStorage: createPromisifiedStorage(),
};
@@ -61,7 +61,7 @@ it("save values", async () => {
});
it("creates a comment", async () => {
const assetID = "asset-id";
const storyID = "story-id";
const input = { body: "Hello World!" };
const createCommentStub = sinon.stub();
const form = { reset: noop };
@@ -74,7 +74,7 @@ it("creates a comment", async () => {
const props: PropTypesOf<typeof PostCommentFormContainer> = {
// tslint:disable-next-line:no-empty
createComment: createCommentStub,
assetID,
storyID,
sessionStorage: createPromisifiedStorage(),
};
@@ -89,7 +89,7 @@ it("creates a comment", async () => {
.onSubmit(input, form);
expect(
createCommentStub.calledWith({
assetID,
storyID,
...input,
})
).toBeTruthy();
@@ -15,7 +15,7 @@ import PostCommentForm, {
interface InnerProps {
createComment: CreateCommentMutation;
assetID: string;
storyID: string;
sessionStorage: PromisifiedStorage;
}
@@ -54,7 +54,7 @@ export class PostCommentFormContainer extends Component<InnerProps, State> {
) => {
try {
await this.props.createComment({
assetID: this.props.assetID,
storyID: this.props.storyID,
...input,
});
form.reset({});
@@ -20,8 +20,8 @@ function getContextKey(commentID: string) {
it("renders correctly", async () => {
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: noop as any,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -42,8 +42,8 @@ it("renders correctly", async () => {
it("renders with initialValues", async () => {
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: noop as any,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -69,8 +69,8 @@ it("renders with initialValues", async () => {
it("save values", async () => {
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: noop as any,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -100,7 +100,7 @@ it("save values", async () => {
});
it("creates a comment", async () => {
const assetID = "asset-id";
const storyID = "story-id";
const input = { body: "Hello World!", local: false };
const createCommentStub = sinon.stub();
const form = { reset: noop };
@@ -108,8 +108,8 @@ it("creates a comment", async () => {
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: createCommentStub,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -136,7 +136,7 @@ it("creates a comment", async () => {
.onSubmit(input, form);
expect(
createCommentStub.calledWith({
assetID,
storyID,
parentID: props.comment.id,
...input,
})
@@ -149,8 +149,8 @@ it("closes on cancel", async () => {
const onCloseStub = sinon.stub();
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: noop as any,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -187,8 +187,8 @@ it("autofocuses", async () => {
const rte = { focus: focusStub };
const props: PropTypesOf<typeof ReplyCommentFormContainerN> = {
createComment: noop as any,
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -7,8 +7,8 @@ import { BadUserInputError } from "talk-framework/lib/errors";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { PromisifiedStorage } from "talk-framework/lib/storage";
import { PropTypesOf } from "talk-framework/types";
import { ReplyCommentFormContainer_asset as AssetData } from "talk-stream/__generated__/ReplyCommentFormContainer_asset.graphql";
import { ReplyCommentFormContainer_comment as CommentData } from "talk-stream/__generated__/ReplyCommentFormContainer_comment.graphql";
import { ReplyCommentFormContainer_story as StoryData } from "talk-stream/__generated__/ReplyCommentFormContainer_story.graphql";
import {
CreateCommentMutation,
withCreateCommentMutation,
@@ -22,7 +22,7 @@ interface InnerProps {
createComment: CreateCommentMutation;
sessionStorage: PromisifiedStorage;
comment: CommentData;
asset: AssetData;
story: StoryData;
onClose?: () => void;
autofocus: boolean;
localReply?: boolean;
@@ -75,7 +75,7 @@ export class ReplyCommentFormContainer extends Component<InnerProps, State> {
) => {
try {
await this.props.createComment({
assetID: this.props.asset.id,
storyID: this.props.story.id,
parentID: this.props.comment.id,
local: this.props.localReply,
...input,
@@ -129,8 +129,8 @@ const enhanced = withContext(({ sessionStorage, browserInfo }) => ({
}))(
withCreateCommentMutation(
withFragmentContainer<InnerProps>({
asset: graphql`
fragment ReplyCommentFormContainer_asset on Asset {
story: graphql`
fragment ReplyCommentFormContainer_story on Story {
id
}
`,
@@ -13,8 +13,8 @@ const ReplyListContainerN = removeFragmentRefs(ReplyListContainer);
it("renders correctly", () => {
const props: PropTypesOf<typeof ReplyListContainerN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -43,8 +43,8 @@ it("renders correctly", () => {
it("renders correctly when replies are empty", () => {
const props: PropTypesOf<typeof ReplyListContainerN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -72,8 +72,8 @@ it("renders correctly when replies are empty", () => {
describe("when has more replies", () => {
let finishLoading: ((error?: Error) => void) | null = null;
const props: PropTypesOf<typeof ReplyListContainerN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
},
comment: {
id: "comment-id",
@@ -4,10 +4,10 @@ import { withProps } from "recompose";
import { withPaginationContainer } from "talk-framework/lib/relay";
import { PropTypesOf } from "talk-framework/types";
import { ReplyListContainer1_asset as AssetData } from "talk-stream/__generated__/ReplyListContainer1_asset.graphql";
import { ReplyListContainer1_comment as CommentData } from "talk-stream/__generated__/ReplyListContainer1_comment.graphql";
import { ReplyListContainer1_me as MeData } from "talk-stream/__generated__/ReplyListContainer1_me.graphql";
import { ReplyListContainer1_settings as SettingsData } from "talk-stream/__generated__/ReplyListContainer1_settings.graphql";
import { ReplyListContainer1_story as StoryData } from "talk-stream/__generated__/ReplyListContainer1_story.graphql";
import {
COMMENT_SORT,
ReplyListContainer1PaginationQueryVariables,
@@ -24,7 +24,7 @@ type ReplyNode5 = UnpackArray<Comment5Data["replies"]["edges"]>["node"];
export interface BaseProps {
me: MeData | null;
asset: AssetData;
story: StoryData;
comment: CommentData;
settings: SettingsData;
relay: RelayPaginationProp;
@@ -62,7 +62,7 @@ export class ReplyListContainer extends React.Component<InnerProps> {
<this.props.ReplyListComponent
me={this.props.me}
comment={edge.node}
asset={this.props.asset}
story={this.props.story}
settings={this.props.settings}
/>
),
@@ -74,7 +74,7 @@ export class ReplyListContainer extends React.Component<InnerProps> {
me={this.props.me}
comment={this.props.comment}
comments={comments}
asset={this.props.asset}
story={this.props.story}
settings={this.props.settings}
onShowAll={this.showAll}
hasMore={this.props.relay.hasMore()}
@@ -108,7 +108,7 @@ function createReplyListContainer(
indentLevel: number,
fragments: {
me: GraphQLTaggedNode;
asset: GraphQLTaggedNode;
story: GraphQLTaggedNode;
comment: GraphQLTaggedNode;
settings: GraphQLTaggedNode;
},
@@ -168,10 +168,10 @@ const ReplyListContainer5 = createReplyListContainer(
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer5_asset on Asset {
...CommentContainer_asset
...LocalReplyListContainer_asset
story: graphql`
fragment ReplyListContainer5_story on Story {
...CommentContainer_story
...LocalReplyListContainer_story
}
`,
comment: graphql`
@@ -230,10 +230,10 @@ const ReplyListContainer4 = createReplyListContainer(
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer4_asset on Asset {
...ReplyListContainer5_asset
...CommentContainer_asset
story: graphql`
fragment ReplyListContainer4_story on Story {
...ReplyListContainer5_story
...CommentContainer_story
}
`,
comment: graphql`
@@ -290,10 +290,10 @@ const ReplyListContainer3 = createReplyListContainer(
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer3_asset on Asset {
...ReplyListContainer4_asset
...CommentContainer_asset
story: graphql`
fragment ReplyListContainer3_story on Story {
...ReplyListContainer4_story
...CommentContainer_story
}
`,
comment: graphql`
@@ -350,10 +350,10 @@ const ReplyListContainer2 = createReplyListContainer(
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer2_asset on Asset {
...ReplyListContainer3_asset
...CommentContainer_asset
story: graphql`
fragment ReplyListContainer2_story on Story {
...ReplyListContainer3_story
...CommentContainer_story
}
`,
comment: graphql`
@@ -410,10 +410,10 @@ const ReplyListContainer1 = createReplyListContainer(
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer1_asset on Asset {
...ReplyListContainer2_asset
...CommentContainer_asset
story: graphql`
fragment ReplyListContainer1_story on Story {
...ReplyListContainer2_story
...CommentContainer_story
}
`,
comment: graphql`
@@ -13,8 +13,8 @@ const StreamContainerN = removeFragmentRefs(StreamContainer);
it("renders correctly", () => {
const props: PropTypesOf<typeof StreamContainerN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
isClosed: false,
comments: {
edges: [{ node: { id: "comment-1" } }, { node: { id: "comment-2" } }],
@@ -39,8 +39,8 @@ it("renders correctly", () => {
describe("when has more comments", () => {
let finishLoading: ((error?: Error) => void) | null = null;
const props: PropTypesOf<typeof StreamContainerN> = {
asset: {
id: "asset-id",
story: {
id: "story-id",
isClosed: false,
comments: {
edges: [{ node: { id: "comment-1" } }, { node: { id: "comment-2" } }],
@@ -3,9 +3,9 @@ import { graphql, RelayPaginationProp } from "react-relay";
import { withPaginationContainer } from "talk-framework/lib/relay";
import { PropTypesOf } from "talk-framework/types";
import { StreamContainer_asset as AssetData } from "talk-stream/__generated__/StreamContainer_asset.graphql";
import { StreamContainer_me as MeData } from "talk-stream/__generated__/StreamContainer_me.graphql";
import { StreamContainer_settings as SettingsData } from "talk-stream/__generated__/StreamContainer_settings.graphql";
import { StreamContainer_story as StoryData } from "talk-stream/__generated__/StreamContainer_story.graphql";
import {
COMMENT_SORT,
StreamContainerPaginationQueryVariables,
@@ -14,7 +14,7 @@ import {
import Stream from "../components/Stream";
interface InnerProps {
asset: AssetData;
story: StoryData;
settings: SettingsData;
me: MeData | null;
relay: RelayPaginationProp;
@@ -35,10 +35,10 @@ export class StreamContainer extends React.Component<InnerProps> {
};
public render() {
const comments = this.props.asset.comments.edges.map(edge => edge.node);
const comments = this.props.story.comments.edges.map(edge => edge.node);
return (
<Stream
asset={this.props.asset}
story={this.props.story}
comments={comments}
settings={this.props.settings}
onLoadMore={this.loadMore}
@@ -80,8 +80,8 @@ const enhanced = withPaginationContainer<
FragmentVariables
>(
{
asset: graphql`
fragment StreamContainer_asset on Asset
story: graphql`
fragment StreamContainer_story on Story
@argumentDefinitions(
count: { type: "Int!", defaultValue: 5 }
cursor: { type: "Cursor" }
@@ -97,8 +97,8 @@ const enhanced = withPaginationContainer<
}
}
}
...CommentContainer_asset
...ReplyListContainer1_asset
...CommentContainer_story
...ReplyListContainer1_story
}
`,
me: graphql`
@@ -118,7 +118,7 @@ const enhanced = withPaginationContainer<
{
direction: "forward",
getConnectionFromProps(props) {
return props.asset && props.asset.comments;
return props.story && props.story.comments;
},
// This is also the default implementation of `getFragmentVariables` if it isn't provided.
getFragmentVariables(prevVars, totalCount) {
@@ -132,9 +132,9 @@ const enhanced = withPaginationContainer<
count,
cursor,
orderBy: fragmentVariables.orderBy,
// assetID isn't specified as an @argument for the fragment, but it should be a
// storyID isn't specified as an @argument for the fragment, but it should be a
// variable available for the fragment under the query root.
assetID: props.asset.id,
storyID: props.story.id,
};
},
query: graphql`
@@ -144,10 +144,10 @@ const enhanced = withPaginationContainer<
$count: Int!
$cursor: Cursor
$orderBy: COMMENT_SORT!
$assetID: ID
$storyID: ID
) {
asset(id: $assetID) {
...StreamContainer_asset
story(id: $storyID) {
...StreamContainer_story
@arguments(count: $count, cursor: $cursor, orderBy: $orderBy)
}
}
@@ -10,12 +10,12 @@ exports[`hide reply button 1`] = `
<React.Fragment>
<ButtonsBar>
<Relay(PermalinkButtonContainerProps)
asset={
commentID="comment-id"
story={
Object {
"url": "http://localhost/asset",
"url": "http://localhost/story",
}
}
commentID="comment-id"
/>
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(Relay(ReactionButtonContainer)))))))
comment={
@@ -72,12 +72,12 @@ exports[`renders body only 1`] = `
onClick={[Function]}
/>
<Relay(PermalinkButtonContainerProps)
asset={
commentID="comment-id"
story={
Object {
"url": "http://localhost/asset",
"url": "http://localhost/story",
}
}
commentID="comment-id"
/>
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(Relay(ReactionButtonContainer)))))))
comment={
@@ -134,12 +134,12 @@ exports[`renders in reply to 1`] = `
onClick={[Function]}
/>
<Relay(PermalinkButtonContainerProps)
asset={
commentID="comment-id"
story={
Object {
"url": "http://localhost/asset",
"url": "http://localhost/story",
}
}
commentID="comment-id"
/>
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(Relay(ReactionButtonContainer)))))))
comment={
@@ -200,12 +200,12 @@ exports[`renders username and body 1`] = `
onClick={[Function]}
/>
<Relay(PermalinkButtonContainerProps)
asset={
commentID="comment-id"
story={
Object {
"url": "http://localhost/asset",
"url": "http://localhost/story",
}
}
commentID="comment-id"
/>
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(Relay(ReactionButtonContainer)))))))
comment={
@@ -262,12 +262,12 @@ exports[`shows conversation link 1`] = `
onClick={[Function]}
/>
<Relay(PermalinkButtonContainerProps)
asset={
commentID="comment-id"
story={
Object {
"url": "http://localhost/asset",
"url": "http://localhost/story",
}
}
commentID="comment-id"
/>
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(Relay(ReactionButtonContainer)))))))
comment={
@@ -300,7 +300,7 @@ exports[`shows conversation link 1`] = `
/>
</ButtonsBar>
<ShowConversationLink
href="http://localhost/asset?commentID=comment-id"
href="http://localhost/story?commentID=comment-id"
id="comments-commentContainer-showConversation-comment-id"
onClick={[Function]}
/>
@@ -2,11 +2,6 @@
exports[`renders correctly 1`] = `
<ReplyList
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-id",
@@ -31,11 +26,6 @@ exports[`renders correctly 1`] = `
Object {
"id": "comment-1",
"replyListElement": <ReplyListComponent
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-1",
@@ -50,17 +40,17 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
}
}
/>,
"showConversationLink": false,
},
Object {
"id": "comment-2",
"replyListElement": <ReplyListComponent
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-2",
@@ -75,6 +65,11 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
}
}
/>,
"showConversationLink": false,
},
@@ -93,6 +88,11 @@ exports[`renders correctly 1`] = `
},
}
}
story={
Object {
"id": "story-id",
}
}
/>
`;
@@ -100,11 +100,6 @@ exports[`renders correctly when replies are empty 1`] = `""`;
exports[`when has more replies renders hasMore 1`] = `
<ReplyList
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-id",
@@ -152,16 +147,16 @@ exports[`when has more replies renders hasMore 1`] = `
},
}
}
story={
Object {
"id": "story-id",
}
}
/>
`;
exports[`when has more replies when showing all disables show all button 1`] = `
<ReplyList
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-id",
@@ -209,16 +204,16 @@ exports[`when has more replies when showing all disables show all button 1`] = `
},
}
}
story={
Object {
"id": "story-id",
}
}
/>
`;
exports[`when has more replies when showing all enable show all button after loading is done 1`] = `
<ReplyList
asset={
Object {
"id": "asset-id",
}
}
comment={
Object {
"id": "comment-id",
@@ -266,5 +261,10 @@ exports[`when has more replies when showing all enable show all button after loa
},
}
}
story={
Object {
"id": "story-id",
}
}
/>
`;
@@ -2,26 +2,6 @@
exports[`renders correctly 1`] = `
<Stream
asset={
Object {
"comments": Object {
"edges": Array [
Object {
"node": Object {
"id": "comment-1",
},
},
Object {
"node": Object {
"id": "comment-2",
},
},
],
},
"id": "asset-id",
"isClosed": false,
}
}
comments={
Array [
Object {
@@ -43,12 +23,7 @@ exports[`renders correctly 1`] = `
},
}
}
/>
`;
exports[`when has more comments renders hasMore 1`] = `
<Stream
asset={
story={
Object {
"comments": Object {
"edges": Array [
@@ -64,10 +39,15 @@ exports[`when has more comments renders hasMore 1`] = `
},
],
},
"id": "asset-id",
"id": "story-id",
"isClosed": false,
}
}
/>
`;
exports[`when has more comments renders hasMore 1`] = `
<Stream
comments={
Array [
Object {
@@ -90,12 +70,7 @@ exports[`when has more comments renders hasMore 1`] = `
},
}
}
/>
`;
exports[`when has more comments when loading more disables load more button 1`] = `
<Stream
asset={
story={
Object {
"comments": Object {
"edges": Array [
@@ -111,10 +86,15 @@ exports[`when has more comments when loading more disables load more button 1`]
},
],
},
"id": "asset-id",
"id": "story-id",
"isClosed": false,
}
}
/>
`;
exports[`when has more comments when loading more disables load more button 1`] = `
<Stream
comments={
Array [
Object {
@@ -137,12 +117,7 @@ exports[`when has more comments when loading more disables load more button 1`]
},
}
}
/>
`;
exports[`when has more comments when loading more enable load more button after loading is done 1`] = `
<Stream
asset={
story={
Object {
"comments": Object {
"edges": Array [
@@ -158,10 +133,15 @@ exports[`when has more comments when loading more enable load more button after
},
],
},
"id": "asset-id",
"id": "story-id",
"isClosed": false,
}
}
/>
`;
exports[`when has more comments when loading more enable load more button after loading is done 1`] = `
<Stream
comments={
Array [
Object {
@@ -184,5 +164,25 @@ exports[`when has more comments when loading more enable load more button after
},
}
}
story={
Object {
"comments": Object {
"edges": Array [
Object {
"node": Object {
"id": "comment-1",
},
},
Object {
"node": Object {
"id": "comment-2",
},
},
],
},
"id": "story-id",
"isClosed": false,
}
}
/>
`;
@@ -6,7 +6,7 @@ import { render } from "./PermalinkViewQuery";
it("renders permalink view container", () => {
const data = {
props: {
asset: {},
story: {},
comment: {},
} as any,
error: null,
@@ -26,10 +26,10 @@ export const render = ({
return <div>{error.message}</div>;
}
if (props) {
if (!props.asset) {
if (!props.story) {
return (
<Localized id="comments-permalinkViewQuery-assetNotFound">
<div>Asset not found</div>
<Localized id="comments-permalinkViewQuery-storyNotFound">
<div>Story not found</div>
</Localized>
);
}
@@ -38,7 +38,7 @@ export const render = ({
me={props.me}
settings={props.settings}
comment={props.comment}
asset={props.asset}
story={props.story}
/>
);
}
@@ -46,20 +46,20 @@ export const render = ({
};
const PermalinkViewQuery: StatelessComponent<InnerProps> = ({
local: { commentID, assetID, assetURL },
local: { commentID, storyID, storyURL },
}) => (
<QueryRenderer<QueryTypes>
query={graphql`
query PermalinkViewQuery(
$commentID: ID!
$assetID: ID
$assetURL: String
$storyID: ID
$storyURL: String
) {
me {
...PermalinkViewContainer_me
}
asset(id: $assetID, url: $assetURL) {
...PermalinkViewContainer_asset
story(id: $storyID, url: $storyURL) {
...PermalinkViewContainer_story
}
comment(id: $commentID) {
...PermalinkViewContainer_comment
@@ -71,8 +71,8 @@ const PermalinkViewQuery: StatelessComponent<InnerProps> = ({
`}
variables={{
commentID: commentID!,
assetID,
assetURL,
storyID,
storyURL,
}}
render={render}
/>
@@ -81,9 +81,9 @@ const PermalinkViewQuery: StatelessComponent<InnerProps> = ({
const enhanced = withLocalStateContainer(
graphql`
fragment PermalinkViewQueryLocal on Local {
assetID
storyID
commentID
assetURL
storyURL
}
`
)(PermalinkViewQuery);
@@ -6,7 +6,7 @@ import { render } from "./StreamQuery";
it("renders stream container", () => {
const data = {
props: {
asset: {},
story: {},
} as any,
error: null,
};
@@ -24,10 +24,10 @@ export const render = ({
}
if (props) {
if (!props.asset) {
if (!props.story) {
return (
<Localized id="comments-streamQuery-assetNotFound">
<div>Asset not found</div>
<Localized id="comments-streamQuery-storyNotFound">
<div>Story not found</div>
</Localized>
);
}
@@ -35,7 +35,7 @@ export const render = ({
<StreamContainer
settings={props.settings}
me={props.me}
asset={props.asset}
story={props.story}
/>
);
}
@@ -44,16 +44,16 @@ export const render = ({
};
const StreamQuery: StatelessComponent<InnerProps> = ({
local: { assetID, assetURL },
local: { storyID, storyURL },
}) => (
<QueryRenderer<QueryTypes>
query={graphql`
query StreamQuery($assetID: ID, $assetURL: String) {
query StreamQuery($storyID: ID, $storyURL: String) {
me {
...StreamContainer_me
}
asset(id: $assetID, url: $assetURL) {
...StreamContainer_asset
story(id: $storyID, url: $storyURL) {
...StreamContainer_story
}
settings {
...StreamContainer_settings
@@ -61,8 +61,8 @@ const StreamQuery: StatelessComponent<InnerProps> = ({
}
`}
variables={{
assetID,
assetURL,
storyID,
storyURL,
}}
render={render}
/>
@@ -71,8 +71,8 @@ const StreamQuery: StatelessComponent<InnerProps> = ({
const enhanced = withLocalStateContainer(
graphql`
fragment StreamQueryLocal on Local {
assetID
assetURL
storyID
storyURL
}
`
)(StreamQuery);
@@ -10,7 +10,7 @@ exports[`renders loading 1`] = `<withPropsOnChange(Spinner) />`;
exports[`renders permalink view container 1`] = `
<withContext(withContext(createMutationContainer(Relay(PermalinkViewContainer))))
asset={Object {}}
comment={Object {}}
story={Object {}}
/>
`;
@@ -10,6 +10,6 @@ exports[`renders loading 1`] = `<withPropsOnChange(Spinner) />`;
exports[`renders stream container 1`] = `
<Relay(StreamContainer)
asset={Object {}}
story={Object {}}
/>
`;
@@ -11,7 +11,7 @@ const CommentHistoryN = removeFragmentRefs(CommentHistory);
it("renders correctly", () => {
const props: PropTypesOf<typeof CommentHistoryN> = {
asset: {},
story: {},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onLoadMore: noop,
hasMore: false,
@@ -24,7 +24,7 @@ it("renders correctly", () => {
describe("has more", () => {
it("renders correctly", () => {
const props: PropTypesOf<typeof CommentHistoryN> = {
asset: {},
story: {},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onLoadMore: noop,
hasMore: true,
@@ -35,7 +35,7 @@ describe("has more", () => {
});
it("disables load more", () => {
const props: PropTypesOf<typeof CommentHistoryN> = {
asset: {},
story: {},
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onLoadMore: noop,
hasMore: true,
@@ -7,7 +7,7 @@ import { Button, HorizontalGutter, Typography } from "talk-ui/components";
import HistoryCommentContainer from "../containers/HistoryCommentContainer";
interface CommentHistoryProps {
asset: PropTypesOf<typeof HistoryCommentContainer>["asset"];
story: PropTypesOf<typeof HistoryCommentContainer>["story"];
comments: Array<
{ id: string } & PropTypesOf<typeof HistoryCommentContainer>["comment"]
>;
@@ -25,7 +25,7 @@ const CommentHistory: StatelessComponent<CommentHistoryProps> = props => {
{props.comments.map(comment => (
<HistoryCommentContainer
key={comment.id}
asset={props.asset}
story={props.story}
comment={comment}
/>
))}
@@ -14,8 +14,8 @@ it("renders correctly", () => {
body: "Hello World",
createdAt: "2018-07-06T18:24:00.000Z",
replyCount: 4,
asset: {
title: "Asset Title",
story: {
title: "Story Title",
},
conversationURL: "http://localhost/conversation",
onGotoConversation: noop,
@@ -17,7 +17,7 @@ export interface HistoryCommentProps {
body: string | null;
createdAt: string;
replyCount: number | null;
asset: {
story: {
title: string | null;
};
conversationURL: string;
@@ -27,7 +27,7 @@ export interface HistoryCommentProps {
const HistoryComment: StatelessComponent<HistoryCommentProps> = props => {
return (
<HorizontalGutter>
<Localized id="profile-historyComment-story" $title={props.asset.title}>
<Localized id="profile-historyComment-story" $title={props.story.title}>
<Typography variant="heading4">{"Story: {$title}"}</Typography>
</Localized>
<Timestamp>{props.createdAt}</Timestamp>
@@ -10,7 +10,7 @@ const ProfileN = removeFragmentRefs(Profile);
it("renders correctly", () => {
const props: PropTypesOf<typeof ProfileN> = {
asset: {},
story: {},
me: {},
};
const wrapper = shallow(<ProfileN {...props} />);
@@ -6,7 +6,7 @@ import { HorizontalGutter } from "talk-ui/components";
import CommentHistoryContainer from "../containers/CommentHistoryContainer";
export interface ProfileProps {
asset: PropTypesOf<typeof CommentHistoryContainer>["asset"];
story: PropTypesOf<typeof CommentHistoryContainer>["story"];
me: PropTypesOf<typeof UserBoxContainer>["me"] &
PropTypesOf<typeof CommentHistoryContainer>["me"];
}
@@ -15,7 +15,7 @@ const Profile: StatelessComponent<ProfileProps> = props => {
return (
<HorizontalGutter size="double">
<UserBoxContainer me={props.me} />
<CommentHistoryContainer me={props.me} asset={props.asset} />
<CommentHistoryContainer me={props.me} story={props.story} />
</HorizontalGutter>
);
};
@@ -14,22 +14,22 @@ exports[`has more disables load more 1`] = `
</withPropsOnChange(Typography)>
</Localized>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-1",
}
}
key="comment-1"
story={Object {}}
/>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-2",
}
}
key="comment-2"
story={Object {}}
/>
<Localized
id="profile-commentHistory-loadMore"
@@ -62,22 +62,22 @@ exports[`has more renders correctly 1`] = `
</withPropsOnChange(Typography)>
</Localized>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-1",
}
}
key="comment-1"
story={Object {}}
/>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-2",
}
}
key="comment-2"
story={Object {}}
/>
<Localized
id="profile-commentHistory-loadMore"
@@ -110,22 +110,22 @@ exports[`renders correctly 1`] = `
</withPropsOnChange(Typography)>
</Localized>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-1",
}
}
key="comment-1"
story={Object {}}
/>
<withContext(createMutationContainer(Relay(HistoryCommentContainer)))
asset={Object {}}
comment={
Object {
"id": "comment-2",
}
}
key="comment-2"
story={Object {}}
/>
</withPropsOnChange(HorizontalGutter)>
`;
@@ -3,7 +3,7 @@
exports[`renders correctly 1`] = `
<withPropsOnChange(HorizontalGutter)>
<Localized
$title="Asset Title"
$title="Story Title"
id="profile-historyComment-story"
>
<withPropsOnChange(Typography)
@@ -8,8 +8,8 @@ exports[`renders correctly 1`] = `
me={Object {}}
/>
<Relay(CommentHistoryContainer)
asset={Object {}}
me={Object {}}
story={Object {}}
/>
</withPropsOnChange(HorizontalGutter)>
`;
@@ -2,15 +2,15 @@ import React from "react";
import { graphql, RelayPaginationProp } from "react-relay";
import { withPaginationContainer } from "talk-framework/lib/relay";
import { CommentHistoryContainer_asset as AssetData } from "talk-stream/__generated__/CommentHistoryContainer_asset.graphql";
import { CommentHistoryContainer_me as MeData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql";
import { CommentHistoryContainer_story as StoryData } from "talk-stream/__generated__/CommentHistoryContainer_story.graphql";
import { CommentHistoryContainerPaginationQueryVariables } from "talk-stream/__generated__/CommentHistoryContainerPaginationQuery.graphql";
import CommentHistory from "../components/CommentHistory";
interface CommentHistoryContainerProps {
me: MeData;
asset: AssetData;
story: StoryData;
relay: RelayPaginationProp;
}
@@ -25,7 +25,7 @@ export class CommentHistoryContainer extends React.Component<
const comments = this.props.me.comments.edges.map(edge => edge.node);
return (
<CommentHistory
asset={this.props.asset}
story={this.props.story}
comments={comments}
onLoadMore={this.loadMore}
hasMore={this.props.relay.hasMore()}
@@ -64,9 +64,9 @@ const enhanced = withPaginationContainer<
FragmentVariables
>(
{
asset: graphql`
fragment CommentHistoryContainer_asset on Asset {
...HistoryCommentContainer_asset
story: graphql`
fragment CommentHistoryContainer_story on Story {
...HistoryCommentContainer_story
}
`,
me: graphql`
@@ -3,8 +3,8 @@ import { graphql } from "react-relay";
import { getURLWithCommentID } from "talk-framework/helpers";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { HistoryCommentContainer_asset as AssetData } from "talk-stream/__generated__/HistoryCommentContainer_asset.graphql";
import { HistoryCommentContainer_comment as CommentData } from "talk-stream/__generated__/HistoryCommentContainer_comment.graphql";
import { HistoryCommentContainer_story as StoryData } from "talk-stream/__generated__/HistoryCommentContainer_story.graphql";
import {
SetCommentIDMutation,
withSetCommentIDMutation,
@@ -13,7 +13,7 @@ import HistoryComment from "../components/HistoryComment";
interface HistoryCommentContainerProps {
setCommentID: SetCommentIDMutation;
asset: AssetData;
story: StoryData;
comment: CommentData;
}
@@ -21,7 +21,7 @@ export class HistoryCommentContainer extends React.Component<
HistoryCommentContainerProps
> {
private handleGoToConversation = (e: React.MouseEvent) => {
if (this.props.asset.id === this.props.comment.asset.id) {
if (this.props.story.id === this.props.comment.story.id) {
this.props.setCommentID({ id: this.props.comment.id });
e.preventDefault();
}
@@ -31,7 +31,7 @@ export class HistoryCommentContainer extends React.Component<
<HistoryComment
{...this.props.comment}
conversationURL={getURLWithCommentID(
this.props.comment.asset.url,
this.props.comment.story.url,
this.props.comment.id
)}
onGotoConversation={this.handleGoToConversation}
@@ -42,8 +42,8 @@ export class HistoryCommentContainer extends React.Component<
const enhanced = withSetCommentIDMutation(
withFragmentContainer<HistoryCommentContainerProps>({
asset: graphql`
fragment HistoryCommentContainer_asset on Asset {
story: graphql`
fragment HistoryCommentContainer_story on Story {
id
}
`,
@@ -53,7 +53,7 @@ const enhanced = withSetCommentIDMutation(
body
createdAt
replyCount
asset {
story {
id
title
url
@@ -2,25 +2,25 @@ import React from "react";
import { graphql } from "react-relay";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { ProfileContainer_asset as AssetData } from "talk-stream/__generated__/ProfileContainer_asset.graphql";
import { ProfileContainer_me as MeData } from "talk-stream/__generated__/ProfileContainer_me.graphql";
import { ProfileContainer_story as StoryData } from "talk-stream/__generated__/ProfileContainer_story.graphql";
import Profile from "../components/Profile";
interface ProfileContainerProps {
me: MeData;
asset: AssetData;
story: StoryData;
}
export class StreamContainer extends React.Component<ProfileContainerProps> {
public render() {
return <Profile me={this.props.me} asset={this.props.asset} />;
return <Profile me={this.props.me} story={this.props.story} />;
}
}
const enhanced = withFragmentContainer<ProfileContainerProps>({
asset: graphql`
fragment ProfileContainer_asset on Asset {
...CommentHistoryContainer_asset
story: graphql`
fragment ProfileContainer_story on Story {
...CommentHistoryContainer_story
}
`,
me: graphql`
@@ -33,27 +33,27 @@ export const render = ({
</Localized>
);
}
if (!props.asset) {
if (!props.story) {
return (
<Localized id="comments-profileQuery-assetNotFound">
<div>Asset not found</div>
<Localized id="comments-profileQuery-storyNotFound">
<div>Story not found</div>
</Localized>
);
}
return <ProfileContainer me={props.me} asset={props.asset} />;
return <ProfileContainer me={props.me} story={props.story} />;
}
return <Spinner />;
};
const ProfileQuery: StatelessComponent<InnerProps> = ({
local: { assetID, assetURL },
local: { storyID, storyURL },
}) => (
<QueryRenderer<QueryTypes>
query={graphql`
query ProfileQuery($assetID: ID, $assetURL: String) {
asset(id: $assetID, url: $assetURL) {
...ProfileContainer_asset
query ProfileQuery($storyID: ID, $storyURL: String) {
story(id: $storyID, url: $storyURL) {
...ProfileContainer_story
}
me {
...ProfileContainer_me
@@ -61,8 +61,8 @@ const ProfileQuery: StatelessComponent<InnerProps> = ({
}
`}
variables={{
assetID,
assetURL,
storyID,
storyURL,
}}
render={render}
/>
@@ -71,8 +71,8 @@ const ProfileQuery: StatelessComponent<InnerProps> = ({
const enhanced = withLocalStateContainer(
graphql`
fragment ProfileQueryLocal on Local {
assetID
assetURL
storyID
storyURL
}
`
)(ProfileQuery);
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders permalink view with unknown asset 1`] = `
exports[`renders permalink view with unknown story 1`] = `
<div
className="HorizontalGutter-root App-root HorizontalGutter-full"
>
@@ -33,7 +33,7 @@ exports[`renders permalink view with unknown asset 1`] = `
role="tabpanel"
>
<div>
Asset not found
Story not found
</div>
</section>
</div>
@@ -1011,7 +1011,7 @@ exports[`post a reply: open reply form 1`] = `
</div>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
href="http://localhost/assets/asset-with-replies?commentID=comment-with-deepest-replies-5"
href="http://localhost/stories/story-with-replies?commentID=comment-with-deepest-replies-5"
id="comments-commentContainer-showConversation-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -2208,7 +2208,7 @@ exports[`post a reply: optimistic response 1`] = `
</div>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
href="http://localhost/assets/asset-with-replies?commentID=comment-with-deepest-replies-5"
href="http://localhost/stories/story-with-replies?commentID=comment-with-deepest-replies-5"
id="comments-commentContainer-showConversation-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -3531,7 +3531,7 @@ exports[`post a reply: server response 1`] = `
</div>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
href="http://localhost/assets/asset-with-replies?commentID=comment-with-deepest-replies-5"
href="http://localhost/stories/story-with-replies?commentID=comment-with-deepest-replies-5"
id="comments-commentContainer-showConversation-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -4694,7 +4694,7 @@ exports[`renders comment stream 1`] = `
</div>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
href="http://localhost/assets/asset-with-replies?commentID=comment-with-deepest-replies-5"
href="http://localhost/stories/story-with-replies?commentID=comment-with-deepest-replies-5"
id="comments-commentContainer-showConversation-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -950,7 +950,7 @@ exports[`renders comment stream 1`] = `
</div>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantUnderlined"
href="http://localhost/assets/asset-with-replies?commentID=comment-with-deepest-replies-5"
href="http://localhost/stories/story-with-replies?commentID=comment-with-deepest-replies-5"
id="comments-commentContainer-showConversation-comment-with-deepest-replies-5"
onBlur={[Function]}
onClick={[Function]}
@@ -4,18 +4,18 @@ import timekeeper from "timekeeper";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, settings, users } from "../fixtures";
import { settings, stories, users } from "../fixtures";
import create from "./create";
function createTestRenderer() {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
me: sinon.stub().returns(users[0]),
settings: sinon.stub().returns(settings),
@@ -27,7 +27,7 @@ function createTestRenderer() {
s
.withArgs(undefined, {
input: {
commentID: assets[0].comments.edges[0].node.id,
commentID: stories[0].comments.edges[0].node.id,
body: "Edited!",
clientMutationId: "0",
},
@@ -35,7 +35,7 @@ function createTestRenderer() {
.returns({
// TODO: add a type assertion here to ensure that if the type changes, that the test will fail
comment: {
id: assets[0].comments.edges[0].node.id,
id: stories[0].comments.edges[0].node.id,
body: "Edited! (from server)",
editing: {
edited: true,
@@ -52,7 +52,7 @@ function createTestRenderer() {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
});
return testRenderer;
@@ -63,7 +63,7 @@ afterAll(() => {
});
it("edit a comment", async () => {
timekeeper.freeze(assets[0].comments.edges[0].node.createdAt);
timekeeper.freeze(stories[0].comments.edges[0].node.createdAt);
const testRenderer = createTestRenderer();
// Wait for loading.
@@ -95,7 +95,7 @@ it("edit a comment", async () => {
});
it("cancel edit", async () => {
timekeeper.freeze(assets[0].comments.edges[0].node.createdAt);
timekeeper.freeze(stories[0].comments.edges[0].node.createdAt);
const testRenderer = createTestRenderer();
await timeout();
@@ -113,7 +113,7 @@ it("cancel edit", async () => {
});
it("shows expiry message", async () => {
timekeeper.freeze(assets[0].comments.edges[0].node.createdAt);
timekeeper.freeze(stories[0].comments.edges[0].node.createdAt);
const testRenderer = createTestRenderer();
await timeout();
@@ -4,13 +4,13 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, settings } from "../fixtures";
import { comments, settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const assetStub = {
...assets[0],
const storyStub = {
...stories[0],
comments: createSinonStub(
s => s.throws(),
s =>
@@ -54,17 +54,17 @@ beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(
undefined,
sinon
.match({ id: assetStub.id, url: null })
.or(sinon.match({ id: assetStub.id }))
.match({ id: storyStub.id, url: null })
.or(sinon.match({ id: storyStub.id }))
)
.returns(assetStub)
.returns(storyStub)
),
settings: sinon.stub().returns(settings),
},
@@ -75,7 +75,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetStub.id, "assetID");
localRecord.setValue(storyStub.id, "storyID");
},
}));
});
@@ -4,7 +4,7 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, commentWithReplies, settings } from "../fixtures";
import { comments, commentWithReplies, settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -29,8 +29,8 @@ beforeEach(() => {
},
};
const assetStub = {
...assets[0],
const storyStub = {
...stories[0],
comments: {
pageInfo: {
hasNextPage: false,
@@ -50,12 +50,12 @@ beforeEach(() => {
s => s.throws(),
s => s.withArgs(undefined, { id: commentStub.id }).returns(commentStub)
),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetStub.id, url: null })
.returns(assetStub)
.withArgs(undefined, { id: storyStub.id, url: null })
.returns(storyStub)
),
settings: sinon.stub().returns(settings),
},
@@ -66,7 +66,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetStub.id, "assetID");
localRecord.setValue(storyStub.id, "storyID");
localRecord.setValue(commentStub.id, "commentID");
},
}));
@@ -4,7 +4,7 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, settings } from "../fixtures";
import { comments, settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -13,8 +13,8 @@ beforeEach(() => {
...comments[0],
};
const assetStub = {
...assets[0],
const storyStub = {
...stories[0],
comments: {
pageInfo: {
hasNextPage: false,
@@ -31,12 +31,12 @@ beforeEach(() => {
const resolvers = {
Query: {
comment: () => null,
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetStub.id, url: null })
.returns(assetStub)
.withArgs(undefined, { id: storyStub.id, url: null })
.returns(storyStub)
),
settings: sinon.stub().returns(settings),
},
@@ -47,7 +47,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetStub.id, "assetID");
localRecord.setValue(storyStub.id, "storyID");
localRecord.setValue("unknown-comment-id", "commentID");
},
}));
@@ -4,7 +4,7 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, settings } from "../fixtures";
import { comments, settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -43,8 +43,8 @@ beforeEach(() => {
),
};
const assetStub = {
...assets[0],
const storyStub = {
...stories[0],
comments: {
pageInfo: {
hasNextPage: false,
@@ -64,12 +64,12 @@ beforeEach(() => {
s => s.throws(),
s => s.withArgs(undefined, { id: commentStub.id }).returns(commentStub)
),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetStub.id, url: null })
.returns(assetStub)
.withArgs(undefined, { id: storyStub.id, url: null })
.returns(storyStub)
),
settings: sinon.stub().returns(settings),
},
@@ -80,7 +80,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetStub.id, "assetID");
localRecord.setValue(storyStub.id, "storyID");
localRecord.setValue(commentStub.id, "commentID");
},
}));
@@ -3,15 +3,15 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { settings } from "../fixtures";
import create from "./create";
import create from "talk-stream/test/comments/create";
import { settings } from "talk-stream/test/fixtures";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const resolvers = {
Query: {
comment: () => null,
asset: () => null,
story: () => null,
settings: sinon.stub().returns(settings),
},
};
@@ -21,13 +21,13 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue("unknown-asset-id", "assetID");
localRecord.setValue("unknown-story-id", "storyID");
localRecord.setValue("unknown-comment-id", "commentID");
},
}));
});
it("renders permalink view with unknown asset", async () => {
it("renders permalink view with unknown story", async () => {
// Wait for loading.
await timeout();
expect(testRenderer.toJSON()).toMatchSnapshot();
@@ -5,7 +5,7 @@ import timekeeper from "timekeeper";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, baseComment, settings, users } from "../fixtures";
import { baseComment, settings, stories, users } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -14,12 +14,12 @@ beforeEach(() => {
Query: {
settings: sinon.stub().returns(settings),
me: sinon.stub().returns(users[0]),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
},
Mutation: {
@@ -29,7 +29,7 @@ beforeEach(() => {
s
.withArgs(undefined, {
input: {
assetID: assets[0].id,
storyID: stories[0].id,
body: "<strong>Hello world!</strong>",
clientMutationId: "0",
},
@@ -56,7 +56,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
@@ -6,9 +6,9 @@ import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import {
assetWithDeepestReplies,
baseComment,
settings,
storyWithDeepestReplies,
users,
} from "../fixtures";
import create from "./create";
@@ -19,12 +19,12 @@ beforeEach(() => {
Query: {
settings: sinon.stub().returns(settings),
me: sinon.stub().returns(users[0]),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetWithDeepestReplies.id, url: null })
.returns(assetWithDeepestReplies)
.withArgs(undefined, { id: storyWithDeepestReplies.id, url: null })
.returns(storyWithDeepestReplies)
),
},
Mutation: {
@@ -34,7 +34,7 @@ beforeEach(() => {
s
.withArgs(undefined, {
input: {
assetID: assetWithDeepestReplies.id,
storyID: storyWithDeepestReplies.id,
parentID: "comment-with-deepest-replies-5",
body: "<strong>Hello world!</strong>",
clientMutationId: "0",
@@ -61,7 +61,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetWithDeepestReplies.id, "assetID");
localRecord.setValue(storyWithDeepestReplies.id, "storyID");
},
}));
});
@@ -5,7 +5,7 @@ import timekeeper from "timekeeper";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, baseComment, settings, users } from "../fixtures";
import { baseComment, settings, stories, users } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -14,12 +14,12 @@ beforeEach(() => {
Query: {
settings: sinon.stub().returns(settings),
me: sinon.stub().returns(users[0]),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
},
Mutation: {
@@ -29,8 +29,8 @@ beforeEach(() => {
s
.withArgs(undefined, {
input: {
assetID: assets[0].id,
parentID: assets[0].comments.edges[0].node.id,
storyID: stories[0].id,
parentID: stories[0].comments.edges[0].node.id,
body: "<strong>Hello world!</strong>",
clientMutationId: "0",
},
@@ -56,7 +56,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
@@ -4,19 +4,19 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assetWithDeepReplies, settings } from "../fixtures";
import { settings, storyWithDeepReplies } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetWithDeepReplies.id, url: null })
.returns(assetWithDeepReplies)
.withArgs(undefined, { id: storyWithDeepReplies.id, url: null })
.returns(storyWithDeepReplies)
),
settings: sinon.stub().returns(settings),
},
@@ -27,7 +27,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetWithDeepReplies.id, "assetID");
localRecord.setValue(storyWithDeepReplies.id, "storyID");
},
}));
});
@@ -4,19 +4,19 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, settings } from "../fixtures";
import { settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
settings: sinon.stub().returns(settings),
},
@@ -27,7 +27,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
@@ -4,7 +4,7 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, settings } from "../fixtures";
import { comments, settings, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -48,8 +48,8 @@ beforeEach(() => {
),
};
const assetStub = {
...assets[0],
const storyStub = {
...stories[0],
comments: {
pageInfo: {
hasNextPage: false,
@@ -70,12 +70,12 @@ beforeEach(() => {
s => s.throws(),
s => s.withArgs(undefined, { id: commentStub.id }).returns(commentStub)
),
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assetStub.id, url: null })
.returns(assetStub)
.withArgs(undefined, { id: storyStub.id, url: null })
.returns(storyStub)
),
},
};
@@ -85,7 +85,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetStub.id, "assetID");
localRecord.setValue(storyStub.id, "storyID");
},
}));
});
@@ -4,16 +4,16 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assetWithDeepestReplies, comments, settings } from "../fixtures";
import { comments, settings, storyWithDeepestReplies } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s => s.returns(assetWithDeepestReplies)
s => s.returns(storyWithDeepestReplies)
),
comment: createSinonStub(
s => s.throws(),
@@ -34,7 +34,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assetWithDeepestReplies.id, "assetID");
localRecord.setValue(storyWithDeepestReplies.id, "storyID");
},
}));
});
+24 -24
View File
@@ -1,8 +1,8 @@
import {
denormalizeAsset,
denormalizeAssets,
denormalizeComment,
denormalizeComments,
denormalizeStories,
denormalizeStory,
} from "talk-framework/testHelpers";
export const settings = {
@@ -214,7 +214,7 @@ export const commentWithDeepestReplies = denormalizeComment({
},
});
export const baseAsset = {
export const baseStory = {
isClosed: false,
comments: {
edges: [],
@@ -227,11 +227,11 @@ export const baseAsset = {
},
};
export const assets = denormalizeAssets([
export const stories = denormalizeStories([
{
...baseAsset,
id: "asset-1",
url: "http://localhost/assets/asset-1",
...baseStory,
id: "story-1",
url: "http://localhost/stories/story-1",
comments: {
edges: [
{ node: comments[0], cursor: comments[0].createdAt },
@@ -243,9 +243,9 @@ export const assets = denormalizeAssets([
},
},
{
...baseAsset,
id: "asset-2",
url: "http://localhost/assets/asset-2",
...baseStory,
id: "story-2",
url: "http://localhost/stories/story-2",
comments: {
edges: [
{ node: comments[2], cursor: comments[2].createdAt },
@@ -258,10 +258,10 @@ export const assets = denormalizeAssets([
},
]);
export const assetWithReplies = denormalizeAsset({
...baseAsset,
id: "asset-with-replies",
url: "http://localhost/assets/asset-with-replies",
export const storyWithReplies = denormalizeStory({
...baseStory,
id: "story-with-replies",
url: "http://localhost/stories/story-with-replies",
comments: {
edges: [
{ node: comments[0], cursor: comments[0].createdAt },
@@ -273,10 +273,10 @@ export const assetWithReplies = denormalizeAsset({
},
});
export const assetWithDeepReplies = denormalizeAsset({
...baseAsset,
id: "asset-with-deep-replies",
url: "http://localhost/assets/asset-with-replies",
export const storyWithDeepReplies = denormalizeStory({
...baseStory,
id: "story-with-deep-replies",
url: "http://localhost/stories/story-with-replies",
comments: {
edges: [
{ node: comments[0], cursor: comments[0].createdAt },
@@ -291,10 +291,10 @@ export const assetWithDeepReplies = denormalizeAsset({
},
});
export const assetWithDeepestReplies = denormalizeAsset({
...baseAsset,
id: "asset-with-deepest-replies",
url: "http://localhost/assets/asset-with-replies",
export const storyWithDeepestReplies = denormalizeStory({
...baseStory,
id: "story-with-deepest-replies",
url: "http://localhost/stories/story-with-replies",
comments: {
edges: [
{
@@ -314,11 +314,11 @@ export const meWithComments = {
comments: {
edges: [
{
node: { ...assets[0].comments.edges[0].node, asset: assets[0] },
node: { ...stories[0].comments.edges[0].node, story: stories[0] },
cursor: comments[0].createdAt,
},
{
node: { ...assets[1].comments.edges[0].node, asset: assets[1] },
node: { ...stories[1].comments.edges[0].node, story: stories[1] },
cursor: comments[1].createdAt,
},
],
@@ -141,7 +141,7 @@ exports[`loads more comments 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-0"
href="http://localhost/stories/story-1?commentID=comment-0"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -196,7 +196,7 @@ exports[`loads more comments 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-1"
href="http://localhost/stories/story-1?commentID=comment-1"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -251,7 +251,7 @@ exports[`loads more comments 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-2"
href="http://localhost/stories/story-1?commentID=comment-2"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -421,7 +421,7 @@ exports[`renders comment stream 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-0"
href="http://localhost/stories/story-1?commentID=comment-0"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -476,7 +476,7 @@ exports[`renders comment stream 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-1"
href="http://localhost/stories/story-1?commentID=comment-1"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -141,7 +141,7 @@ exports[`renders profile 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-1?commentID=comment-0"
href="http://localhost/stories/story-1?commentID=comment-0"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -196,7 +196,7 @@ exports[`renders profile 1`] = `
>
<a
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantUnderlined"
href="http://localhost/assets/asset-2?commentID=comment-2"
href="http://localhost/stories/story-2?commentID=comment-2"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
@@ -4,7 +4,7 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, comments, meWithComments } from "../fixtures";
import { comments, meWithComments, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
@@ -17,11 +17,11 @@ beforeEach(() => {
s.withArgs({ first: 5, orderBy: "CREATED_AT_DESC" }).returns({
edges: [
{
node: { ...comments[0], asset: assets[0] },
node: { ...comments[0], story: stories[0] },
cursor: comments[0].createdAt,
},
{
node: { ...comments[1], asset: assets[0] },
node: { ...comments[1], story: stories[0] },
cursor: comments[1].createdAt,
},
],
@@ -40,7 +40,7 @@ beforeEach(() => {
.returns({
edges: [
{
node: { ...comments[2], asset: assets[0] },
node: { ...comments[2], story: stories[0] },
cursor: comments[2].createdAt,
},
],
@@ -54,12 +54,12 @@ beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
me: sinon.stub().returns(meStub),
},
@@ -70,7 +70,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
@@ -4,19 +4,19 @@ import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { createSinonStub } from "talk-framework/testHelpers";
import { assets, meWithComments } from "../fixtures";
import { meWithComments, stories } from "../fixtures";
import create from "./create";
let testRenderer: ReactTestRenderer;
beforeEach(() => {
const resolvers = {
Query: {
asset: createSinonStub(
story: createSinonStub(
s => s.throws(),
s =>
s
.withArgs(undefined, { id: assets[0].id, url: null })
.returns(assets[0])
.withArgs(undefined, { id: stories[0].id, url: null })
.returns(stories[0])
),
me: sinon.stub().returns(meWithComments),
},
@@ -27,7 +27,7 @@ beforeEach(() => {
logNetwork: false,
resolvers,
initLocalState: localRecord => {
localRecord.setValue(assets[0].id, "assetID");
localRecord.setValue(stories[0].id, "storyID");
},
}));
});
@@ -1,17 +0,0 @@
import DataLoader from "dataloader";
import TenantContext from "talk-server/graph/tenant/context";
import {
Asset,
FindOrCreateAssetInput,
retrieveManyAssets,
} from "talk-server/models/asset";
import { findOrCreate } from "talk-server/services/assets";
export default (ctx: TenantContext) => ({
findOrCreate: (input: FindOrCreateAssetInput) =>
findOrCreate(ctx.mongo, ctx.tenant, input, ctx.queue.scraper),
asset: new DataLoader<string, Asset | null>(ids =>
retrieveManyAssets(ctx.mongo, ctx.tenant.id, ids)
),
});
@@ -2,11 +2,11 @@ import DataLoader from "dataloader";
import Context from "talk-server/graph/tenant/context";
import {
AssetToCommentsArgs,
CommentToParentsArgs,
CommentToRepliesArgs,
GQLActionPresence,
GQLCOMMENT_SORT,
StoryToCommentsArgs,
} from "talk-server/graph/tenant/schema/__generated__/types";
import {
ACTION_ITEM_TYPE,
@@ -14,9 +14,9 @@ import {
} from "talk-server/models/action";
import {
Comment,
retrieveCommentAssetConnection,
retrieveCommentParentsConnection,
retrieveCommentRepliesConnection,
retrieveCommentStoryConnection,
retrieveCommentUserConnection,
retrieveManyComments,
} from "talk-server/models/comment";
@@ -61,29 +61,29 @@ export default (ctx: Context) => ({
first = 10,
orderBy = GQLCOMMENT_SORT.CREATED_AT_DESC,
after,
}: AssetToCommentsArgs
}: StoryToCommentsArgs
) =>
retrieveCommentUserConnection(ctx.mongo, ctx.tenant.id, userID, {
first,
orderBy,
after,
}),
forAsset: (
assetID: string,
forStory: (
storyID: string,
// Apply the graph schema defaults at the loader.
{
first = 10,
orderBy = GQLCOMMENT_SORT.CREATED_AT_DESC,
after,
}: AssetToCommentsArgs
}: StoryToCommentsArgs
) =>
retrieveCommentAssetConnection(ctx.mongo, ctx.tenant.id, assetID, {
retrieveCommentStoryConnection(ctx.mongo, ctx.tenant.id, storyID, {
first,
orderBy,
after,
}).then(primeCommentsFromConnection(ctx)),
forParent: (
assetID: string,
storyID: string,
parentID: string,
// Apply the graph schema defaults at the loader.
{
@@ -95,7 +95,7 @@ export default (ctx: Context) => ({
retrieveCommentRepliesConnection(
ctx.mongo,
ctx.tenant.id,
assetID,
storyID,
parentID,
{
first,
@@ -1,12 +1,13 @@
import Context from "talk-server/graph/tenant/context";
import Assets from "./assets";
import Auth from "./auth";
import Comments from "./comments";
import Stories from "./stories";
import Users from "./users";
export default (ctx: Context) => ({
Auth: Auth(ctx),
Assets: Assets(ctx),
Stories: Stories(ctx),
Comments: Comments(ctx),
Users: Users(ctx),
});
@@ -0,0 +1,17 @@
import DataLoader from "dataloader";
import TenantContext from "talk-server/graph/tenant/context";
import {
FindOrCreateStoryInput,
retrieveManyStories,
Story,
} from "talk-server/models/story";
import { findOrCreate } from "talk-server/services/stories";
export default (ctx: TenantContext) => ({
findOrCreate: (input: FindOrCreateStoryInput) =>
findOrCreate(ctx.mongo, ctx.tenant, input, ctx.queue.scraper),
story: new DataLoader<string, Story | null>(ids =>
retrieveManyStories(ctx.mongo, ctx.tenant.id, ids)
),
});
@@ -27,7 +27,7 @@ export default (ctx: TenantContext) => ({
ctx.user!,
{
author_id: ctx.user!.id,
asset_id: input.assetID,
story_id: input.storyID,
body: input.body,
parent_id: input.parentID,
},
@@ -1,14 +0,0 @@
import { GQLAssetTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
import { decodeActionCounts } from "talk-server/models/action";
import { Asset } from "talk-server/models/asset";
const Asset: GQLAssetTypeResolver<Asset> = {
comments: (asset, input, ctx) =>
ctx.loaders.Comments.forAsset(asset.id, input),
// TODO: implement this.
isClosed: () => false,
actionCounts: asset => decodeActionCounts(asset.action_counts),
commentCounts: asset => asset.comment_counts,
};
export default Asset;
@@ -23,7 +23,7 @@ const Comment: GQLCommentTypeResolver<Comment> = {
ctx.loaders.Users.user.load(comment.author_id),
replies: (comment, input, ctx) =>
comment.reply_count > 0
? ctx.loaders.Comments.forParent(comment.asset_id, comment.id, input)
? ctx.loaders.Comments.forParent(comment.story_id, comment.id, input)
: createConnection(),
actionCounts: comment => decodeActionCounts(comment.action_counts),
myActionPresence: (comment, input, ctx) =>
@@ -84,8 +84,8 @@ const Comment: GQLCommentTypeResolver<Comment> = {
comment.parent_id
? ctx.loaders.Comments.parents(comment, input)
: createConnection(),
asset: (comment, input, ctx) =>
ctx.loaders.Assets.asset.load(comment.asset_id),
story: (comment, input, ctx) =>
ctx.loaders.Stories.story.load(comment.story_id),
};
export default Comment;
@@ -2,7 +2,7 @@ import {
GQLCOMMENT_STATUS,
GQLCommentCountsTypeResolver,
} from "talk-server/graph/tenant/schema/__generated__/types";
import { CommentStatusCounts } from "talk-server/models/asset";
import { CommentStatusCounts } from "talk-server/models/story";
const CommentCounts: GQLCommentCountsTypeResolver<CommentStatusCounts> = {
totalVisible: commentCounts =>
@@ -3,7 +3,6 @@ import Time from "talk-server/graph/common/scalars/time";
import { GQLResolver } from "talk-server/graph/tenant/schema/__generated__/types";
import Asset from "./asset";
import AuthIntegrations from "./auth_integrations";
import Comment from "./comment";
import CommentCounts from "./comment_counts";
@@ -11,10 +10,10 @@ import Mutation from "./mutation";
import OIDCAuthIntegration from "./oidc_auth_integration";
import Profile from "./profile";
import Query from "./query";
import Story from "./story";
import User from "./user";
const Resolvers: GQLResolver = {
Asset,
AuthIntegrations,
Comment,
CommentCounts,
@@ -24,6 +23,7 @@ const Resolvers: GQLResolver = {
Profile,
Query,
Time,
Story,
User,
};
@@ -1,7 +1,7 @@
import { GQLQueryTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
const Query: GQLQueryTypeResolver<void> = {
asset: (source, args, ctx) => ctx.loaders.Assets.findOrCreate(args),
story: (source, args, ctx) => ctx.loaders.Stories.findOrCreate(args),
comment: (source, { id }, ctx) =>
id ? ctx.loaders.Comments.comment.load(id) : null,
settings: (source, args, ctx) => ctx.tenant,
@@ -0,0 +1,14 @@
import { GQLStoryTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
import { decodeActionCounts } from "talk-server/models/action";
import { Story } from "talk-server/models/story";
const Story: GQLStoryTypeResolver<Story> = {
comments: (story, input, ctx) =>
ctx.loaders.Comments.forStory(story.id, input),
// TODO: implement this.
isClosed: () => false,
actionCounts: story => decodeActionCounts(story.action_counts),
commentCounts: story => story.comment_counts,
};
export default Story;

Some files were not shown because too many files have changed in this diff Show More