[next] Support login and logout for TalkStreamEmbed (#2081)

* feat: Support login and logout for TalkStreamEmbed

* fix: better test names

* fix: remove obsolete line
This commit is contained in:
Kiwi
2018-11-20 17:48:57 +01:00
committed by GitHub
parent 9af523318c
commit 6fa0c7f538
9 changed files with 148 additions and 52 deletions
@@ -18,7 +18,7 @@ export async function commit(
input: SetAuthTokenInput,
{ localStorage, clearSession }: TalkContext
) {
return await commitLocalUpdatePromisified(environment, async store => {
await commitLocalUpdatePromisified(environment, async store => {
setAuthTokenInLocalState(input.authToken, store);
if (input.authToken) {
await localStorage.setItem("authToken", input.authToken);
@@ -31,6 +31,6 @@ export async function commit(
}
export const withSetAuthTokenMutation = createMutationContainer(
"setCommentID",
"setAuthToken",
commit
);
+4
View File
@@ -10,6 +10,8 @@ import {
OnEvents,
OnPostMessageAuthError,
OnPostMessageSetAuthToken,
OnPymLogin,
OnPymLogout,
OnPymSetCommentID,
} from "./listeners";
import { initLocalState } from "./local";
@@ -17,6 +19,8 @@ import localesData from "./locales";
const listeners = (
<>
<OnPymLogin />
<OnPymLogout />
<OnPymSetCommentID />
<OnPostMessageSetAuthToken />
<OnPostMessageAuthError />
@@ -1,48 +1,29 @@
import { shallow } from "enzyme";
import { noop } from "lodash";
import React from "react";
import { Environment, RecordSource } from "relay-runtime";
import { TalkContext } from "talk-framework/lib/bootstrap";
import { LOCAL_ID } from "talk-framework/lib/relay";
import { createPromisifiedStorage } from "talk-framework/lib/storage";
import { createRelayEnvironment } from "talk-framework/testHelpers";
import { createSinonStub } from "talk-framework/testHelpers";
import { OnPostMessageSetAuthToken } from "./OnPostMessageSetAuthToken";
let relayEnvironment: Environment;
const source: RecordSource = new RecordSource();
beforeAll(() => {
relayEnvironment = createRelayEnvironment({
source,
});
});
it("Sets auth token", () => {
const token = `${btoa(
JSON.stringify({
alg: "HS256",
typ: "JWT",
})
)}.${btoa(
JSON.stringify({
exp: 1540503165,
jti: "31b26591-4e9a-4388-a7ff-e1bdc5d97cce",
})
)}`;
const context: Partial<TalkContext> = {
postMessage: {
on: (name: string, cb: (token: string) => void) => {
expect(name).toBe("setAuthToken");
cb(token);
},
} as any,
relayEnvironment,
localStorage: createPromisifiedStorage(),
clearSession: noop,
it("Listens to event and sets auth token", () => {
const token = "auth-token";
const postMessage: any = {
on: (name: string, cb: (token: string) => void) => {
expect(name).toBe("setAuthToken");
cb(token);
},
};
shallow(<OnPostMessageSetAuthToken context={context as any} />);
expect(source.get(LOCAL_ID)!.authToken).toEqual(token);
const setAuthToken = createSinonStub(
s => s.throws(),
s => s.withArgs({ authToken: token }).returns(null)
);
shallow(
<OnPostMessageSetAuthToken
postMessage={postMessage}
setAuthToken={setAuthToken}
/>
);
expect(setAuthToken.calledOnce);
});
@@ -1,22 +1,22 @@
import { Component } from "react";
import { TalkContext, withContext } from "talk-framework/lib/bootstrap";
import { commit as setAuthToken } from "talk-framework/mutations/SetAuthTokenMutation";
import {
SetAuthTokenMutation,
withSetAuthTokenMutation,
} from "talk-framework/mutations/SetAuthTokenMutation";
interface Props {
context: TalkContext;
postMessage: TalkContext["postMessage"];
setAuthToken: SetAuthTokenMutation;
}
export class OnPostMessageSetAuthToken extends Component<Props> {
constructor(props: Props) {
super(props);
// Auth popup will use this to handle a successful login.
props.context.postMessage!.on("setAuthToken", (authToken: string) => {
setAuthToken(
this.props.context.relayEnvironment,
{ authToken },
this.props.context
);
props.postMessage!.on("setAuthToken", (authToken: string) => {
props.setAuthToken({ authToken });
});
}
@@ -25,7 +25,7 @@ export class OnPostMessageSetAuthToken extends Component<Props> {
}
}
const enhanced = withContext(context => ({ context }))(
OnPostMessageSetAuthToken
const enhanced = withContext(({ postMessage }) => ({ postMessage }))(
withSetAuthTokenMutation(OnPostMessageSetAuthToken)
);
export default enhanced;
@@ -0,0 +1,24 @@
import { shallow } from "enzyme";
import React from "react";
import { createSinonStub } from "talk-framework/testHelpers";
import { OnPymLogin } from "./OnPymLogin";
it("Listens to event and calls setAuthToken", () => {
const authToken = "auth-token";
const pym: any = {
onMessage: (eventName: string, cb: (authToken: string) => void) => {
expect(eventName).toBe("login");
cb(authToken);
},
};
const setAuthToken = createSinonStub(
s => s.throws(),
s => s.withArgs({ authToken }).returns(null)
);
shallow(<OnPymLogin pym={pym} setAuthToken={setAuthToken} />);
expect(setAuthToken.calledOnce);
});
@@ -0,0 +1,34 @@
import { Child } from "pym.js";
import { Component } from "react";
import {
SetAuthTokenMutation,
withSetAuthTokenMutation,
} from "talk-framework/mutations";
import { withContext } from "talk-framework/lib/bootstrap";
interface Props {
pym: Child;
setAuthToken: SetAuthTokenMutation;
}
export class OnPymLogin extends Component<Props> {
constructor(props: Props) {
super(props);
// Sets comment id through pym.
props.pym!.onMessage("login", authToken => {
this.props.setAuthToken({ authToken });
});
}
public render() {
return null;
}
}
const enhanced = withContext(({ pym }) => ({
pym,
}))(withSetAuthTokenMutation(OnPymLogin));
export default enhanced;
@@ -0,0 +1,20 @@
import { shallow } from "enzyme";
import React from "react";
import sinon from "sinon";
import { OnPymLogout } from "./OnPymLogout";
it("Listens to event and calls signOut", () => {
const authToken = "auth-token";
const pym: any = {
onMessage: (eventName: string, cb: (authToken: string) => void) => {
expect(eventName).toBe("logout");
cb(authToken);
},
};
const signOut = sinon.stub();
shallow(<OnPymLogout pym={pym} signOut={signOut} />);
expect(signOut.calledOnce);
});
@@ -0,0 +1,31 @@
import { Child } from "pym.js";
import { Component } from "react";
import { SignOutMutation, withSignOutMutation } from "talk-framework/mutations";
import { withContext } from "talk-framework/lib/bootstrap";
interface Props {
pym: Child;
signOut: SignOutMutation;
}
export class OnPymLogout extends Component<Props> {
constructor(props: Props) {
super(props);
// Sets comment id through pym.
props.pym!.onMessage("logout", authToken => {
this.props.signOut();
});
}
public render() {
return null;
}
}
const enhanced = withContext(({ pym }) => ({
pym,
}))(withSignOutMutation(OnPymLogout));
export default enhanced;
@@ -4,3 +4,5 @@ export {
} from "./OnPostMessageSetAuthToken";
export { default as OnPostMessageAuthError } from "./OnPostMessageAuthError";
export { default as OnEvents } from "./OnEvents";
export { default as OnPymLogin } from "./OnPymLogin";
export { default as OnPymLogout } from "./OnPymLogout";