Skip to content

Commit

Permalink
fix: minor fixes, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BJvdA committed Mar 25, 2021
1 parent 3f5fa01 commit 8370daa
Show file tree
Hide file tree
Showing 10 changed files with 465 additions and 80 deletions.
35 changes: 35 additions & 0 deletions src/client/__tests__/getClient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { rest } from 'msw';
import { setupServer } from 'msw/node';

import { getClient } from '..';

const token = '123';

const server = setupServer();

describe('[client] getClient', () => {
beforeAll(() => server.listen());
afterEach(() => {
server.resetHandlers();
jest.restoreAllMocks();
});
afterAll(() => server.close());

it('should return a configured GraphQL request client', async () => {
const client = getClient({ token });

server.use(
rest.post(`https://gapi.storyblok.com/v1/api`, async (req, res, ctx) => {
expect(req.headers).toHaveProperty('map.token', token);
expect(req.headers).toHaveProperty('map.version', 'published');

return res(
ctx.status(200),
ctx.json({ data: { ArticleItem: { content: { title: 'Title' } } } }),
);
}),
);

await client.request('');
});
});
80 changes: 80 additions & 0 deletions src/client/__tests__/getStaticPropsWithSdk.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { rest } from 'msw';
import { setupServer } from 'msw/node';

import { getClient, getStaticPropsWithSdk } from '..';

const token = '123';
const previewToken = '456';

const server = setupServer();

describe('[client] getStaticPropsWithSdk', () => {
beforeAll(() => server.listen());
afterEach(() => {
server.resetHandlers();
jest.restoreAllMocks();
});
afterAll(() => server.close());

it('should inject a configured GraphQL request client', async () => {
const getSdkMock = jest.fn((v) => v);

const client = getClient({ token });
const staticPropsWithSdk = getStaticPropsWithSdk(
getSdkMock,
client,
previewToken,
);

server.use(
rest.post(`https://gapi.storyblok.com/v1/api`, async (req, res, ctx) => {
expect(req.headers).toHaveProperty('map.token', token);
expect(req.headers).toHaveProperty('map.version', 'published');

return res(ctx.status(200), ctx.json({ data: {} }));
}),
);

const res = await staticPropsWithSdk(async ({ sdk }) => {
expect(sdk).toBeDefined();

await sdk.request('');

return { props: { test: true } };
})({});

expect(res.props?.__storyblok_toolkit_preview).not.toBeTruthy();
expect(res.props?.test).toBeTruthy();
});

it('should configure for draft in preview mode', async () => {
const getSdkMock = jest.fn((v) => v);

const client = getClient({ token });
const staticPropsWithSdk = getStaticPropsWithSdk(
getSdkMock,
client,
previewToken,
);

server.use(
rest.post(`https://gapi.storyblok.com/v1/api`, async (req, res, ctx) => {
expect(req.headers).toHaveProperty('map.token', previewToken);
expect(req.headers).toHaveProperty('map.version', 'draft');

return res(ctx.status(200), ctx.json({ data: {} }));
}),
);

const res = await staticPropsWithSdk(async ({ sdk }) => {
expect(sdk).toBeDefined();

await sdk.request('');

return {} as any;
})({ preview: true });

expect(res.props?.__storyblok_toolkit_preview).toBeTruthy();
expect(Object.keys(res.props).length).toBe(1);
});
});
36 changes: 36 additions & 0 deletions src/client/getClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { GraphQLClient } from 'graphql-request';

export interface ClientOptions {
/**
* Custom fetch init parameters, `graphql-request` version.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters
*/
additionalOptions?: ConstructorParameters<typeof GraphQLClient>[1];
/** Storyblok API token (preview or publish) */
token: string;
/**
* Which version of the story to load. Defaults to `'draft'` in development,
* and `'published'` in production.
*
* @default `process.env.NODE_ENV === 'development' ? 'draft' : 'published'`
*/
version?: 'draft' | 'published';
}

