Skip to content

Commit

Permalink
Merge pull request #44 from shopware/fix-test-data-cleanup
Browse files Browse the repository at this point in the history
fix: Improved data cleanup of TestDataService
  • Loading branch information
Phil23 authored Jun 27, 2024
2 parents 5446907 + b7c2d3c commit 1eca596
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 38 deletions.
21 changes: 0 additions & 21 deletions src/fixtures/ApiContexts.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { test as base } from '@playwright/test';
import { AdminApiContext } from '../services/AdminApiContext';
import { StoreApiContext } from '../services/StoreApiContext';
import { TestDataService } from '../services/TestDataService';
import type { FixtureTypes } from '../types/FixtureTypes';

export interface ApiContextTypes {
AdminApiContext: AdminApiContext;
StoreApiContext: StoreApiContext;
TestDataService: TestDataService;
}

export const test = base.extend<NonNullable<unknown>, FixtureTypes>({
Expand All @@ -32,23 +30,4 @@ export const test = base.extend<NonNullable<unknown>, FixtureTypes>({
},
{ scope: 'worker' },
],

TestDataService: [
async ({ AdminApiContext, IdProvider, DefaultSalesChannel, SalesChannelBaseConfig }, use) => {
const DataService = new TestDataService(AdminApiContext, IdProvider, {
defaultSalesChannel: DefaultSalesChannel.salesChannel,
defaultTaxId: SalesChannelBaseConfig.taxId,
defaultCurrencyId: SalesChannelBaseConfig.defaultCurrencyId,
defaultCategoryId: DefaultSalesChannel.salesChannel.navigationCategoryId,
defaultLanguageId: DefaultSalesChannel.salesChannel.languageId,
defaultCountryId: DefaultSalesChannel.salesChannel.countryId,
defaultCustomerGroupId: DefaultSalesChannel.salesChannel.customerGroupId,
})

await use(DataService);

await DataService.cleanUp();
},
{ scope: 'worker' },
],
});
26 changes: 26 additions & 0 deletions src/fixtures/TestData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test as base } from '@playwright/test';
import { TestDataService } from '../services/TestDataService';
import type { FixtureTypes } from '../types/FixtureTypes';

export interface TestDataFixtureTypes {
TestDataService: TestDataService;
}

