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

feat: add analytics assignment and creation of sales channel analytics #212

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
129 changes: 119 additions & 10 deletions src/services/TestDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ import type {
Country,
CustomerGroup,
SystemConfig,
SalesChannelAnalytics,
} from '../types/ShopwareTypes';
import { expect } from '@playwright/test';

export interface SalesChannelRecord {
salesChannelId: string;
field: string;
}
frobel marked this conversation as resolved.
Show resolved Hide resolved

export interface CreatedRecord {
resource: string;
payload: Record<string, string>;
Expand Down Expand Up @@ -91,7 +97,7 @@ export class TestDataService {
*
* @private
*/
private highPriorityEntities = ['order', 'product', 'landing_page'];
private highPriorityEntities = ['order', 'product', 'landing_page', 'sales_channel_currency', 'sales_channel_country'];

/**
* A registry of all created records.
Expand All @@ -100,6 +106,13 @@ export class TestDataService {
*/
private createdRecords: CreatedRecord[] = [];

/**
* A registry of all created sales channel records.
*
* @private
*/
private createdSalesChannelRecords: SalesChannelRecord[] = [];


constructor(AdminApiClient: AdminApiContext, IdProvider: IdProvider, options: DataServiceOptions) {
this.AdminApiClient = AdminApiClient;
Expand Down Expand Up @@ -882,6 +895,30 @@ export class TestDataService {
return systemConfigEntry;
}

/**
* Creates a random sales channel analytics entity
*
* @param overrides - Specific data overrides that will be applied to the sales channel analytics data struct.
*/
async createSalesChannelAnalytics(
overrides: Partial<SalesChannelAnalytics> = {},
): Promise<SalesChannelAnalytics> {

const basicSalesChannelAnalyticsStruct = this.getSalesChannelAnalyticsStruct(overrides);


const response = await this.AdminApiClient.post('sales-channel-analytics?_response=detail', {
data: basicSalesChannelAnalyticsStruct,
});
expect(response.ok()).toBeTruthy();

const { data: salesChannelAnalytics } = (await response.json()) as { data: SalesChannelAnalytics };

this.addCreatedRecord('sales_channel_analytics', salesChannelAnalytics.id);

return salesChannelAnalytics;
}

/**
* Assigns a media resource as the download of a digital product.
*
Expand Down Expand Up @@ -1065,13 +1102,13 @@ export class TestDataService {

const syncSalesChannelResponse = await this.AdminApiClient.post('./_action/sync', {
data: {
'write-sales-channel': {
entity: 'sales_channel',
'write-sales-channel-currency': {
entity: 'sales_channel_currency',
action: 'upsert',
payload: [
{
id: salesChannelId,
currencies: [{ id: currencyId }],
salesChannelId: salesChannelId,
currencyId: currencyId,
},
],
},
Expand All @@ -1081,6 +1118,39 @@ export class TestDataService {

const { data: salesChannel } = await syncSalesChannelResponse.json();

this.addCreatedRecord('sales_channel_currency', {salesChannelId: salesChannelId, currencyId: currencyId})

return salesChannel;
}

/**
* Assigns a sales channel analytics entity to a sales channel.
*
* @param salesChannelId - The uuid of the sales channel.
* @param salesChannelAnalyticsId - The uuid of the sales channel analytics entity.
*/
async assignSalesChannelAnalytics(salesChannelId: string, salesChannelAnalyticsId: string) {

const syncSalesChannelResponse = await this.AdminApiClient.post('./_action/sync', {
data: {
'write-sales-channel-analytics': {
entity: 'sales_channel_analytics',
action: 'upsert',
payload: [
{
salesChannel: { id: salesChannelId },
id: salesChannelAnalyticsId,
},
],
},
},
});
expect(syncSalesChannelResponse.ok()).toBeTruthy();

const { data: salesChannel } = (await syncSalesChannelResponse.json()) as { data: SalesChannel};

this.addCreatedSalesChannelRecord(salesChannelId, 'analyticsId');

return salesChannel;
}

Expand All @@ -1094,13 +1164,13 @@ export class TestDataService {

const syncSalesChannelResponse = await this.AdminApiClient.post('./_action/sync', {
data: {
'write-sales-channel': {
entity: 'sales_channel',
'write-sales-channel-country': {
entity: 'sales_channel_country',
action: 'upsert',
payload: [
{
id: salesChannelId,
countries: [{ id: countryId }],
salesChannelId: salesChannelId,
countryId: countryId,
},
],
},
Expand All @@ -1110,6 +1180,8 @@ export class TestDataService {

const { data: salesChannel } = await syncSalesChannelResponse.json();

this.addCreatedRecord('sales_channel_country', { salesChannelId: salesChannelId, countryId: countryId });

return salesChannel;
}

Expand Down Expand Up @@ -1414,6 +1486,17 @@ export class TestDataService {
}
}

/**
* Adds a sales channel related property to the registry of created sales channel records.
* The property added to the registry will be overridden with null value by the cleanup call.
*
* @param salesChannelId - The sales channel id where the property pair is located
* @param field - The database field which has to be overridden
*/
addCreatedSalesChannelRecord(salesChannelId: string, field: string) {
this.createdSalesChannelRecords.push({ salesChannelId: salesChannelId, field: field });
}

/**
* Set the configuration of automated data clean up.
* If set to "true" the data service will delete all entities created by it.
Expand All @@ -1432,8 +1515,20 @@ export class TestDataService {
return null;
}

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

if(this.createdSalesChannelRecords) {
for (const salesChannelRecord of this.createdSalesChannelRecords) {
const salesChannelResponse = await this.AdminApiClient.patch(`sales-channel/${salesChannelRecord.salesChannelId}`, {
data: {
[salesChannelRecord.field]: null,
},
});
expect(salesChannelResponse.ok()).toBeTruthy();
}
}


this.createdRecords.forEach((record) => {
if (this.highPriorityEntities.includes(record.resource)) {
Expand Down Expand Up @@ -2237,6 +2332,20 @@ export class TestDataService {
return Object.assign({}, basicCustomerGroup, overrides);
}

getSalesChannelAnalyticsStruct(overrides: Partial<SalesChannelAnalytics> = {}): Partial<SalesChannelAnalytics> {
const salesChannelAnalyticsUuid = this.IdProvider.getIdPair().uuid;
const trackingId = this.IdProvider.getIdPair().id;

const basicSalesChannelAnalyticsStruct = {
id: salesChannelAnalyticsUuid,
trackingId: trackingId,
active: true,
trackOrders: false,
anonymizeIp: true,
};
return Object.assign({}, basicSalesChannelAnalyticsStruct, overrides);
}

async clearCaches() {
await this.AdminApiClient.delete('_action/cache');
}
Expand Down
4 changes: 4 additions & 0 deletions src/types/ShopwareTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ export type CustomerGroup = components['schemas']['CustomerGroup'] & {
id: string,
};

export type SalesChannelAnalytics = components['schemas']['SalesChannelAnalytics'] & {
id: string,
};

export interface RegistrationData {
salutation: string;
firstName: string;
Expand Down
9 changes: 9 additions & 0 deletions tests/TestDataService/TestDataService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Category,
APIResponse,
SystemConfig,
SalesChannelAnalytics,
} from '../../src';

test('Data Service', async ({
Expand Down Expand Up @@ -90,6 +91,9 @@ test('Data Service', async ({
expect(systemConfigEntry.configurationKey).toEqual('test.random.foo');
expect(systemConfigEntry.configurationValue).toEqual(true);

const salesChannelAnalytics = await TestDataService.createSalesChannelAnalytics({ active: false });
expect(salesChannelAnalytics.active).toEqual(false);

// Test data clean-up with deactivated cleansing process
TestDataService.setCleanUp(false);
const cleanUpFalseResponse = await TestDataService.cleanUp();
Expand Down Expand Up @@ -143,6 +147,10 @@ test('Data Service', async ({
const { data: databaseSystemConfigEntry } = (await systemConfigEntryResponse.json()) as { data: SystemConfig };
expect(databaseSystemConfigEntry.id).toBe(systemConfigEntry.id);

const salesChannelAnalyticsResponse = await AdminApiContext.get(`./sales-channel-analytics/${salesChannelAnalytics.id}?_response=detail`);
const { data: databaseSalesChannelAnalytics } = (await salesChannelAnalyticsResponse.json()) as { data: SalesChannelAnalytics };
expect(databaseSalesChannelAnalytics.id).toBe(salesChannelAnalytics.id);

// Test data clean-up with activated cleansing process
TestDataService.setCleanUp(true);
const cleanUpResponse = await TestDataService.cleanUp() as APIResponse;
Expand All @@ -164,4 +172,5 @@ test('Data Service', async ({
expect(cleanUp['deleted']['product_manufacturer']).toBeDefined();
expect(cleanUp['deleted']['cms_page']).toBeDefined();
expect(cleanUp['deleted']['system_config']).toBeDefined();
expect(cleanUp['deleted']['sales_channel_analytics']).toBeDefined();
});
Loading