From 6c9a6d5f805d111ae1ecbd0c58de6e68f8bdffc0 Mon Sep 17 00:00:00 2001 From: Rick Clark Date: Wed, 26 Sep 2018 14:21:02 +0100 Subject: [PATCH] Setup apollo client auth link --- package-lock.json | 27 +++++++++++++++ package.json | 1 + src/components/App/index.js | 19 +++++++++++ src/components/GetStarted/index.fixture.js | 33 ++++++++++++++++++ src/components/GetStarted/index.js | 39 ++++++++++++++++++++++ src/components/GetStarted/style.css | 21 ++++++++++++ src/components/GetStarted/test.js | 10 ++++++ src/routes/SetupNew/index.js | 6 +++- src/routes/SetupNew/test.js | 24 +++++++++++++ 9 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/components/GetStarted/index.fixture.js create mode 100644 src/components/GetStarted/index.js create mode 100644 src/components/GetStarted/style.css create mode 100644 src/components/GetStarted/test.js diff --git a/package-lock.json b/package-lock.json index 7451031..803da8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -590,6 +590,33 @@ "zen-observable-ts": "^0.8.9" } }, + "apollo-link-context": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/apollo-link-context/-/apollo-link-context-1.0.9.tgz", + "integrity": "sha512-gcC1WH7mTyNtS0bF4fPijepXqnERwZjm1JCkuOT6ADBTpDTXIqK+Ec+/QkVawDO26EV9OX5ujWe4kI1qC6T6tA==", + "requires": { + "apollo-link": "^1.2.3" + }, + "dependencies": { + "apollo-link": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.3.tgz", + "integrity": "sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==", + "requires": { + "apollo-utilities": "^1.0.0", + "zen-observable-ts": "^0.8.10" + } + }, + "zen-observable-ts": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz", + "integrity": "sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ==", + "requires": { + "zen-observable": "^0.8.0" + } + } + } + }, "apollo-link-dedup": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.9.tgz", diff --git a/package.json b/package.json index cb18c3a..4de5fb6 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "apollo-cache-persist": "^0.1.1", "apollo-client": "^2.3.5", "apollo-link": "^1.2.2", + "apollo-link-context": "^1.0.9", "apollo-link-error": "^1.1.0", "apollo-link-http": "^1.5.4", "apollo-link-state": "^0.4.2", diff --git a/src/components/App/index.js b/src/components/App/index.js index b41cb6f..23148ce 100644 --- a/src/components/App/index.js +++ b/src/components/App/index.js @@ -1,6 +1,7 @@ /* eslint-disable import/no-named-as-default, no-console */ import React from 'react'; +import { get } from 'lodash'; import { BrowserRouter as Router, Route } from 'react-router-dom'; import { ApolloClient } from 'apollo-client'; import { @@ -11,6 +12,7 @@ import { HttpLink } from 'apollo-link-http'; import { onError } from 'apollo-link-error'; import { ApolloLink } from 'apollo-link'; import { ApolloProvider } from 'react-apollo'; +import { setContext } from 'apollo-link-context'; import { withClientState } from 'apollo-link-state'; import { persistCache } from 'apollo-cache-persist'; import { Provider } from 'react-redux'; @@ -62,6 +64,22 @@ export default class App extends React.Component { }, }); + const authLink = setContext((_, previousContext) => { + // get the authentication token from the cache + const token = get( + previousContext, + 'cache.data.data["$ROOT_QUERY.githubAuth"].token', + ); + + // return the headers to the context so httpLink can read them + return { + headers: { + ...previousContext.headers, + authorization: token ? `Bearer ${token}` : '', + }, + }; + }); + const client = new ApolloClient({ link: ApolloLink.from([ onError(({ graphQLErrors, networkError }) => { @@ -74,6 +92,7 @@ export default class App extends React.Component { if (networkError) console.log(`[Network error]: ${networkError}`); }), stateLink, + authLink, new HttpLink({ uri: process.env.REACT_APP_GITHUB_API_URL, credentials: 'same-origin', diff --git a/src/components/GetStarted/index.fixture.js b/src/components/GetStarted/index.fixture.js new file mode 100644 index 0000000..62b6f1c --- /dev/null +++ b/src/components/GetStarted/index.fixture.js @@ -0,0 +1,33 @@ +import { GetStarted } from '.'; + +const baseProps = { + saveGithubToken: () => {}, + setLoadingToken: () => {}, + loadingToken: false, +}; + +export default [ + { + component: GetStarted, + name: 'Not loading the token', + props: { + ...baseProps, + }, + }, + { + component: GetStarted, + name: 'Loading the token', + props: { + ...baseProps, + loadingToken: true, + }, + }, + { + component: GetStarted, + name: 'With error', + props: { + ...baseProps, + error: 'Borked', + }, + }, +]; diff --git a/src/components/GetStarted/index.js b/src/components/GetStarted/index.js new file mode 100644 index 0000000..ed0a203 --- /dev/null +++ b/src/components/GetStarted/index.js @@ -0,0 +1,39 @@ +/* eslint-disable no-return-assign */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import gql from 'graphql-tag'; +import { Query } from 'react-apollo'; + +import style from './style.css'; + +export function GetStarted({ data }) { + console.log(data); + return
; +} + +GetStarted.propTypes = { + data: PropTypes.shape({}).isRequired, +}; + +// GetStarted.defaultProps = { + +// }; + +const GET_CURRENT_USER = gql(` +query { + viewer { + login + avatarUrl + url + } +} +`); + +export default function GetStartedContainer() { + return ( + + {({ data, client }) => } + + ); +} diff --git a/src/components/GetStarted/style.css b/src/components/GetStarted/style.css new file mode 100644 index 0000000..22b3535 --- /dev/null +++ b/src/components/GetStarted/style.css @@ -0,0 +1,21 @@ +@import "../../css/colors.css"; +@import "../../css/units.css"; + +.signInContainer { + text-align: center; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} + +.welcome { + font-weight: bold; + color: var(--primary-medium); + font-size: 1.8rem; + margin-top: 0; +} + +.begin { + margin: 3rem auto; +} diff --git a/src/components/GetStarted/test.js b/src/components/GetStarted/test.js new file mode 100644 index 0000000..07d8011 --- /dev/null +++ b/src/components/GetStarted/test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { GetStarted } from '.'; + +describe('', () => { + it('renders successfully', () => { + const component = shallow(); + expect(component.length).toBe(1); + }); +}); diff --git a/src/routes/SetupNew/index.js b/src/routes/SetupNew/index.js index 05d4f18..46fc463 100644 --- a/src/routes/SetupNew/index.js +++ b/src/routes/SetupNew/index.js @@ -4,6 +4,7 @@ import { get } from 'lodash'; import gql from 'graphql-tag'; import { Query } from 'react-apollo'; import SignInForm from '../../components/SignInForm'; +import { GetStarted } from '../../components/GetStarted'; export const GET_GITHUB_TOKEN_FROM_CACHE = gql` { @@ -16,9 +17,11 @@ export const GET_GITHUB_TOKEN_FROM_CACHE = gql` `; export function SetupNew({ data, client }) { + const authToken = get(data, 'githubAuth.token'); + return ( - {!get(data, 'githubAuth.token') && ( + {!authToken && ( { client.writeData({ @@ -58,6 +61,7 @@ export function SetupNew({ data, client }) { error={get(data, 'githubAuth.error')} /> )} + {authToken && } ); } diff --git a/src/routes/SetupNew/test.js b/src/routes/SetupNew/test.js index 7fa0b14..dad553c 100644 --- a/src/routes/SetupNew/test.js +++ b/src/routes/SetupNew/test.js @@ -3,6 +3,7 @@ import { shallow } from 'enzyme'; import { SetupNew } from './'; import SignInForm from '../../components/SignInForm'; +import { GetStarted } from '../../components/GetStarted'; describe('Setup', () => { const defaultProps = { @@ -44,6 +45,10 @@ describe('Setup', () => { expect(props.error).toBe(data.githubAuth.error); }); + it('does not render a component', () => { + expect(component.find(GetStarted).length).toBe(0); + }); + describe('saveGithubToken fn passed to as a prop', () => { it('writes github token to apollo client + sets loading false', () => { const token = '1234'; @@ -103,4 +108,23 @@ describe('Setup', () => { }); }); }); + + describe('when apollo data contains github auth token', () => { + const data = { + githubAuth: { + token: '1234', + loadingToken: false, + error: null, + }, + }; + const component = shallow(); + + it('renders a component', () => { + expect(component.find(GetStarted).length).toBe(1); + }); + + it('does not render a component', () => { + expect(component.find(SignInForm).length).toBe(0); + }); + }); });