From ca3cf1dfe9cb6a3cf53aa5318c03a5130b2e866f Mon Sep 17 00:00:00 2001 From: William San Date: Wed, 29 Jun 2022 18:35:04 -0400 Subject: [PATCH 1/3] Add initial state to embeddable sandbox and HTML unit tests --- .../__tests__/getEmbeddedExplorerHTML.test.ts | 83 +++++++++++++++++++ .../__tests__/getEmbeddedSandboxHTML.test.ts | 74 +++++++++++++++++ .../src/plugin/landingPage/default/index.ts | 12 ++- .../src/plugin/landingPage/default/types.ts | 2 +- 4 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 packages/server/src/plugin/landingPage/__tests__/getEmbeddedExplorerHTML.test.ts create mode 100644 packages/server/src/plugin/landingPage/__tests__/getEmbeddedSandboxHTML.test.ts diff --git a/packages/server/src/plugin/landingPage/__tests__/getEmbeddedExplorerHTML.test.ts b/packages/server/src/plugin/landingPage/__tests__/getEmbeddedExplorerHTML.test.ts new file mode 100644 index 00000000000..d0f4972648b --- /dev/null +++ b/packages/server/src/plugin/landingPage/__tests__/getEmbeddedExplorerHTML.test.ts @@ -0,0 +1,83 @@ +import { getEmbeddedExplorerHTML } from '../default/index'; +import type { ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions } from '../default/types'; + +const version = '_latest'; +expect.addSnapshotSerializer(require('jest-serializer-html')); + +describe('Embedded Explorer Landing Page Config HTML', () => { + it('with document, variables, headers and displayOptions provided', () => { + const config: ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions = + { + includeCookies: true, + document: 'query Test { id }', + variables: { + option: { + a: 'val', + b: 1, + c: true, + }, + }, + headers: { authorization: 'true' }, + embed: { + displayOptions: { + showHeadersAndEnvVars: true, + docsPanelState: 'open', + theme: 'light', + }, + persistExplorerState: true, + }, + graphRef: 'graph@current', + }; + expect(getEmbeddedExplorerHTML(version, config)).toMatchInlineSnapshot(` + +
+
+ + + `); + }); + + it('for embedded explorer with document, variables, headers and displayOptions excluded', () => { + const config: ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions = + { + includeCookies: false, + embed: true as true, + graphRef: 'graph@current', + }; + expect(getEmbeddedExplorerHTML(version, config)).toMatchInlineSnapshot(` + +
+
+ + + `); + }); +}); diff --git a/packages/server/src/plugin/landingPage/__tests__/getEmbeddedSandboxHTML.test.ts b/packages/server/src/plugin/landingPage/__tests__/getEmbeddedSandboxHTML.test.ts new file mode 100644 index 00000000000..08a70cf2f91 --- /dev/null +++ b/packages/server/src/plugin/landingPage/__tests__/getEmbeddedSandboxHTML.test.ts @@ -0,0 +1,74 @@ +import { getEmbeddedSandboxHTML } from '../default'; +import type { LandingPageConfig } from '../default/types'; + +const version = '_latest'; +expect.addSnapshotSerializer(require('jest-serializer-html')); + +describe('Landing Page Config HTML', () => { + it('for embedded sandbox with document, variables and headers provided', () => { + const config: LandingPageConfig = { + includeCookies: true, + document: 'query Test { id }', + variables: { + option: { + a: 'val', + b: 1, + c: true, + }, + }, + headers: { authorization: 'true' }, + embed: true, + }; + expect(getEmbeddedSandboxHTML(version, config)).toMatchInlineSnapshot(` + +
+
+ + + `); + }); + + it('for embedded sandbox with document, variables and headers excluded', () => { + const config: LandingPageConfig = { + includeCookies: false, + embed: true, + }; + expect(getEmbeddedSandboxHTML(version, config)).toMatchInlineSnapshot(` + +
+
+ + + `); + }); +}); diff --git a/packages/server/src/plugin/landingPage/default/index.ts b/packages/server/src/plugin/landingPage/default/index.ts index 1a1444aa7d3..1596093c978 100644 --- a/packages/server/src/plugin/landingPage/default/index.ts +++ b/packages/server/src/plugin/landingPage/default/index.ts @@ -66,7 +66,7 @@ function getConfigStringForHtml(config: LandingPageConfig) { .replace("'", '\\u0027'); } -const getEmbeddedExplorerHTML = ( +export const getEmbeddedExplorerHTML = ( version: string, config: ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions, ) => { @@ -133,7 +133,10 @@ id="embeddableExplorer" `; }; -const getEmbeddedSandboxHTML = (version: string, config: LandingPageConfig) => { +export const getEmbeddedSandboxHTML = ( + version: string, + config: LandingPageConfig, +) => { return ` +
+ + +`; +}; + +export const getEmbeddedSandboxHTML = ( + version: string, + config: LandingPageConfig, +) => { + return ` + +
+ + +`; +}; diff --git a/packages/server/src/plugin/landingPage/default/index.ts b/packages/server/src/plugin/landingPage/default/index.ts index 1596093c978..15a87fb6c84 100644 --- a/packages/server/src/plugin/landingPage/default/index.ts +++ b/packages/server/src/plugin/landingPage/default/index.ts @@ -1,11 +1,14 @@ import type { BaseContext } from '../../../externalTypes'; import type { ImplicitlyInstallablePlugin } from '../../../ApolloServer'; import type { - ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions, ApolloServerPluginLandingPageLocalDefaultOptions, ApolloServerPluginLandingPageProductionDefaultOptions, LandingPageConfig, } from './types'; +import { + getEmbeddedExplorerHTML, + getEmbeddedSandboxHTML, +} from './getEmbeddedHTML.js'; export function ApolloServerPluginLandingPageLocalDefault< TContext extends BaseContext, @@ -49,121 +52,6 @@ function encodeConfig(config: LandingPageConfig): string { return JSON.stringify(encodeURIComponent(JSON.stringify(config))); } -// This function turns an object into a string and replaces -// <, >, &, ' with their unicode chars to avoid adding html tags to -// the landing page html that might be passed from the config. -// The only place these characters can appear in the output of -// JSON.stringify is within string literals, where they can equally -// well appear \u-escaped. This specifically means that -// `` won't terminate the script block early. -// (Perhaps we should have done this instead of the triple-encoding -// of encodeConfig for the main landing page.) -function getConfigStringForHtml(config: LandingPageConfig) { - return JSON.stringify(config) - .replace('<', '\\u003c') - .replace('>', '\\u003e') - .replace('&', '\\u0026') - .replace("'", '\\u0027'); -} - -export const getEmbeddedExplorerHTML = ( - version: string, - config: ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions, -) => { - interface EmbeddableExplorerOptions { - graphRef: string; - target: string; - - initialState?: { - document?: string; - variables?: Record; - headers?: Record; - displayOptions: { - docsPanelState?: 'open' | 'closed'; // default to 'open', - showHeadersAndEnvVars?: boolean; // default to `false` - theme?: 'dark' | 'light'; - }; - }; - persistExplorerState?: boolean; // defaults to 'false' - - endpointUrl: string; - - includeCookies?: boolean; // defaults to 'false' - } - const productionLandingPageConfigOrDefault = { - displayOptions: {}, - persistExplorerState: false, - ...(typeof config.embed === 'boolean' ? {} : config.embed), - }; - const embeddedExplorerParams: Omit = - { - ...config, - target: '#embeddableExplorer', - initialState: { - ...config, - displayOptions: { - ...productionLandingPageConfigOrDefault.displayOptions, - }, - }, - persistExplorerState: - productionLandingPageConfigOrDefault.persistExplorerState, - }; - - return ` - -
- - -`; -}; - -export const getEmbeddedSandboxHTML = ( - version: string, - config: LandingPageConfig, -) => { - return ` - -
- - -`; -}; - const getNonEmbeddedLandingPageHTML = ( version: string, config: LandingPageConfig,