aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/tests/integration/UserMigration/CalendarMigratorTest.php
blob: 0682733a10380b7bd058c7833b12bef7f21afecb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php

declare(strict_types=1);

/**
 * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

namespace OCA\DAV\Tests\integration\UserMigration;

use OCA\DAV\AppInfo\Application;
use OCA\DAV\UserMigration\CalendarMigrator;
use OCP\AppFramework\App;
use OCP\IUserManager;
use Sabre\VObject\Component as VObjectComponent;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Property as VObjectProperty;
use Sabre\VObject\Reader as VObjectReader;
use Sabre\VObject\UUIDUtil;
use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase;
use function scandir;

/**
 * @group DB
 */
class CalendarMigratorTest extends TestCase {

	private IUserManager $userManager;

	private CalendarMigrator $migrator;

	private OutputInterface $output;

	private const ASSETS_DIR = __DIR__ . '/assets/calendars/';

	protected function setUp(): void {
		$app = new App(Application::APP_ID);
		$container = $app->getContainer();

		$this->userManager = $container->get(IUserManager::class);
		$this->migrator = $container->get(CalendarMigrator::class);
		$this->output = $this->createMock(OutputInterface::class);
	}

	public static function dataAssets(): array {
		return array_map(
			function (string $filename) {
				/** @var VCalendar $vCalendar */
				$vCalendar = VObjectReader::read(
					fopen(self::ASSETS_DIR . $filename, 'r'),
					VObjectReader::OPTION_FORGIVING,
				);
				[$initialCalendarUri, $ext] = explode('.', $filename, 2);
				return [UUIDUtil::getUUID(), $filename, $initialCalendarUri, $vCalendar];
			},
			array_diff(
				scandir(self::ASSETS_DIR),
				// Exclude current and parent directories
				['.', '..'],
			),
		);
	}

	private function getProperties(VCalendar $vCalendar): array {
		return array_map(
			fn (VObjectProperty $property) => $property->serialize(),
			array_values(array_filter(
				$vCalendar->children(),
				fn ($child) => $child instanceof VObjectProperty,
			)),
		);
	}

	private function getComponents(VCalendar $vCalendar): array {
		return array_map(
			// Elements of the serialized blob are sorted
			fn (VObjectComponent $component) => $component->serialize(),
			$vCalendar->getComponents(),
		);
	}

	private function getSanitizedComponents(VCalendar $vCalendar): array {
		return array_map(
			// Elements of the serialized blob are sorted
			fn (VObjectComponent $component) => $this->invokePrivate($this->migrator, 'sanitizeComponent', [$component])->serialize(),
			$vCalendar->getComponents(),
		);
	}

	#[\PHPUnit\Framework\Attributes\DataProvider('dataAssets')]
	public function testImportExportAsset(string $userId, string $filename, string $initialCalendarUri, VCalendar $importCalendar): void {
		$user = $this->userManager->createUser($userId, 'topsecretpassword');

		$problems = $importCalendar->validate();
		$this->assertEmpty($problems);

		$this->invokePrivate($this->migrator, 'importCalendar', [$user, $filename, $initialCalendarUri, $importCalendar, $this->output]);

		$calendarExports = $this->invokePrivate($this->migrator, 'getCalendarExports', [$user, $this->output]);
		$this->assertCount(1, $calendarExports);

		/** @var VCalendar $exportCalendar */
		['vCalendar' => $exportCalendar] = reset($calendarExports);

		$this->assertEqualsCanonicalizing(
			$this->getProperties($importCalendar),
			$this->getProperties($exportCalendar),
		);

		$this->assertEqualsCanonicalizing(
			// Components are expected to be sanitized on import
			$this->getSanitizedComponents($importCalendar),
			$this->getComponents($exportCalendar),
		);
	}
}