Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(reference-editor): re-introduce entity refetch when slide-in is closed #1233

Merged
merged 2 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 72 additions & 15 deletions cypress/component/reference/MultipleEntryReferenceEditor.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React from 'react';

import { NavigatorSlideInfo } from '@contentful/app-sdk';
import { Button, Card, Heading, Note, Paragraph } from '@contentful/f36-components';
import { Entry } from '@contentful/field-editor-shared';
import { cloneDeep, set } from 'lodash-es';

import { CombinedLinkActions, MultipleEntryReferenceEditor } from '../../../packages/reference/src';
import { Entity, Link } from '../../../packages/reference/src/types';
import { ReferenceEditorSdkProps } from '../../fixtures';
import { PubsubFake } from '../../fixtures/pubsub';
import { createDefaultFakeStore } from '../../fixtures/store';
import {
createReferenceEditorTestSdk,
fixtures,
ReferenceEditorFakeSdkProps,
} from '../../fixtures';
import { mount } from '../mount';
import { createReferenceEditorTestSdk, fixtures } from '../test-sdks';

const commonProps = {
isInitiallyDisabled: false,
Expand Down Expand Up @@ -417,21 +419,17 @@ describe('Multiple Reference Editor', () => {

describe(`behaviour on external changes`, () => {
function updateEntry(entry: Entry, title: string) {
cy.get('@fixtures')
.its('pubsub')
.then((pubsub: PubsubFake) => {
const updatedEntry = modifyEntry(entry, {
'sys.version': entry.sys.version + 2,
'fields.exField.en-US': title,
});
pubsub.send('Entry', updatedEntry.sys.id, updatedEntry);
cy.getComponentFixtures().then(({ pubsub }) => {
const updatedEntry = modifyEntry(entry, {
'sys.version': entry.sys.version + 2,
'fields.exField.en-US': title,
});
pubsub.entityChanged('Entry', updatedEntry.sys.id, updatedEntry);
});
}

function localMount(entry: Entry, props?: ReferenceEditorSdkProps) {
const store = createDefaultFakeStore();
function localMount(entry: Entry, props?: ReferenceEditorFakeSdkProps) {
const sdk = createReferenceEditorTestSdk({
store,
initialValue: [asLink(entry)],
...props,
});
Expand Down Expand Up @@ -475,4 +473,63 @@ describe('Multiple Reference Editor', () => {
cy.findByText(updatedTitle);
});
});

describe(`behaviour on slideInNavigation`, () => {
function updateAndSlideIn(entry: Entry, title: string, slide: NavigatorSlideInfo) {
cy.getComponentFixtures().then(({ store, navigator }) => {
const updatedEntry = modifyEntry(entry, {
'sys.version': entry.sys.version + 2,
'fields.exField.en-US': title,
});
store.set('Entry', updatedEntry.sys.id, updatedEntry);
navigator.slideIn(slide);
});
}

function localMount(entry: Entry) {
const sdk = createReferenceEditorTestSdk({
initialValue: [asLink(entry)],
modifier: (sdk) => {
// @ts-expect-error ...
sdk.space.onEntityChanged = undefined;
return sdk;
},
});
mount(
<MultipleEntryReferenceEditor
{...commonProps}
hasCardEditActions={false}
hasCardMoveActions={false}
hasCardRemoveActions={false}
isInitiallyDisabled={false}
sdk={sdk}
/>
);
}

it(`updates cards if slide is closed`, () => {
const entry = fixtures.entries.published;
const initialTitle = entry.fields.exField['en-US'];
const updatedTitle = initialTitle + ' [updated]';

localMount(entry);

cy.findByText(initialTitle);
updateAndSlideIn(entry, updatedTitle, { oldSlideLevel: 2, newSlideLevel: 1 });
cy.findByText(updatedTitle);
});

it(`does not update cards if slide is opened`, () => {
const entry = fixtures.entries.published;
const initialTitle = entry.fields.exField['en-US'];
const updatedTitle = initialTitle + ' [updated]';

localMount(entry);

cy.findByText(initialTitle);
updateAndSlideIn(entry, updatedTitle, { oldSlideLevel: 1, newSlideLevel: 2 });
cy.findByText(updatedTitle).should('not.exist');
cy.findByText(initialTitle).should('exist');
});
});
});
17 changes: 13 additions & 4 deletions cypress/component/reference/MultipleMediaEditor.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';

import { Card, Heading, Button, Asset } from '@contentful/f36-components';
import { Asset, Button, Card, Heading } from '@contentful/f36-components';
import { AssetProps } from 'contentful-management';

import { MultipleMediaEditor, CombinedLinkActions } from '../../../packages/reference/src';
import { CombinedLinkActions, MultipleMediaEditor } from '../../../packages/reference/src';
import { createReferenceEditorTestSdk, fixtures } from '../../fixtures';
import { mount } from '../mount';
import { createReferenceEditorTestSdk } from '../test-sdks';

const commonProps = {
isInitiallyDisabled: false,
Expand Down Expand Up @@ -42,7 +43,15 @@ describe('Multiple Media Editor', () => {
});

it('can insert new links', () => {
const sdk = createReferenceEditorTestSdk();
const sdk = createReferenceEditorTestSdk({
modifier: (sdk) => {
sdk.navigator.openNewAsset = async () => ({
navigated: true,
entity: fixtures.assets.empty as AssetProps,
});
return sdk;
},
});
mount(<MultipleMediaEditor {...commonProps} sdk={sdk} />);

findCreateAndLinkBtn().click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';

import { MultipleResourceReferenceEditor } from '../../../packages/reference/src';
import { Entity, ResourceLink } from '../../../packages/reference/src/types';
import { createReferenceEditorTestSdk, fixtures } from '../../fixtures';
import { mount } from '../mount';
import { createReferenceEditorTestSdk, fixtures } from '../test-sdks';

function asLink<E extends Entity>(entity: E): ResourceLink {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';

import { SingleResourceReferenceEditor } from '../../../packages/reference/src';
import { Entity, ResourceLink } from '../../../packages/reference/src/types';
import { createReferenceEditorTestSdk, fixtures } from '../../fixtures';
import { mount } from '../mount';
import { createReferenceEditorTestSdk, fixtures } from '../test-sdks';

function asLink<E extends Entity>(entity: E): ResourceLink {
return {
Expand Down
10 changes: 0 additions & 10 deletions cypress/component/test-sdks.ts

This file was deleted.

63 changes: 21 additions & 42 deletions cypress/fixtures/FakeSdk.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
import { ContentType, FieldAPI, FieldExtensionSDK, Link } from '@contentful/app-sdk';
import type { ContentType, FieldAPI, FieldExtensionSDK } from '@contentful/app-sdk';
import {
createFakeCMAAdapter,
createFakeFieldAPI,
createFakeLocalesAPI,
createFakeSpaceAPI,
} from '@contentful/field-editor-test-utils';
import type { Emitter } from 'mitt';
import type { LocaleProps } from 'contentful-management';

import { assets, entries } from '../../packages/reference/src/__fixtures__/fixtures';
import { createFakeNavigatorAPI } from './navigator';
import { createFakePubsub } from './pubsub';
import { createDefaultFakeStore, Store } from './store';
import { newLink } from './utils';

const newLink = (linkType: string, id: string): Link => ({
sys: {
id,
linkType,
type: 'Link',
},
});

// used for component testing
export type ReferenceEditorSdkProps = {
export type ReferenceEditorFakeSdkProps = {
store?: Store;
ids?: Partial<FieldExtensionSDK['ids']>;
initialValue?: unknown;
validations?: unknown;
validations?: FieldAPI['validations'];
fetchDelay?: number;
modifier?: (sdk: FieldExtensionSDK) => FieldExtensionSDK;
};

export function newReferenceEditorFakeSdk(
props?: ReferenceEditorSdkProps
): [FieldExtensionSDK, Emitter] {
export function createReferenceEditorTestSdk(
props?: ReferenceEditorFakeSdkProps
): FieldExtensionSDK {
const store = props?.store ?? createDefaultFakeStore();
const rawInitialValue = window.localStorage.getItem('initialValue');
const initialValue = rawInitialValue ? JSON.parse(rawInitialValue) : props?.initialValue;
const rawValidations = window.localStorage.getItem('fieldValidations');
const validations = rawValidations ? JSON.parse(rawValidations) : props?.validations;
const initialValue = props?.initialValue;
const validations = props?.validations;
const customizeMock = (field: FieldAPI): FieldAPI => {
return validations ? { ...field, validations } : field;
};
const [field, mitt] = createFakeFieldAPI(customizeMock, initialValue);
const [field] = createFakeFieldAPI(customizeMock, initialValue);
const [pubsub, onEntityChanged] = createFakePubsub();
// TODO should go to space API
const [navigator, navigatorEmitter] = createFakeNavigatorAPI();
const space = createFakeSpaceAPI((api) => {
return {
...api,
Expand Down Expand Up @@ -74,7 +68,7 @@ export function newReferenceEditorFakeSdk(
}));
};

const sdk = {
const localSdk = {
field,
locales,
cmaAdapter: createFakeCMAAdapter({
Expand Down Expand Up @@ -108,7 +102,7 @@ export function newReferenceEditorFakeSdk(
},
Locale: {
getMany: async () => {
const items = store.getAll('Locale');
const items = store.getAll<LocaleProps>('Locale');
const total = items.length;

return {
Expand Down Expand Up @@ -160,23 +154,7 @@ export function newReferenceEditorFakeSdk(
return selectorCounter % 2 ? entryLinks.slice(0, 2) : [entryLinks[2]];
},
},
navigator: {
openNewAsset: async () => ({
entity: newLink('Asset', assets.empty.sys.id),
}),
openAsset: async () => {
alert('open Asset in slide in');
return {};
},
openNewEntry: async () => ({
entity: newLink('Entry', entries.empty.sys.id),
}),
openEntry: async () => {
alert('open entry in slide in');
return {};
},
onSlideInNavigation: () => () => ({}),
},
navigator,
access: {
can: async () => true,
},
Expand All @@ -185,8 +163,9 @@ export function newReferenceEditorFakeSdk(
environment: 'environment-id',
},
} as unknown as FieldExtensionSDK;
const sdk = props?.modifier?.(localSdk) ?? localSdk;

cy.wrap({ store, pubsub }).as('fixtures');
cy.wrap({ store, pubsub, navigator: navigatorEmitter }).as('componentFixtures');

return [sdk, mitt];
return sdk;
}
13 changes: 13 additions & 0 deletions cypress/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
import { NavigatorAPIEmitter } from './navigator';
import { PubsubEmitter } from './pubsub';
import { Store } from './store';

export * from './FakeSdk';
export * as fixtures from '../../packages/reference/src/__fixtures__/fixtures';
export * from './pubsub';
export * from './store';
export * as utils from './utils';

export type ComponentFixtures = {
store: Store;
pubsub: PubsubEmitter;
navigator: NavigatorAPIEmitter;
};
38 changes: 38 additions & 0 deletions cypress/fixtures/navigator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { NavigatorAPI, NavigatorSlideInfo } from '@contentful/app-sdk';
import mitt from 'mitt';

export type NavigatorAPIEmitter = {
slideIn: (slide: NavigatorSlideInfo) => void;
};

export function createFakeNavigatorAPI(): [NavigatorAPI, NavigatorAPIEmitter] {
const localEmitter = mitt();
const navigatorEmitter: NavigatorAPIEmitter = {
slideIn: (slide) => localEmitter.emit('onSlideInNavigation', slide),
};

const api = {
openNewAsset: async () => ({
navigated: false,
}),
openAsset: async () => ({
navigated: false,
}),
openNewEntry: async () => ({
navigated: false,
}),
openEntry: async () => ({
navigated: false,
}),
onSlideInNavigation: (handler) => {
const type = `onSlideInNavigation`;
localEmitter.on(type, handler);

return () => {
localEmitter.off(type, handler);
};
},
} as unknown as NavigatorAPI;

return [api, navigatorEmitter];
}
10 changes: 5 additions & 5 deletions cypress/fixtures/pubsub.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mitt from 'mitt';

export type PubsubFake = {
send: (entityType: string, entityId: string, data: unknown) => void;
export type PubsubEmitter = {
entityChanged: (entityType: string, entityId: string, data: unknown) => void;
};

export type OnEntityChanged = (
Expand All @@ -10,10 +10,10 @@ export type OnEntityChanged = (
handler: (data: unknown) => void
) => void;

export function createFakePubsub(): [PubsubFake, OnEntityChanged] {
export function createFakePubsub(): [PubsubEmitter, OnEntityChanged] {
const emitter = mitt();
const pubsub: PubsubFake = {
send: (entityType, entityId, data) =>
const pubsub: PubsubEmitter = {
entityChanged: (entityType, entityId, data) =>
emitter.emit(`entityChanged.${entityType}.${entityId}`, data),
};

Expand Down
9 changes: 9 additions & 0 deletions cypress/fixtures/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Link } from '@contentful/app-sdk';

export const newLink = (linkType: string, id: string): Link => ({
sys: {
id,
linkType,
type: 'Link',
},
});
4 changes: 4 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,7 @@ Cypress.Commands.add('mockGoogleMapsResponse', (mockData) => {
request.reply(`${callbackParam} && ${callbackParam}(${JSON.stringify(mockData)})`);
});
});

Cypress.Commands.add('getComponentFixtures', () => {
return cy.get('@componentFixtures');
});
Loading