Add test to check relations inside components are transferred

This commit is contained in:
Christian Capeans 2023-07-31 13:02:53 +02:00
parent b8add03505
commit 1c1d77d5f0

View File

@ -3,6 +3,7 @@ import { cloneDeep } from 'lodash/fp';
import { Readable, Writable } from 'stream-chain'; import { Readable, Writable } from 'stream-chain';
import type { Schema } from '@strapi/strapi'; import type { Schema } from '@strapi/strapi';
import { createTransferEngine, TRANSFER_STAGES } from '..'; import { createTransferEngine, TRANSFER_STAGES } from '..';
import type { import type {
IAsset, IAsset,
IConfiguration, IConfiguration,
@ -20,6 +21,27 @@ import {
const getMockSourceStream = (data: Iterable<unknown>) => Readable.from(data); const getMockSourceStream = (data: Iterable<unknown>) => Readable.from(data);
const defaultLinksData: Array<ILink> = [
{
kind: 'relation.basic',
relation: 'oneToOne',
left: { type: 'api::foo.foo', ref: 1, field: 'foo' },
right: { type: 'api::bar.bar', ref: 2, field: 'bar' },
},
{
kind: 'relation.basic',
relation: 'oneToMany',
left: { type: 'api::foo.foo', ref: 1, field: 'foos' },
right: { type: 'api::bar.bar', ref: 2, field: 'bar' },
},
{
kind: 'relation.basic',
relation: 'oneToMany',
left: { type: 'basic.foo', field: 'foo', ref: 1 },
right: { type: 'api::foo.foo', ref: 1 },
},
];
const schemas = { const schemas = {
'admin::permission': { 'admin::permission': {
collectionName: 'admin_permissions', collectionName: 'admin_permissions',
@ -143,6 +165,63 @@ const schemas = {
uid: 'api::homepage.homepage', uid: 'api::homepage.homepage',
globalId: 'Homepage', globalId: 'Homepage',
}, },
'api::bar.bar': {
kind: 'collectionType',
collectionName: 'bars',
modelType: 'contentType',
info: {
singularName: 'bar',
pluralName: 'bars',
displayName: 'bar',
description: '',
},
options: {
draftAndPublish: true,
},
pluginOptions: {},
attributes: {
bar: {
type: 'integer',
},
foo: {
displayName: 'foo',
type: 'component',
repeatable: false,
component: 'basic.foo',
},
},
},
'api::foo.foo': {
kind: 'collectionType',
collectionName: 'foos',
modelType: 'contentType',
info: {
singularName: 'foo',
pluralName: 'foos',
displayName: 'foo',
},
options: {
draftAndPublish: true,
},
pluginOptions: {},
attributes: {
foo: {
type: 'string',
},
},
},
'basic.foo': {
collectionName: 'components_basic_foos',
info: { displayName: 'Good Basic' },
options: {},
attributes: {
foo: { type: 'relation', relation: 'oneToOne', target: 'api::foo.foo' },
},
modelType: 'component',
modelName: 'foo-basic',
uid: 'basic.foo',
globalId: 'ComponentBasicFoo',
},
}; };
type Entity = IEntity< type Entity = IEntity<
@ -158,22 +237,8 @@ const getEntitiesMockSourceStream = (
] ]
) => getMockSourceStream(data); ) => getMockSourceStream(data);
const getLinksMockSourceStream = ( const getLinksMockSourceStream = (data: Array<ILink> = defaultLinksData) =>
data: Array<ILink> = [ getMockSourceStream(data);
{
kind: 'relation.basic',
relation: 'oneToOne',
left: { type: 'api::foo.foo', ref: 1, field: 'foo' },
right: { type: 'api::bar.bar', ref: 2, field: 'bar' },
},
{
kind: 'relation.basic',
relation: 'oneToMany',
left: { type: 'api::foo.foo', ref: 1, field: 'foos' },
right: { type: 'api::bar.bar', ref: 2, field: 'bar' },
},
]
) => getMockSourceStream(data);
const getAssetsMockSourceStream = ( const getAssetsMockSourceStream = (
data: Iterable<IAsset> = [ data: Iterable<IAsset> = [
@ -228,10 +293,13 @@ const getSchemasMockSourceStream = (
] ]
) => getMockSourceStream(data); ) => getMockSourceStream(data);
const getMockDestinationStream = () => { const getMockDestinationStream = (listener?) => {
const stream = new Writable({ const stream = new Writable({
objectMode: true, objectMode: true,
write(chunk, encoding, callback) { write(chunk, encoding, callback) {
if (listener) {
listener(chunk);
}
callback(); callback();
}, },
}); });
@ -279,7 +347,9 @@ const createSource = (streamData?: {
}; };
}; };
const createDestination = (): IDestinationProvider => { const createDestination = (
overrideOptions?: Partial<IDestinationProvider>
): IDestinationProvider => {
return { return {
type: 'destination', type: 'destination',
name: 'completeDestination', name: 'completeDestination',
@ -288,12 +358,12 @@ const createDestination = (): IDestinationProvider => {
bootstrap: jest.fn(), bootstrap: jest.fn(),
close: jest.fn(), close: jest.fn(),
createEntitiesWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()), createEntitiesWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()),
createLinksWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()), createLinksWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()),
createAssetsWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()), createAssetsWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()),
createConfigurationWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()), createConfigurationWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()),
createSchemasWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()), createSchemasWriteStream: jest.fn().mockResolvedValue(getMockDestinationStream()),
...overrideOptions,
}; };
}; };
@ -320,8 +390,8 @@ describe('Transfer engine', () => {
exclude: [], exclude: [],
} as unknown as ITransferEngineOptions; } as unknown as ITransferEngineOptions;
let completeSource; let completeSource: ISourceProvider;
let completeDestination; let completeDestination: IDestinationProvider;
beforeEach(() => { beforeEach(() => {
jest.restoreAllMocks(); jest.restoreAllMocks();
@ -444,7 +514,7 @@ describe('Transfer engine', () => {
// Two values are emitted by default for each stage // Two values are emitted by default for each stage
// TODO: this is no longer true, we should be checking the sum of the various mocked streams // TODO: this is no longer true, we should be checking the sum of the various mocked streams
const itemPerStage = 2; const itemPerStage = 3;
expect(calls).toEqual((sourceStages.length - providerStages.length) * itemPerStage); expect(calls).toEqual((sourceStages.length - providerStages.length) * itemPerStage);
}); });
@ -501,6 +571,24 @@ describe('Transfer engine', () => {
expect(calls).toEqual(3); // 3 deleted stages above expect(calls).toEqual(3); // 3 deleted stages above
}); });
test('relations inside components are transferred', async () => {
const processedLinks: ILink[] = [];
completeDestination = createDestination({
createLinksWriteStream: jest.fn().mockResolvedValue(
getMockDestinationStream((chunk: ILink) => {
processedLinks.push(chunk);
})
),
});
const engine = createTransferEngine(completeSource, completeDestination, defaultOptions);
await engine.transferLinks();
expect(completeDestination.createLinksWriteStream).toHaveBeenCalled();
expect(processedLinks).toStrictEqual(defaultLinksData);
});
}); });
describe('integrity checks', () => { describe('integrity checks', () => {