mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 11:21:01 +08:00
[next] UserBox with respect to auth settings (#2079)
* feat: adapt userbox according to settings in embed stream * fix: lint and test * feat: respect allowRegistration
This commit is contained in:
@@ -6,6 +6,10 @@ enum View {
|
||||
}
|
||||
|
||||
type Local {
|
||||
authToken: String
|
||||
authExp: Int
|
||||
authJTI: String
|
||||
loggedIn: Boolean!
|
||||
view: View!
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,21 @@ import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import UserBoxAuthenticated from "./UserBoxAuthenticated";
|
||||
|
||||
it("renders correctly", () => {
|
||||
it("renders correctly with logout button", () => {
|
||||
const props: PropTypesOf<typeof UserBoxAuthenticated> = {
|
||||
onSignOut: noop,
|
||||
username: "Username",
|
||||
showLogoutButton: true,
|
||||
};
|
||||
const wrapper = shallow(<UserBoxAuthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders correctly without logout button", () => {
|
||||
const props: PropTypesOf<typeof UserBoxAuthenticated> = {
|
||||
onSignOut: noop,
|
||||
username: "Username",
|
||||
showLogoutButton: false,
|
||||
};
|
||||
const wrapper = shallow(<UserBoxAuthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -4,8 +4,9 @@ import React, { StatelessComponent } from "react";
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
|
||||
export interface UserBoxAuthenticatedProps {
|
||||
onSignOut: () => void;
|
||||
onSignOut?: () => void;
|
||||
username: string;
|
||||
showLogoutButton?: boolean;
|
||||
}
|
||||
|
||||
const UserBoxAuthenticated: StatelessComponent<
|
||||
@@ -27,21 +28,23 @@ const UserBoxAuthenticated: StatelessComponent<
|
||||
{"Signed in as <username></username>."}
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="general-userBoxAuthenticated-notYou"
|
||||
button={
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="underlined"
|
||||
onClick={props.onSignOut}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
{"Not you? <button>Sign Out</button>"}
|
||||
</Typography>
|
||||
</Localized>
|
||||
{props.showLogoutButton && (
|
||||
<Localized
|
||||
id="general-userBoxAuthenticated-notYou"
|
||||
button={
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="underlined"
|
||||
onClick={props.onSignOut}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
{"Not you? <button>Sign Out</button>"}
|
||||
</Typography>
|
||||
</Localized>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,17 @@ it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof UserBoxUnauthenticated> = {
|
||||
onSignIn: noop,
|
||||
onRegister: noop,
|
||||
showRegisterButton: true,
|
||||
};
|
||||
const wrapper = shallow(<UserBoxUnauthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders correctly hides showRegisterButton", () => {
|
||||
const props: PropTypesOf<typeof UserBoxUnauthenticated> = {
|
||||
onSignIn: noop,
|
||||
onRegister: noop,
|
||||
showRegisterButton: false,
|
||||
};
|
||||
const wrapper = shallow(<UserBoxUnauthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -8,7 +8,8 @@ import styles from "./UserBoxUnauthenticated.css";
|
||||
|
||||
export interface UserBoxUnauthenticatedProps {
|
||||
onSignIn: () => void;
|
||||
onRegister: () => void;
|
||||
onRegister?: () => void;
|
||||
showRegisterButton?: boolean;
|
||||
}
|
||||
|
||||
const UserBoxUnauthenticated: StatelessComponent<
|
||||
@@ -40,16 +41,18 @@ const UserBoxUnauthenticated: StatelessComponent<
|
||||
Sign in
|
||||
</Button>
|
||||
</Localized>
|
||||
<Localized id="general-userBoxUnauthenticated-register">
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
onClick={props.onRegister}
|
||||
>
|
||||
Register
|
||||
</Button>
|
||||
</Localized>
|
||||
{props.showRegisterButton && (
|
||||
<Localized id="general-userBoxUnauthenticated-register">
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
onClick={props.onRegister}
|
||||
>
|
||||
Register
|
||||
</Button>
|
||||
</Localized>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
exports[`renders correctly with logout button 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
itemGutter="half"
|
||||
wrap={true}
|
||||
@@ -36,3 +36,22 @@ exports[`renders correctly 1`] = `
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
`;
|
||||
|
||||
exports[`renders correctly without logout button 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
itemGutter="half"
|
||||
wrap={true}
|
||||
>
|
||||
<Localized
|
||||
id="general-userBoxAuthenticated-signedInAs"
|
||||
username={<Username />}
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
container="div"
|
||||
variant="bodyCopy"
|
||||
>
|
||||
Signed in as <username></username>.
|
||||
</withPropsOnChange(Typography)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
`;
|
||||
|
||||
@@ -52,3 +52,44 @@ exports[`renders correctly 1`] = `
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
`;
|
||||
|
||||
exports[`renders correctly hides showRegisterButton 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
alignItems="center"
|
||||
itemGutter={true}
|
||||
>
|
||||
<MatchMediaWithContext
|
||||
gteWidth="sm"
|
||||
>
|
||||
<Localized
|
||||
id="general-userBoxUnauthenticated-joinTheConversation"
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
className="UserBoxUnauthenticated-joinText"
|
||||
container="span"
|
||||
variant="bodyCopyBold"
|
||||
>
|
||||
Join the conversation
|
||||
</withPropsOnChange(Typography)>
|
||||
</Localized>
|
||||
<withPropsOnChange(Typography)
|
||||
container="span"
|
||||
variant="bodyCopyBold"
|
||||
>
|
||||
|
|
||||
</withPropsOnChange(Typography)>
|
||||
</MatchMediaWithContext>
|
||||
<Localized
|
||||
id="general-userBoxUnauthenticated-signIn"
|
||||
>
|
||||
<withPropsOnChange(Button)
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
size="small"
|
||||
variant="underlined"
|
||||
>
|
||||
Sign in
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
`;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { UserBoxContainer } from "./UserBoxContainer";
|
||||
// Remove relay refs so we can stub the props.
|
||||
const UserBoxContainerN = removeFragmentRefs(UserBoxContainer);
|
||||
|
||||
it("renders correctly", () => {
|
||||
it("renders fully", () => {
|
||||
const props: PropTypesOf<typeof UserBoxContainerN> = {
|
||||
local: {
|
||||
authPopup: {
|
||||
@@ -17,8 +17,212 @@ it("renders correctly", () => {
|
||||
focus: false,
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
authJTI: "JTI",
|
||||
},
|
||||
me: null,
|
||||
settings: {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainerN {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders without logout button", () => {
|
||||
const props: PropTypesOf<typeof UserBoxContainerN> = {
|
||||
local: {
|
||||
authPopup: {
|
||||
open: false,
|
||||
focus: false,
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
authJTI: null,
|
||||
},
|
||||
me: null,
|
||||
settings: {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainerN {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders sso only", () => {
|
||||
const props: PropTypesOf<typeof UserBoxContainerN> = {
|
||||
local: {
|
||||
authPopup: {
|
||||
open: false,
|
||||
focus: false,
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
authJTI: "JTI",
|
||||
},
|
||||
me: null,
|
||||
settings: {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainerN {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders sso only without logut button", () => {
|
||||
const props: PropTypesOf<typeof UserBoxContainerN> = {
|
||||
local: {
|
||||
authPopup: {
|
||||
open: false,
|
||||
focus: false,
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
authJTI: "JTI",
|
||||
},
|
||||
me: null,
|
||||
settings: {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainerN {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders without register button", () => {
|
||||
const props: PropTypesOf<typeof UserBoxContainerN> = {
|
||||
local: {
|
||||
authPopup: {
|
||||
open: false,
|
||||
focus: false,
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
authJTI: "JTI",
|
||||
},
|
||||
me: null,
|
||||
settings: {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: true,
|
||||
allowRegistration: false,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: false,
|
||||
},
|
||||
sso: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: true,
|
||||
allowRegistration: false,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "talk-framework/lib/relay";
|
||||
import { SignOutMutation, withSignOutMutation } from "talk-framework/mutations";
|
||||
import { UserBoxContainer_me as MeData } from "talk-stream/__generated__/UserBoxContainer_me.graphql";
|
||||
import { UserBoxContainer_settings as SettingsData } from "talk-stream/__generated__/UserBoxContainer_settings.graphql";
|
||||
import { UserBoxContainerLocal as Local } from "talk-stream/__generated__/UserBoxContainerLocal.graphql";
|
||||
import UserBoxUnauthenticated from "talk-stream/components/UserBoxUnauthenticated";
|
||||
import {
|
||||
@@ -24,6 +25,7 @@ import UserBoxAuthenticated from "../components/UserBoxAuthenticated";
|
||||
interface InnerProps {
|
||||
local: Local;
|
||||
me: MeData | null;
|
||||
settings: SettingsData;
|
||||
showAuthPopup: ShowAuthPopupMutation;
|
||||
setAuthPopupState: SetAuthPopupStateMutation;
|
||||
signOut: SignOutMutation;
|
||||
@@ -37,6 +39,31 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
private handleRegister = () => this.props.showAuthPopup({ view: "SIGN_UP" });
|
||||
private handleSignOut = () => this.props.signOut();
|
||||
|
||||
private get supportsLogout() {
|
||||
return !!this.props.local.authJTI;
|
||||
}
|
||||
|
||||
private get supportsRegister() {
|
||||
const integrations = this.props.settings.auth.integrations;
|
||||
return (
|
||||
(integrations.facebook.allowRegistration &&
|
||||
integrations.facebook.enabled) ||
|
||||
(integrations.google.allowRegistration && integrations.google.enabled) ||
|
||||
(integrations.local.allowRegistration && integrations.local.enabled) ||
|
||||
integrations.oidc.some(c => c.allowRegistration && c.enabled)
|
||||
);
|
||||
}
|
||||
|
||||
private get weControlAuth() {
|
||||
const integrations = this.props.settings.auth.integrations;
|
||||
return (
|
||||
integrations.facebook.enabled ||
|
||||
integrations.google.enabled ||
|
||||
integrations.local.enabled ||
|
||||
integrations.oidc.some(c => c.enabled)
|
||||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {
|
||||
local: {
|
||||
@@ -48,13 +75,17 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
if (me) {
|
||||
return (
|
||||
<UserBoxAuthenticated
|
||||
onSignOut={this.handleSignOut}
|
||||
// TODO: why nullable?
|
||||
onSignOut={(this.weControlAuth && this.handleSignOut) || undefined}
|
||||
username={me.username!}
|
||||
showLogoutButton={this.supportsLogout}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.weControlAuth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popup
|
||||
@@ -69,7 +100,10 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
/>
|
||||
<UserBoxUnauthenticated
|
||||
onSignIn={this.handleSignIn}
|
||||
onRegister={this.handleRegister}
|
||||
onRegister={
|
||||
(this.supportsRegister && this.handleRegister) || undefined
|
||||
}
|
||||
showRegisterButton={this.supportsRegister}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -87,6 +121,7 @@ const enhanced = withSignOutMutation(
|
||||
focus
|
||||
view
|
||||
}
|
||||
authJTI
|
||||
}
|
||||
`
|
||||
)(
|
||||
@@ -96,6 +131,34 @@ const enhanced = withSignOutMutation(
|
||||
username
|
||||
}
|
||||
`,
|
||||
settings: graphql`
|
||||
fragment UserBoxContainer_settings on Settings {
|
||||
auth {
|
||||
integrations {
|
||||
local {
|
||||
enabled
|
||||
allowRegistration
|
||||
}
|
||||
sso {
|
||||
enabled
|
||||
allowRegistration
|
||||
}
|
||||
oidc {
|
||||
enabled
|
||||
allowRegistration
|
||||
}
|
||||
google {
|
||||
enabled
|
||||
allowRegistration
|
||||
}
|
||||
facebook {
|
||||
enabled
|
||||
allowRegistration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})(UserBoxContainer)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
exports[`renders fully 1`] = `
|
||||
<Fragment>
|
||||
<Popup
|
||||
features="menubar=0,resizable=0,width=350,height=395,top=200,left=500"
|
||||
@@ -15,6 +15,50 @@ exports[`renders correctly 1`] = `
|
||||
<UserBoxUnauthenticated
|
||||
onRegister={[Function]}
|
||||
onSignIn={[Function]}
|
||||
showRegisterButton={true}
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`renders sso only 1`] = `""`;
|
||||
|
||||
exports[`renders sso only without logut button 1`] = `""`;
|
||||
|
||||
exports[`renders without logout button 1`] = `
|
||||
<Fragment>
|
||||
<Popup
|
||||
features="menubar=0,resizable=0,width=350,height=395,top=200,left=500"
|
||||
focus={false}
|
||||
href="/embed/auth?view=SIGN_IN"
|
||||
onBlur={[Function]}
|
||||
onClose={[Function]}
|
||||
onFocus={[Function]}
|
||||
open={false}
|
||||
title="Talk Auth"
|
||||
/>
|
||||
<UserBoxUnauthenticated
|
||||
onRegister={[Function]}
|
||||
onSignIn={[Function]}
|
||||
showRegisterButton={true}
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`renders without register button 1`] = `
|
||||
<Fragment>
|
||||
<Popup
|
||||
features="menubar=0,resizable=0,width=350,height=395,top=200,left=500"
|
||||
focus={false}
|
||||
href="/embed/auth?view=SIGN_IN"
|
||||
onBlur={[Function]}
|
||||
onClose={[Function]}
|
||||
onFocus={[Function]}
|
||||
open={false}
|
||||
title="Talk Auth"
|
||||
/>
|
||||
<UserBoxUnauthenticated
|
||||
onSignIn={[Function]}
|
||||
showRegisterButton={false}
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -20,7 +20,8 @@ export interface PermalinkViewProps {
|
||||
PropTypesOf<typeof ReplyListContainer>["comment"]
|
||||
| null;
|
||||
settings: PropTypesOf<typeof ConversationThreadContainer>["settings"] &
|
||||
PropTypesOf<typeof ReplyListContainer>["settings"];
|
||||
PropTypesOf<typeof ReplyListContainer>["settings"] &
|
||||
PropTypesOf<typeof UserBoxContainer>["settings"];
|
||||
showAllCommentsHref: string | null;
|
||||
onShowAllComments: (e: MouseEvent<any>) => void;
|
||||
}
|
||||
@@ -35,7 +36,7 @@ const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<HorizontalGutter className={styles.root} size="double">
|
||||
<UserBoxContainer me={me} />
|
||||
<UserBoxContainer me={me} settings={settings} />
|
||||
<Flex alignItems="center" justifyContent="center" direction="column">
|
||||
<Localized id="comments-permalinkView-currentViewing">
|
||||
<Typography className={styles.title1}>
|
||||
|
||||
@@ -19,7 +19,8 @@ export interface StreamProps {
|
||||
} & PropTypesOf<typeof CommentContainer>["story"] &
|
||||
PropTypesOf<typeof ReplyListContainer>["story"];
|
||||
settings: PropTypesOf<typeof CommentContainer>["settings"] &
|
||||
PropTypesOf<typeof ReplyListContainer>["settings"];
|
||||
PropTypesOf<typeof ReplyListContainer>["settings"] &
|
||||
PropTypesOf<typeof UserBoxContainer>["settings"];
|
||||
comments: ReadonlyArray<
|
||||
{ id: string } & PropTypesOf<typeof CommentContainer>["comment"] &
|
||||
PropTypesOf<typeof ReplyListContainer>["comment"]
|
||||
@@ -38,7 +39,7 @@ const Stream: StatelessComponent<StreamProps> = props => {
|
||||
return (
|
||||
<HorizontalGutter className={styles.root} size="double">
|
||||
<HorizontalGutter size="half">
|
||||
<UserBoxContainer me={props.me} />
|
||||
<UserBoxContainer me={props.me} settings={props.settings} />
|
||||
{props.me ? (
|
||||
<PostCommentFormContainer storyID={props.story.id} />
|
||||
) : (
|
||||
|
||||
+2
@@ -7,6 +7,7 @@ exports[`renders comment not found 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={Object {}}
|
||||
settings={Object {}}
|
||||
/>
|
||||
<withPropsOnChange(Flex)
|
||||
alignItems="center"
|
||||
@@ -64,6 +65,7 @@ exports[`renders correctly 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={Object {}}
|
||||
settings={Object {}}
|
||||
/>
|
||||
<withPropsOnChange(Flex)
|
||||
alignItems="center"
|
||||
|
||||
@@ -10,6 +10,14 @@ exports[`renders correctly 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={null}
|
||||
settings={
|
||||
Object {
|
||||
"reaction": Object {
|
||||
"icon": "thumb_up_alt",
|
||||
"label": "Respect",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
@@ -128,6 +136,14 @@ exports[`when there is more disables load more button 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={null}
|
||||
settings={
|
||||
Object {
|
||||
"reaction": Object {
|
||||
"icon": "thumb_up_alt",
|
||||
"label": "Respect",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
@@ -260,6 +276,14 @@ exports[`when there is more renders a load more button 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={null}
|
||||
settings={
|
||||
Object {
|
||||
"reaction": Object {
|
||||
"icon": "thumb_up_alt",
|
||||
"label": "Respect",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
@@ -392,6 +416,14 @@ exports[`when use is logged in renders correctly 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={Object {}}
|
||||
settings={
|
||||
Object {
|
||||
"reaction": Object {
|
||||
"icon": "thumb_up_alt",
|
||||
"label": "Respect",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
<withContext(withContext(createMutationContainer(PostCommentFormContainer)))
|
||||
storyID="story-id"
|
||||
|
||||
@@ -88,6 +88,7 @@ const enhanced = withContext(ctx => ({
|
||||
fragment PermalinkViewContainer_settings on Settings {
|
||||
...ConversationThreadContainer_settings
|
||||
...ReplyListContainer1_settings
|
||||
...UserBoxContainer_settings
|
||||
}
|
||||
`,
|
||||
})(PermalinkViewContainer)
|
||||
|
||||
@@ -112,6 +112,7 @@ const enhanced = withPaginationContainer<
|
||||
fragment StreamContainer_settings on Settings {
|
||||
...ReplyListContainer1_settings
|
||||
...CommentContainer_settings
|
||||
...UserBoxContainer_settings
|
||||
}
|
||||
`,
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@ it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof ProfileN> = {
|
||||
story: {},
|
||||
me: {},
|
||||
settings: {},
|
||||
};
|
||||
const wrapper = shallow(<ProfileN {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -9,12 +9,13 @@ export interface ProfileProps {
|
||||
story: PropTypesOf<typeof CommentHistoryContainer>["story"];
|
||||
me: PropTypesOf<typeof UserBoxContainer>["me"] &
|
||||
PropTypesOf<typeof CommentHistoryContainer>["me"];
|
||||
settings: PropTypesOf<typeof UserBoxContainer>["settings"];
|
||||
}
|
||||
|
||||
const Profile: StatelessComponent<ProfileProps> = props => {
|
||||
return (
|
||||
<HorizontalGutter size="double">
|
||||
<UserBoxContainer me={props.me} />
|
||||
<UserBoxContainer me={props.me} settings={props.settings} />
|
||||
<CommentHistoryContainer me={props.me} story={props.story} />
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ exports[`renders correctly 1`] = `
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer)))))))))
|
||||
me={Object {}}
|
||||
settings={Object {}}
|
||||
/>
|
||||
<Relay(CommentHistoryContainer)
|
||||
me={Object {}}
|
||||
|
||||
@@ -3,18 +3,26 @@ import { graphql } from "react-relay";
|
||||
|
||||
import { withFragmentContainer } from "talk-framework/lib/relay";
|
||||
import { ProfileContainer_me as MeData } from "talk-stream/__generated__/ProfileContainer_me.graphql";
|
||||
import { ProfileContainer_settings as SettingsData } from "talk-stream/__generated__/ProfileContainer_settings.graphql";
|
||||
import { ProfileContainer_story as StoryData } from "talk-stream/__generated__/ProfileContainer_story.graphql";
|
||||
|
||||
import Profile from "../components/Profile";
|
||||
|
||||
interface ProfileContainerProps {
|
||||
me: MeData;
|
||||
settings: SettingsData;
|
||||
story: StoryData;
|
||||
}
|
||||
|
||||
export class StreamContainer extends React.Component<ProfileContainerProps> {
|
||||
public render() {
|
||||
return <Profile me={this.props.me} story={this.props.story} />;
|
||||
return (
|
||||
<Profile
|
||||
me={this.props.me}
|
||||
story={this.props.story}
|
||||
settings={this.props.settings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
const enhanced = withFragmentContainer<ProfileContainerProps>({
|
||||
@@ -29,6 +37,11 @@ const enhanced = withFragmentContainer<ProfileContainerProps>({
|
||||
...CommentHistoryContainer_me
|
||||
}
|
||||
`,
|
||||
settings: graphql`
|
||||
fragment ProfileContainer_settings on Settings {
|
||||
...UserBoxContainer_settings
|
||||
}
|
||||
`,
|
||||
})(StreamContainer);
|
||||
|
||||
export default enhanced;
|
||||
|
||||
@@ -40,7 +40,13 @@ export const render = ({
|
||||
</Localized>
|
||||
);
|
||||
}
|
||||
return <ProfileContainer me={props.me} story={props.story} />;
|
||||
return (
|
||||
<ProfileContainer
|
||||
me={props.me}
|
||||
story={props.story}
|
||||
settings={props.settings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <Spinner />;
|
||||
@@ -58,6 +64,9 @@ const ProfileQuery: StatelessComponent<InnerProps> = ({
|
||||
me {
|
||||
...ProfileContainer_me
|
||||
}
|
||||
settings {
|
||||
...ProfileContainer_settings
|
||||
}
|
||||
}
|
||||
`}
|
||||
variables={{
|
||||
|
||||
@@ -7,6 +7,7 @@ export default function create(params: CreateParams) {
|
||||
if (params.initLocalState) {
|
||||
localRecord.setValue("COMMENTS", "activeTab");
|
||||
localRecord.setValue(false, "loggedIn");
|
||||
localRecord.setValue("jti", "authJTI");
|
||||
params.initLocalState(localRecord, source, environment);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6,6 +6,27 @@ import {
|
||||
} from "talk-framework/testHelpers";
|
||||
|
||||
export const settings = {
|
||||
auth: {
|
||||
integrations: {
|
||||
facebook: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: false,
|
||||
allowRegistration: true,
|
||||
},
|
||||
local: {
|
||||
enabled: true,
|
||||
allowRegistration: true,
|
||||
},
|
||||
oidc: [],
|
||||
},
|
||||
},
|
||||
reaction: {
|
||||
icon: "thumb_up",
|
||||
label: "Respect",
|
||||
|
||||
@@ -6,6 +6,7 @@ export default function create(params: CreateParams) {
|
||||
initLocalState: (localRecord, source, environment) => {
|
||||
if (params.initLocalState) {
|
||||
localRecord.setValue("PROFILE", "activeTab");
|
||||
localRecord.setValue("jti", "authJTI");
|
||||
params.initLocalState(localRecord, source, environment);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ import sinon from "sinon";
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { createSinonStub } from "talk-framework/testHelpers";
|
||||
|
||||
import { comments, meWithComments, stories } from "../fixtures";
|
||||
import { comments, meWithComments, settings, stories } from "../fixtures";
|
||||
import create from "./create";
|
||||
|
||||
let testRenderer: ReactTestRenderer;
|
||||
@@ -54,6 +54,7 @@ beforeEach(() => {
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
settings: sinon.stub().returns(settings),
|
||||
story: createSinonStub(
|
||||
s => s.throws(),
|
||||
s =>
|
||||
|
||||
@@ -4,13 +4,14 @@ import sinon from "sinon";
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { createSinonStub } from "talk-framework/testHelpers";
|
||||
|
||||
import { meWithComments, stories } from "../fixtures";
|
||||
import { meWithComments, settings, stories } from "../fixtures";
|
||||
import create from "./create";
|
||||
|
||||
let testRenderer: ReactTestRenderer;
|
||||
beforeEach(() => {
|
||||
const resolvers = {
|
||||
Query: {
|
||||
settings: sinon.stub().returns(settings),
|
||||
story: createSinonStub(
|
||||
s => s.throws(),
|
||||
s =>
|
||||
|
||||
Reference in New Issue
Block a user