Skip to content

Commit

Permalink
OXDEV-8732 Add UserDataExport service implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Fedurtsya <anton@fedurtsya.com>
  • Loading branch information
Sieg committed Sep 25, 2024
1 parent fd7ab6d commit 223ca8c
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 21 deletions.
20 changes: 0 additions & 20 deletions src/UserData/Service/UserDataExportInterface.php

This file was deleted.

37 changes: 37 additions & 0 deletions src/UserData/Service/UserDataExportService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Service;

class UserDataExportService implements UserDataExportServiceInterface
{
public function __construct(
private CollectionAggregationServiceInterface $collectionAggregationService,
private CollectionSerializerServiceInterface $collectionSerializerService,
private ZipCreatorInterface $zipCreatorService,
) {
}

/**
* collects data from CollectionAggregationService as array of Collections
* iterate through collections and serialize them to ResultFileInterfaces array
* give this array of ResultFileInterfaces to the ZipCreatorInterface
*/
public function exportUserData(string $userId, string $outputZipFilePath): void
{
$tableDataCollections = $this->collectionAggregationService->collectUserData($userId);

$serializedFiles = [];
foreach ($tableDataCollections as $oneTableDataCollection) {
$serializedFiles[] = $this->collectionSerializerService->serializeCollection($oneTableDataCollection);
}

$this->zipCreatorService->createZip($serializedFiles, $outputZipFilePath);
}
}
15 changes: 15 additions & 0 deletions src/UserData/Service/UserDataExportServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\UserData\Service;

interface UserDataExportServiceInterface
{
public function exportUserData(string $userId, string $outputZipFilePath): void;
}
6 changes: 5 additions & 1 deletion src/UserData/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,8 @@ services:
$collectors: !tagged oe.gdpr.user_data

OxidEsales\GdprOptinModule\UserData\Service\CollectionSerializerServiceInterface:
class: OxidEsales\GdprOptinModule\UserData\Service\JsonCollectionSerializerService
class: OxidEsales\GdprOptinModule\UserData\Service\JsonCollectionSerializerService

# Cannot be added while ZipCreatorInterface not available yet
# OxidEsales\GdprOptinModule\UserData\Service\UserDataExportServiceInterface:
# class: OxidEsales\GdprOptinModule\UserData\Service\UserDataExportService
85 changes: 85 additions & 0 deletions tests/Unit/UserData/Service/UserDataExportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GdprOptinModule\Tests\Unit\UserData\Service;

use OxidEsales\GdprOptinModule\UserData\DataType\ResultFileInterface;
use OxidEsales\GdprOptinModule\UserData\DataType\TableDataCollectionInterface;
use OxidEsales\GdprOptinModule\UserData\Service\CollectionAggregationServiceInterface;
use OxidEsales\GdprOptinModule\UserData\Service\CollectionSerializerServiceInterface;
use OxidEsales\GdprOptinModule\UserData\Service\UserDataExportService;
use OxidEsales\GdprOptinModule\UserData\Service\UserDataExportServiceInterface;
use OxidEsales\GdprOptinModule\UserData\Service\ZipCreatorInterface;
use PHPUnit\Framework\TestCase;

class UserDataExportTest extends TestCase
{
public function testZipCreationServiceTriggeredWithCorrectlyProcessedData(): void
{
$userId = uniqid();
$outputZipFilePath = uniqid();

// Step1: data collection
$collectionAggregationServiceMock = $this->createMock(CollectionAggregationServiceInterface::class);
$collectionAggregationServiceMock->method('collectUserData')
->with($userId)->willReturn([
$tableCollection1Stub = $this->createStub(TableDataCollectionInterface::class),
$tableCollection2Stub = $this->createStub(TableDataCollectionInterface::class),
]);

// Step2: data serialization
$collectionSerializerServiceMock = $this->createMock(CollectionSerializerServiceInterface::class);
$resultFile1 = $this->createStub(ResultFileInterface::class);
$resultFile2 = $this->createStub(ResultFileInterface::class);
$collectionSerializerServiceMock->expects($matcher = $this->exactly(2))
->method('serializeCollection')
->willReturnCallback(function (TableDataCollectionInterface $tableCollection)
use ($matcher, $tableCollection1Stub, $tableCollection2Stub, $resultFile1, $resultFile2) {
match ($matcher->numberOfInvocations()) {
1 => $this->assertEquals($tableCollection1Stub, $tableCollection),
2 => $this->assertEquals($tableCollection2Stub, $tableCollection),
};

return match ($matcher->numberOfInvocations()) {
1 => $resultFile1,
2 => $resultFile2,
default => throw new \Exception('Unexpected match value'),
};
});

// Step3: zip creation
$zipCreatorServiceSpy = $this->createMock(ZipCreatorInterface::class);
$zipCreatorServiceSpy->expects($this->once())
->method('createZip')
->with([$resultFile1, $resultFile2], $outputZipFilePath);

$sut = $this->getSut(
collectionAggregationService: $collectionAggregationServiceMock,
collectionSerializerService: $collectionSerializerServiceMock,
zipCreatorService: $zipCreatorServiceSpy,
);

$sut->exportUserData($userId, $outputZipFilePath);
}

public function getSut(
CollectionAggregationServiceInterface $collectionAggregationService = null,
CollectionSerializerServiceInterface $collectionSerializerService = null,
ZipCreatorInterface $zipCreatorService = null,
): UserDataExportServiceInterface {
$collectionAggregationService ??= $this->createStub(CollectionAggregationServiceInterface::class);
$collectionSerializerService ??= $this->createStub(CollectionSerializerServiceInterface::class);

return new UserDataExportService(
collectionAggregationService: $collectionAggregationService,
collectionSerializerService: $collectionSerializerService,
zipCreatorService: $zipCreatorService ?? $this->createStub(ZipCreatorInterface::class),
);
}
}

0 comments on commit 223ca8c

Please sign in to comment.