diff --git a/src/core/client/framework/mutations/SetAuthTokenMutation.ts b/src/core/client/framework/mutations/SetAuthTokenMutation.ts index 120188ac4..da0047add 100644 --- a/src/core/client/framework/mutations/SetAuthTokenMutation.ts +++ b/src/core/client/framework/mutations/SetAuthTokenMutation.ts @@ -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 ); diff --git a/src/core/client/stream/index.tsx b/src/core/client/stream/index.tsx index 80ddaeeab..8cc11ceb6 100644 --- a/src/core/client/stream/index.tsx +++ b/src/core/client/stream/index.tsx @@ -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 = ( <> + + diff --git a/src/core/client/stream/listeners/OnPostMessageSetAuthToken.spec.tsx b/src/core/client/stream/listeners/OnPostMessageSetAuthToken.spec.tsx index 290d917e6..92eec2050 100644 --- a/src/core/client/stream/listeners/OnPostMessageSetAuthToken.spec.tsx +++ b/src/core/client/stream/listeners/OnPostMessageSetAuthToken.spec.tsx @@ -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 = { - 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(); - expect(source.get(LOCAL_ID)!.authToken).toEqual(token); + + const setAuthToken = createSinonStub( + s => s.throws(), + s => s.withArgs({ authToken: token }).returns(null) + ); + + shallow( + + ); + expect(setAuthToken.calledOnce); }); diff --git a/src/core/client/stream/listeners/OnPostMessageSetAuthToken.ts b/src/core/client/stream/listeners/OnPostMessageSetAuthToken.ts index 553e4fa5b..9086f6214 100644 --- a/src/core/client/stream/listeners/OnPostMessageSetAuthToken.ts +++ b/src/core/client/stream/listeners/OnPostMessageSetAuthToken.ts @@ -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 { 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 { } } -const enhanced = withContext(context => ({ context }))( - OnPostMessageSetAuthToken +const enhanced = withContext(({ postMessage }) => ({ postMessage }))( + withSetAuthTokenMutation(OnPostMessageSetAuthToken) ); export default enhanced; diff --git a/src/core/client/stream/listeners/OnPymLogin.spec.tsx b/src/core/client/stream/listeners/OnPymLogin.spec.tsx new file mode 100644 index 000000000..478d106a7 --- /dev/null +++ b/src/core/client/stream/listeners/OnPymLogin.spec.tsx @@ -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(); + expect(setAuthToken.calledOnce); +}); diff --git a/src/core/client/stream/listeners/OnPymLogin.ts b/src/core/client/stream/listeners/OnPymLogin.ts new file mode 100644 index 000000000..0d40376e0 --- /dev/null +++ b/src/core/client/stream/listeners/OnPymLogin.ts @@ -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 { + 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; diff --git a/src/core/client/stream/listeners/OnPymLogout.spec.tsx b/src/core/client/stream/listeners/OnPymLogout.spec.tsx new file mode 100644 index 000000000..b2f1325cf --- /dev/null +++ b/src/core/client/stream/listeners/OnPymLogout.spec.tsx @@ -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(); + expect(signOut.calledOnce); +}); diff --git a/src/core/client/stream/listeners/OnPymLogout.ts b/src/core/client/stream/listeners/OnPymLogout.ts new file mode 100644 index 000000000..fd6411aa9 --- /dev/null +++ b/src/core/client/stream/listeners/OnPymLogout.ts @@ -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 { + 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; diff --git a/src/core/client/stream/listeners/index.ts b/src/core/client/stream/listeners/index.ts index 6400c538b..273e68663 100644 --- a/src/core/client/stream/listeners/index.ts +++ b/src/core/client/stream/listeners/index.ts @@ -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";