diff --git a/src/core/client/auth/components/App.tsx b/src/core/client/auth/components/App.tsx index 584e866bc..3bf18dbc2 100644 --- a/src/core/client/auth/components/App.tsx +++ b/src/core/client/auth/components/App.tsx @@ -14,7 +14,7 @@ export interface AppProps { const App: StatelessComponent = props => { return ( - Hello World + Show view {props.view} ); }; diff --git a/src/core/client/auth/local/__snapshots__/initLocalState.spec.ts.snap b/src/core/client/auth/local/__snapshots__/initLocalState.spec.ts.snap new file mode 100644 index 000000000..25e900e0c --- /dev/null +++ b/src/core/client/auth/local/__snapshots__/initLocalState.spec.ts.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`init local state 1`] = ` +"{ + \\"client:root\\": { + \\"__id\\": \\"client:root\\", + \\"__typename\\": \\"__Root\\", + \\"local\\": { + \\"__ref\\": \\"client:root.local\\" + } + }, + \\"client:root.local\\": { + \\"__id\\": \\"client:root.local\\", + \\"__typename\\": \\"Local\\", + \\"view\\": \\"SIGN_IN\\" + } +}" +`; diff --git a/src/core/client/auth/local/initLocalState.spec.ts b/src/core/client/auth/local/initLocalState.spec.ts new file mode 100644 index 000000000..bcf88006f --- /dev/null +++ b/src/core/client/auth/local/initLocalState.spec.ts @@ -0,0 +1,36 @@ +import { Environment, RecordSource } from "relay-runtime"; + +import { LOCAL_ID } from "talk-framework/lib/relay"; +import { createRelayEnvironment } from "talk-framework/testHelpers"; + +import initLocalState from "./initLocalState"; + +let environment: Environment; +let source: RecordSource; + +beforeEach(() => { + source = new RecordSource(); + environment = createRelayEnvironment({ + source, + initLocalState: false, + }); +}); + +it("init local state", () => { + initLocalState(environment); + expect(JSON.stringify(source.toJSON(), null, 2)).toMatchSnapshot(); +}); + +it("set view from query", () => { + const view = "SIGN_UP"; + const previousLocation = location.toString(); + const previousState = window.history.state; + window.history.replaceState( + previousState, + document.title, + `http://localhost/?view=${view}` + ); + initLocalState(environment); + expect(source.get(LOCAL_ID)!.view).toBe(view); + window.history.replaceState(previousState, document.title, previousLocation); +}); diff --git a/src/core/client/auth/local/initLocalState.ts b/src/core/client/auth/local/initLocalState.ts index 567825f50..15e9edfbc 100644 --- a/src/core/client/auth/local/initLocalState.ts +++ b/src/core/client/auth/local/initLocalState.ts @@ -1,3 +1,4 @@ +import qs from "query-string"; import { commitLocalUpdate, Environment } from "relay-runtime"; import { @@ -16,8 +17,11 @@ export default async function initLocalState(environment: Environment) { // Create the Local Record which is the Root for the client states. const localRecord = createAndRetain(environment, s, LOCAL_ID, LOCAL_TYPE); + // Parse query params + const query = qs.parse(location.search); + // Set default view. - localRecord.setValue("SIGN_IN", "view"); + localRecord.setValue(query.view || "SIGN_IN", "view"); root.setLinkedRecord(localRecord, "local"); }); diff --git a/src/core/client/framework/testHelpers/createRelayEnvironment.ts b/src/core/client/framework/testHelpers/createRelayEnvironment.ts index 717c037ad..f7e035ddc 100644 --- a/src/core/client/framework/testHelpers/createRelayEnvironment.ts +++ b/src/core/client/framework/testHelpers/createRelayEnvironment.ts @@ -31,12 +31,19 @@ export interface CreateRelayEnvironmentNetworkParams { export interface CreateRelayEnvironmentParams { /** If set, creates a network to a local graphql server with a local schema */ network?: CreateRelayEnvironmentNetworkParams; - /** Allows to set initial state for Local state */ - initLocalState?: ( - local: RecordProxy, - source: RecordSourceProxy, - environment: Environment - ) => void; + /** + * Initializes an empty local state if true. + * When passing in a function it gets executed after + * the intialization. Defaults to true. + */ + initLocalState?: + | (( + local: RecordProxy, + source: RecordSourceProxy, + environment: Environment + ) => void) + | false + | true; /** Use this source for creating the environment */ source?: RecordSource; } @@ -61,18 +68,20 @@ export default function createRelayEnvironment( network, store: new Store(params.source || new RecordSource()), }); - commitLocalUpdate(environment, sourceProxy => { - const root = sourceProxy.getRoot(); - const localRecord = createAndRetain( - environment, - sourceProxy, - LOCAL_ID, - LOCAL_TYPE - ); - root.setLinkedRecord(localRecord, "local"); - if (params.initLocalState) { - params.initLocalState!(localRecord, sourceProxy, environment); - } - }); + if (params.initLocalState !== false) { + commitLocalUpdate(environment, sourceProxy => { + const root = sourceProxy.getRoot(); + const localRecord = createAndRetain( + environment, + sourceProxy, + LOCAL_ID, + LOCAL_TYPE + ); + root.setLinkedRecord(localRecord, "local"); + if (typeof params.initLocalState === "function") { + params.initLocalState!(localRecord, sourceProxy, environment); + } + }); + } return environment; } diff --git a/src/core/client/stream/local/__snapshots__/initLocalState.spec.ts.snap b/src/core/client/stream/local/__snapshots__/initLocalState.spec.ts.snap new file mode 100644 index 000000000..52ffec402 --- /dev/null +++ b/src/core/client/stream/local/__snapshots__/initLocalState.spec.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`init local state 1`] = ` +"{ + \\"client:root\\": { + \\"__id\\": \\"client:root\\", + \\"__typename\\": \\"__Root\\", + \\"local\\": { + \\"__ref\\": \\"client:root.local\\" + } + }, + \\"client:root.local\\": { + \\"__id\\": \\"client:root.local\\", + \\"__typename\\": \\"Local\\", + \\"network\\": { + \\"__ref\\": \\"client:root.local.network\\" + }, + \\"authPopup\\": { + \\"__ref\\": \\"client:root.local.authPopup\\" + } + }, + \\"client:root.local.network\\": { + \\"__id\\": \\"client:root.local.network\\", + \\"__typename\\": \\"Network\\", + \\"isOffline\\": false + }, + \\"client:root.local.authPopup\\": { + \\"__id\\": \\"client:root.local.authPopup\\", + \\"__typename\\": \\"AuthPopup\\", + \\"open\\": false, + \\"focus\\": false, + \\"href\\": \\"\\" + } +}" +`; diff --git a/src/core/client/stream/local/initLocalState.spec.ts b/src/core/client/stream/local/initLocalState.spec.ts new file mode 100644 index 000000000..d1842c9a5 --- /dev/null +++ b/src/core/client/stream/local/initLocalState.spec.ts @@ -0,0 +1,52 @@ +import { Environment, RecordSource } from "relay-runtime"; + +import { timeout } from "talk-common/utils"; +import { LOCAL_ID } from "talk-framework/lib/relay"; +import { createRelayEnvironment } from "talk-framework/testHelpers"; + +import initLocalState from "./initLocalState"; + +let environment: Environment; +let source: RecordSource; + +beforeEach(() => { + source = new RecordSource(); + environment = createRelayEnvironment({ + source, + initLocalState: false, + }); +}); + +it("init local state", async () => { + initLocalState(environment); + await timeout(); + expect(JSON.stringify(source.toJSON(), null, 2)).toMatchSnapshot(); +}); + +it("set assetID from query", () => { + const assetID = "asset-id"; + const previousLocation = location.toString(); + const previousState = window.history.state; + window.history.replaceState( + previousState, + document.title, + `http://localhost/?assetID=${assetID}` + ); + initLocalState(environment); + expect(source.get(LOCAL_ID)!.assetID).toBe(assetID); + window.history.replaceState(previousState, document.title, previousLocation); +}); + +it("set commentID from query", () => { + const commentID = "comment-id"; + const previousLocation = location.toString(); + const previousState = window.history.state; + window.history.replaceState( + previousState, + document.title, + `http://localhost/?commentID=${commentID}` + ); + initLocalState(environment); + expect(source.get(LOCAL_ID)!.commentID).toBe(commentID); + window.history.replaceState(previousState, document.title, previousLocation); +});