export const test = base.extend<FixtureTypes>({

TestDataService: async ({ AdminApiContext, IdProvider, DefaultSalesChannel, SalesChannelBaseConfig }, use) => {
const DataService = new TestDataService(AdminApiContext, IdProvider, {
defaultSalesChannel: DefaultSalesChannel.salesChannel,
defaultTaxId: SalesChannelBaseConfig.taxId,
defaultCurrencyId: SalesChannelBaseConfig.defaultCurrencyId,
defaultCategoryId: DefaultSalesChannel.salesChannel.navigationCategoryId,
defaultLanguageId: DefaultSalesChannel.salesChannel.languageId,
defaultCountryId: DefaultSalesChannel.salesChannel.countryId,
defaultCustomerGroupId: DefaultSalesChannel.salesChannel.customerGroupId,
})

await use(DataService);

await DataService.cleanUp();
},
});
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { test as DefaultSalesChannel } from './fixtures/DefaultSalesChannel';
import { test as ApiContexts } from './fixtures/ApiContexts';
import { test as PageContexts } from './fixtures/PageContexts';
import { test as Actors } from './fixtures/Actors';
import { test as TestData } from './fixtures/TestData';
import { test as HelperFixtures } from './fixtures/HelperFixtures';
import { test as StorefrontPages } from './page-objects/StorefrontPages';
import { test as AdministrationPages } from './page-objects/AdministrationPages';
Expand Down Expand Up @@ -30,6 +31,7 @@ export const test = mergeTests(
ApiContexts,
PageContexts,
Actors,
TestData,
StorefrontPages,
AdministrationPages,
DataFixtures,
Expand Down
79 changes: 62 additions & 17 deletions src/services/TestDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {

export interface CreatedRecord {
resource: string;
id: string;
payload: Record<string, string>;
}

export interface SimpleLineItem {
Expand Down Expand Up @@ -65,10 +65,30 @@ export class TestDataService {
public readonly defaultCountryId: string;
public readonly defaultCustomerGroupId: string;

/**
* Configures if an automated cleanup of the data should be executed.
*
* @private
*/
private shouldCleanUp = true;

/**
* Configuration of higher priority entities for the cleanup operation.
* These entities will be deleted before others.
* This will prevent restricted delete operations of associated entities.
*
* @private
*/
private highPriorityEntities = ['order', 'product'];

/**
* A registry of all created records.
*
* @private
*/
private createdRecords: CreatedRecord[] = [];


constructor(AdminApiClient: AdminApiContext, IdProvider: IdProvider, options: DataServiceOptions) {
this.AdminApiClient = AdminApiClient;
this.IdProvider = IdProvider;
Expand Down Expand Up @@ -166,9 +186,7 @@ export class TestDataService {
const product = await this.createBasicProduct(overrides, taxId, currencyId);
const media = await this.createMediaTXT(content);

const productDownload = await this.assignProductDownload(product.id, media.id);

this.addCreatedRecord('product-download', productDownload.id);
await this.assignProductDownload(product.id, media.id);

return product;
}
Expand Down Expand Up @@ -323,7 +341,7 @@ export class TestDataService {

const { data: propertyGroup } = (await propertyGroupResponse.json()) as { data: PropertyGroup };

this.addCreatedRecord('property-group', propertyGroup.id);
this.addCreatedRecord('property_group', propertyGroup.id);

return propertyGroup;
}
Expand Down Expand Up @@ -358,7 +376,7 @@ export class TestDataService {

const { data: propertyGroup } = (await propertyGroupResponse.json()) as { data: PropertyGroup };

this.addCreatedRecord('property-group', propertyGroup.id);
this.addCreatedRecord('property_group', propertyGroup.id);

return propertyGroup;
}
Expand Down Expand Up @@ -785,10 +803,19 @@ export class TestDataService {
* All entities added to the registry will be deleted by the cleanup call.
*
* @param resource - The resource name of the entity.
* @param id - The uuid of the entity.
* @param payload - You can pass a payload object for the delete operation or simply pass the uuid of the entity.
*/
addCreatedRecord(resource: string, id: string) {
this.createdRecords.push({ resource, id });
addCreatedRecord(resource: string, payload: string | Record<string, string>) {
const res = resource.replace('-', '_');

if (typeof payload === 'string') {
this.createdRecords.push({
resource: res,
payload: { id: payload },
});
} else {
this.createdRecords.push({ resource: res, payload });
}
}

/**
Expand All @@ -809,23 +836,41 @@ export class TestDataService {
return Promise.reject();
}

const priorityDeleteOperations: Record<string, SyncApiOperation> = {};
const deleteOperations: Record<string, SyncApiOperation> = {};

this.createdRecords.forEach((record) => {
if (!deleteOperations[`delete-${record.resource}`]) {
deleteOperations[`delete-${record.resource}`] = {
entity: record.resource,
action: 'delete',
payload: [],
};
if (this.highPriorityEntities.includes(record.resource)) {
if (!priorityDeleteOperations[`delete-${record.resource}`]) {
priorityDeleteOperations[`delete-${record.resource}`] = {
entity: record.resource,
action: 'delete',
payload: [],
};
}

priorityDeleteOperations[`delete-${record.resource}`].payload.push(record.payload);

} else {
if (!deleteOperations[`delete-${record.resource}`]) {
deleteOperations[`delete-${record.resource}`] = {
entity: record.resource,
action: 'delete',
payload: [],
};
}

deleteOperations[`delete-${record.resource}`].payload.push(record.payload);
}
});

deleteOperations[`delete-${record.resource}`].payload.push({ id: record.id });
await this.AdminApiClient.post('_action/sync', {
data: priorityDeleteOperations,
});

return await this.AdminApiClient.post('_action/sync', {
data: deleteOperations,
})
});
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/types/FixtureTypes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ApiContextTypes } from '../fixtures/ApiContexts';
import { PageContextTypes } from '../fixtures/PageContexts';
import { ActorFixtureTypes } from '../fixtures/Actors';
import { TestDataFixtureTypes } from '../fixtures/TestData';
import { HelperFixtureTypes } from '../fixtures/HelperFixtures';
import { DefaultSalesChannelTypes } from '../fixtures/DefaultSalesChannel';
import { StorefrontPageTypes } from '../page-objects/StorefrontPages';
Expand All @@ -11,6 +12,7 @@ export interface FixtureTypes extends
ApiContextTypes,
PageContextTypes,
ActorFixtureTypes,
TestDataFixtureTypes,
HelperFixtureTypes,
DefaultSalesChannelTypes,
StorefrontPageTypes,
Expand Down
17 changes: 17 additions & 0 deletions tests/TestDataService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ test('Data Service', async ({
expect(product.description).toEqual('Test Description');
expect(product.coverId).toBeDefined();

const digitalProduct = await TestDataService.createDigitalProduct('Test Test', { description: 'You can download me.' });
expect(digitalProduct.description).toEqual('You can download me.');

const propertyGroup = await TestDataService.createColorPropertyGroup();
expect(propertyGroup.description).toEqual('Color');

const customer = await TestDataService.createCustomer({ firstName: 'Luke', lastName: 'Skywalker' })
expect(customer.firstName).toEqual('Luke');
expect(customer.lastName).toEqual('Skywalker');
Expand All @@ -22,4 +28,15 @@ test('Data Service', async ({
expect(order.orderNumber).toEqual('123456789');
expect(order.orderCustomer.firstName).toEqual('Luke');
expect(order.price.totalPrice).toEqual(58.99);

// Data Clean-Up
const cleanUpResponse = await TestDataService.cleanUp();
expect(cleanUpResponse.ok()).toBeTruthy();

const cleanUp = await cleanUpResponse.json();
expect(cleanUp['notFound'].length).toBe(0);
expect(cleanUp['deleted']['category']).toBeDefined();
expect(cleanUp['deleted']['media']).toBeDefined();
expect(cleanUp['deleted']['property_group']).toBeDefined();
expect(cleanUp['deleted']['customer']).toBeDefined();
});

0 comments on commit 1eca596

Please sign in to comment.