export const getClient = ({
additionalOptions,
token: Token,
version,
}: ClientOptions) =>
new GraphQLClient('https://gapi.storyblok.com/v1/api', {
...(additionalOptions || {}),
headers: {
Token,
Version:
version || process.env.NODE_ENV === 'development'
? 'draft'
: 'published',
...(additionalOptions?.headers || {}),
},
});
45 changes: 45 additions & 0 deletions src/client/getStaticPropsWithSdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { ParsedUrlQuery } from 'querystring';
import { GraphQLClient } from 'graphql-request';
import type { GetStaticPropsResult, GetStaticPropsContext } from 'next';

import { getClient, ClientOptions } from './getClient';

type SdkFunctionWrapper = <T>(action: () => Promise<T>) => Promise<T>;
type GetSdk<T> = (client: GraphQLClient, withWrapper?: SdkFunctionWrapper) => T;

type GetStaticPropsWithSdk<
R,
P extends { [key: string]: any } = { [key: string]: any },
Q extends ParsedUrlQuery = ParsedUrlQuery
> = (
context: GetStaticPropsContext<Q> & { sdk: R },
) => Promise<GetStaticPropsResult<P>>;

export const getStaticPropsWithSdk = <T>(
getSdk: GetSdk<T>,
client: GraphQLClient,
storyblokToken?: string,
additionalClientOptions?: ClientOptions['additionalOptions'],
) => (getStaticProps: GetStaticPropsWithSdk<T>) => async (
context: GetStaticPropsContext,
) => {
const sdk = getSdk(
storyblokToken && context?.preview
? getClient({
additionalOptions: additionalClientOptions,
token: storyblokToken,
version: 'draft',
})
: client,
);

const res = await getStaticProps({ ...context, sdk });

return {
...res,
props: {
...((res as any)?.props || {}),
__storyblok_toolkit_preview: !!context?.preview,
},
};
};
80 changes: 2 additions & 78 deletions src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,2 @@
import type { ParsedUrlQuery } from 'querystring';
import { GraphQLClient } from 'graphql-request';
import type { GetStaticPropsResult, GetStaticPropsContext } from 'next';

interface ClientOptions {
/**
* Custom fetch init parameters, `graphql-request` version.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters
*/
additionalOptions?: ConstructorParameters<typeof GraphQLClient>[1];
/** Storyblok API token (preview or publish) */
token: string;
/**
* Which version of the story to load. Defaults to `'draft'` in development,
* and `'published'` in production.
*
* @default `process.env.NODE_ENV === 'development' ? 'draft' : 'published'`
*/
version?: 'draft' | 'published';
}

type SdkFunctionWrapper = <T>(action: () => Promise<T>) => Promise<T>;
type GetSdk<T> = (client: GraphQLClient, withWrapper?: SdkFunctionWrapper) => T;

type GetStaticPropsWithSdk<
R,
P extends { [key: string]: any } = { [key: string]: any },
Q extends ParsedUrlQuery = ParsedUrlQuery
> = (
context: GetStaticPropsContext<Q> & { sdk: R },
) => Promise<GetStaticPropsResult<P>>;

export const getClient = ({
additionalOptions,
token: Token,
version,
}: ClientOptions) =>
new GraphQLClient('https://gapi.storyblok.com/v1/api', {
...(additionalOptions || {}),
headers: {
Token,
Version:
version || process.env.NODE_ENV === 'development'
? 'draft'
: 'published',
...(additionalOptions?.headers || {}),
},
});

export const getStaticPropsWithSdk = <T>(
getSdk: GetSdk<T>,
client: GraphQLClient,
storyblokToken?: string,
additionalClientOptions?: ClientOptions['additionalOptions'],
) => (getStaticProps: GetStaticPropsWithSdk<T>) => async (
context: GetStaticPropsContext,
) => {
const sdk = getSdk(
storyblokToken && context?.preview
? getClient({
additionalOptions: additionalClientOptions,
token: storyblokToken,
version: 'draft',
})
: client,
);

const res = await getStaticProps({ ...context, sdk });

return {
...res,
props: {
...((res as any)?.props || {}),
__storyblok_toolkit_preview: !!context?.preview,
},
};
};
export * from './getClient';
export * from './getStaticPropsWithSdk';
Loading

1 comment on commit 8370daa

@vercel
Copy link

@vercel vercel bot commented on 8370daa Mar 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.