Skip to content

Commit

Permalink
[sitecore-jss] [sitecore-jss-nextjs] Pass sc_layoutKind to grapqhl …
Browse files Browse the repository at this point in the history
…layout request header. (#1907)

* pass layout kind to grapqhl request

* update changelog

* refactor

* remove only

* Update CHANGELOG.md

Co-authored-by: Illia Kovalenko <[email protected]>

* Update packages/sitecore-jss/src/editing/graphql-editing-service.ts

Co-authored-by: Illia Kovalenko <[email protected]>

* Update packages/sitecore-jss/src/editing/graphql-editing-service.ts

Co-authored-by: Illia Kovalenko <[email protected]>

* resolve review comments

* Update CHANGELOG.md

* update changelog

* fix changelog

---------

Co-authored-by: Addy Pathania <[email protected]>
Co-authored-by: Illia Kovalenko <[email protected]>
  • Loading branch information
3 people authored Aug 27, 2024
1 parent e232f6f commit 20ac215
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 27 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ Our versioning strategy is as follows:

### 🧹 Chores

## 22.1.1

### 🎉 New Features & Improvements

* `[XM Cloud]` `[Metadata Mode]` `[Next.js]` API was changed, next.js preview data provides a new parameter `layoutKind` therefore, please make the necessary updates in the app in `plugins/preview-mode.ts` as shown in the following PR to experience a smooth upgrade.
* `[sitecore-jss]` `[sitecore-jss-nextjs]` Pass `sc_layoutKind` to GraphQLEditingService request header to support shared/final editing layouts ([#1907](https://github.com/Sitecore/jss/pull/1907))
* `[sitecore-jss]` `GraphQLRequestClient`'s `request` method now supports dynamic headers based on specific request ([#1907](https://github.com/Sitecore/jss/pull/1907))

```
client.request(query, variables, { headers })
```

## 22.1.0

### 🐛 Bug Fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ class PreviewModePlugin implements Plugin {

// If we're in Pages preview (editing) Metadata Edit Mode, prefetch the editing data
if (isEditingMetadataPreviewData(context.previewData)) {
const { site, itemId, language, version, variantIds } = context.previewData;
const { site, itemId, language, version, variantIds, layoutKind } = context.previewData;

const data = await graphQLEditingService.fetchEditingData({
siteName: site,
itemId,
language,
version,
layoutKind,
});

if (!data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ describe('EditingRenderMiddleware', () => {
sc_variant: 'dev',
sc_version: 'latest',
secret: secret,
sc_layoutKind: 'shared',
} as MetadataQueryParams;

it('should handle request', async () => {
Expand All @@ -200,6 +201,7 @@ describe('EditingRenderMiddleware', () => {
version: 'latest',
editMode: 'metadata',
pageState: 'edit',
layoutKind: 'shared',
});

expect(res.redirect).to.have.been.calledOnce;
Expand Down Expand Up @@ -237,6 +239,7 @@ describe('EditingRenderMiddleware', () => {
version: undefined,
editMode: 'metadata',
pageState: 'edit',
layoutKind: undefined,
});
});

Expand Down Expand Up @@ -265,6 +268,7 @@ describe('EditingRenderMiddleware', () => {
version: undefined,
editMode: 'metadata',
pageState: 'edit',
layoutKind: undefined,
});

expect(res.redirect).to.have.been.calledOnce;
Expand Down Expand Up @@ -297,6 +301,7 @@ describe('EditingRenderMiddleware', () => {
version: 'latest',
editMode: 'metadata',
pageState: 'edit',
layoutKind: 'shared',
});

expect(res.redirect).to.have.been.calledOnce;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
import { STATIC_PROPS_ID, SERVER_PROPS_ID } from 'next/constants';
import { AxiosDataFetcher, debug } from '@sitecore-jss/sitecore-jss';
import { EditMode, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
import { LayoutKind } from '@sitecore-jss/sitecore-jss/editing';
import {
QUERY_PARAM_EDITING_SECRET,
EDITING_ALLOWED_ORIGINS,
Expand Down Expand Up @@ -277,6 +278,7 @@ export type MetadataQueryParams = {
mode: Exclude<LayoutServicePageState, 'normal'>;
sc_variant?: string;
sc_version?: string;
sc_layoutKind?: LayoutKind;
};

/**
Expand All @@ -297,6 +299,7 @@ export type EditingMetadataPreviewData = {
pageState: Exclude<LayoutServicePageState, 'Normal'>;
variantIds: string[];
version?: string;
layoutKind?: LayoutKind;
};

/**
Expand Down Expand Up @@ -358,6 +361,7 @@ export class MetadataHandler {
version: query.sc_version,
editMode: EditMode.Metadata,
pageState: query.mode,
layoutKind: query.sc_layoutKind,
} as EditingMetadataPreviewData,
// Cache the preview data for 3 seconds to ensure the page is rendered with the correct preview data not the cached one
{
Expand Down
90 changes: 78 additions & 12 deletions packages/sitecore-jss/src/editing/graphql-editing-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
mockEditingServiceResponse,
} from '../test-data/mockEditingServiceResponse';
import { EditMode } from '../layout';
import { LayoutKind } from './models';
import debug from '../debug';

use(spies);
Expand Down Expand Up @@ -91,12 +92,20 @@ describe('GraphQLEditingService', () => {
})
).to.be.true;
expect(clientFactorySpy.returnValues[0].request).to.be.called.exactly(1);
expect(clientFactorySpy.returnValues[0].request).to.be.called.with(query, {
language,
version,
itemId,
siteName,
});
expect(clientFactorySpy.returnValues[0].request).to.be.called.with(
query,
{
language,
version,
itemId,
siteName,
},
{
headers: {
sc_layoutKind: 'final',
},
}
);

expect(result).to.deep.equal({
layoutData: layoutDataResponse,
Expand Down Expand Up @@ -148,12 +157,20 @@ describe('GraphQLEditingService', () => {
})
).to.be.true;
expect(clientFactorySpy.returnValues[0].request).to.be.called.exactly(1);
expect(clientFactorySpy.returnValues[0].request).to.be.called.with(query, {
language,
version,
itemId,
siteName,
});
expect(clientFactorySpy.returnValues[0].request).to.be.called.with(
query,
{
language,
version,
itemId,
siteName,
},
{
headers: {
sc_layoutKind: 'final',
},
}
);

expect(result).to.deep.equal({
layoutData: {
Expand Down Expand Up @@ -215,6 +232,55 @@ describe('GraphQLEditingService', () => {
spy.restore(clientFactorySpy);
});

it('should fetch shared layout editing data', async () => {
nock(hostname, { reqheaders: { sc_editMode: 'true', sc_layoutKind: 'shared' } })
.post(endpointPath, /EditingQuery/gi)
.reply(200, editingData);

const clientFactorySpy = sinon.spy(clientFactory);

const service = new GraphQLEditingService({
clientFactory: clientFactorySpy,
});

spy.on(clientFactorySpy.returnValues[0], 'request');

const result = await service.fetchEditingData({
language,
version,
itemId,
siteName,
layoutKind: LayoutKind.Shared,
});

expect(clientFactorySpy.calledOnce).to.be.true;
expect(clientFactorySpy.returnValues[0].request).to.be.called.exactly(1);
expect(clientFactorySpy.returnValues[0].request).to.be.called.with(
query,
{
language,
version,
itemId,
siteName,
},
{
headers: {
sc_layoutKind: 'shared',
},
}
);

expect(result).to.deep.equal({
layoutData: layoutDataResponse,
dictionary: {
foo: 'foo-phrase',
bar: 'bar-phrase',
},
});

spy.restore(clientFactorySpy);
});

it('should fetch editing data when dicionary has multiple pages', async () => {
nock(hostname, { reqheaders: { sc_editMode: 'true' } })
.post(endpointPath, /EditingQuery/gi)
Expand Down
33 changes: 26 additions & 7 deletions packages/sitecore-jss/src/editing/graphql-editing-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PageInfo } from '../graphql';
import { GraphQLClient, GraphQLRequestClientFactory } from '../graphql-request-client';
import { DictionaryPhrases } from '../i18n';
import { EditMode, LayoutServiceData } from '../layout';
import { LayoutKind } from './models';

/**
* The dictionary query default page size.
Expand Down Expand Up @@ -115,20 +116,30 @@ export class GraphQLEditingService {
* @param {string} variables.itemId - The item id (path) to fetch layout data for.
* @param {string} variables.language - The language to fetch layout data for.
* @param {string} [variables.version] - The version of the item (optional).
* @param {LayoutKind} [variables.layoutKind] - The final or shared layout variant.
* @returns {Promise} The layout data and dictionary phrases.
*/
async fetchEditingData({
siteName,
itemId,
language,
version,
layoutKind = LayoutKind.Final,
}: {
siteName: string;
itemId: string;
language: string;
version?: string;
layoutKind?: LayoutKind;
}) {
debug.editing('fetching editing data for %s %s %s %s', siteName, itemId, language, version);
debug.editing(
'fetching editing data for %s %s %s %s',
siteName,
itemId,
language,
version,
layoutKind
);

if (!siteName) {
throw new RangeError('The site name must be a non-empty string');
Expand All @@ -143,12 +154,20 @@ export class GraphQLEditingService {
let hasNext = true;
let after = '';

const editingData = await this.graphQLClient.request<GraphQLEditingQueryResponse>(query, {
siteName,
itemId,
version,
language,
});
const editingData = await this.graphQLClient.request<GraphQLEditingQueryResponse>(
query,
{
siteName,
itemId,
version,
language,
},
{
headers: {
sc_layoutKind: layoutKind,
},
}
);

if (editingData?.site?.siteInfo?.dictionary) {
dictionaryResults = editingData.site.siteInfo.dictionary.results;
Expand Down
1 change: 1 addition & 0 deletions packages/sitecore-jss/src/editing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export {
EditButtonTypes,
mapButtonToCommand,
} from './edit-frame';
export { LayoutKind } from './models';
9 changes: 9 additions & 0 deletions packages/sitecore-jss/src/editing/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Represents the Editing Layout variant.
* - shared - shared layout
* - final - final layout
*/
export enum LayoutKind {
Final = 'final',
Shared = 'shared',
}
36 changes: 35 additions & 1 deletion packages/sitecore-jss/src/graphql-request-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,41 @@ describe('GraphQLRequestClient', () => {
});

const graphQLClient = new GraphQLRequestClient(endpoint, { apiKey });
await graphQLClient.request('test');
const result = await graphQLClient.request('test');

expect(result).to.deep.equal({ result: 'Hello world...' });
});

it('should send additional request headers configured through options', async () => {
const apiKey = 'cjhNRWNVOHRFTklwUjhYa0RSTnBhSStIam1mNE1KN1pyeW13c3FnRVExTT18bXRzdC1kLTAxOQ==';
const customHeader = 'Custom-Header-Value';
nock('http://jssnextweb', {
reqheaders: {
sc_apikey: apiKey,
},
})
.post('/graphql')
.reply(200, function() {
const receivedHeaders = this.req.headers;

expect(receivedHeaders['sc_apikey']).to.deep.equal([apiKey]);
expect(receivedHeaders['custom-header']).to.deep.equal([customHeader]);

return {
data: {
result: 'Hello world...',
},
};
});

const graphQLClient = new GraphQLRequestClient(endpoint, { apiKey });
const result = await graphQLClient.request('test', undefined, {
headers: {
'Custom-Header': customHeader,
},
});

expect(result).to.deep.equal({ result: 'Hello world...' });
});

it('should debug log request and response', async () => {
Expand Down
Loading

0 comments on commit 20ac215

Please sign in to comment.