1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Http\RequestHandlers; 21 22use Exception; 23use Fig\Http\Message\RequestMethodInterface; 24use Fig\Http\Message\StatusCodeInterface; 25use Fisharebest\Webtrees\Auth; 26use Fisharebest\Webtrees\Http\Exceptions\HttpServerErrorException; 27use Fisharebest\Webtrees\Services\GedcomExportService; 28use Fisharebest\Webtrees\Services\GedcomImportService; 29use Fisharebest\Webtrees\Services\TimeoutService; 30use Fisharebest\Webtrees\Services\TreeService; 31use Fisharebest\Webtrees\Services\UpgradeService; 32use Fisharebest\Webtrees\Services\UserService; 33use Fisharebest\Webtrees\TestCase; 34use Illuminate\Support\Collection; 35use Nyholm\Psr7\Factory\Psr17Factory; 36use PHPUnit\Framework\Attributes\CoversClass; 37 38#[CoversClass(UpgradeWizardStep::class)] 39class UpgradeWizardStepTest extends TestCase 40{ 41 protected static bool $uses_database = true; 42 43 public function testIgnoreStepInvalid(): void 44 { 45 $handler = new UpgradeWizardStep( 46 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 47 new TreeService(new GedcomImportService()), 48 new UpgradeService(new TimeoutService()) 49 ); 50 51 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Invalid']); 52 53 $response = $handler->handle($request); 54 55 self::assertSame(StatusCodeInterface::STATUS_NO_CONTENT, $response->getStatusCode()); 56 } 57 58 public function testStepCheckOK(): void 59 { 60 $mock_upgrade_service = $this->createMock(UpgradeService::class); 61 $mock_upgrade_service->method('latestVersion')->willReturn('999.999.999'); 62 $handler = new UpgradeWizardStep( 63 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 64 new TreeService(new GedcomImportService()), 65 $mock_upgrade_service 66 ); 67 68 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 69 $response = $handler->handle($request); 70 71 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 72 } 73 74 public function testStepCheckUnavailable(): void 75 { 76 $this->expectException(HttpServerErrorException::class); 77 78 $mock_upgrade_service = $this->createMock(UpgradeService::class); 79 $mock_upgrade_service->method('latestVersion')->willReturn(''); 80 $handler = new UpgradeWizardStep( 81 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 82 new TreeService(new GedcomImportService()), 83 $mock_upgrade_service 84 ); 85 86 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 87 $handler->handle($request); 88 } 89 90 public function testStepCheckFail(): void 91 { 92 $this->expectException(HttpServerErrorException::class); 93 94 $mock_upgrade_service = $this->createMock(UpgradeService::class); 95 $mock_upgrade_service->method('latestVersion')->willReturn('0.0.0'); 96 $handler = new UpgradeWizardStep( 97 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 98 new TreeService(new GedcomImportService()), 99 $mock_upgrade_service 100 ); 101 102 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 103 $handler->handle($request); 104 } 105 106 public function testStepPrepare(): void 107 { 108 $handler = new UpgradeWizardStep( 109 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 110 new TreeService(new GedcomImportService()), 111 new UpgradeService(new TimeoutService()) 112 ); 113 114 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Prepare']); 115 $response = $handler->handle($request); 116 117 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 118 } 119 120 public function testStepPending(): void 121 { 122 $handler = new UpgradeWizardStep( 123 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 124 new TreeService(new GedcomImportService()), 125 new UpgradeService(new TimeoutService()) 126 ); 127 128 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Pending']); 129 $response = $handler->handle($request); 130 131 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 132 } 133 134 public function testStepPendingExist(): void 135 { 136 $tree_service = new TreeService(new GedcomImportService()); 137 $tree = $tree_service->create('name', 'title'); 138 $user = (new UserService())->create('user', 'name', 'email', 'password'); 139 140 Auth::login($user); 141 $tree->createIndividual("0 @@ INDI\n1 NAME Joe Bloggs"); 142 143 $handler = new UpgradeWizardStep( 144 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 145 new TreeService(new GedcomImportService()), 146 new UpgradeService(new TimeoutService()) 147 ); 148 149 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Pending']); 150 $response = $handler->handle($request); 151 152 self::assertSame(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, $response->getStatusCode()); 153 } 154 155 public function testStepExport(): void 156 { 157 $tree = $this->importTree('demo.ged'); 158 $all_trees = Collection::make([$tree->name() => $tree]); 159 $tree_service = $this->createMock(TreeService::class); 160 $tree_service->method('all')->willReturn($all_trees); 161 162 $handler = new UpgradeWizardStep( 163 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 164 $tree_service, 165 new UpgradeService(new TimeoutService()) 166 ); 167 168 $request = self::createRequest()->withQueryParams(['step' => 'Export', 'tree' => $tree->name()]); 169 $response = $handler->handle($request); 170 171 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 172 173 // Now overwrite the file we just created 174 $response = $handler->handle($request); 175 176 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 177 } 178 179 public function testStepDownloadFails(): void 180 { 181 $this->expectException(HttpServerErrorException::class); 182 183 $mock_upgrade_service = $this->createMock(UpgradeService::class); 184 $mock_upgrade_service->method('downloadFile')->will(self::throwException(new Exception())); 185 $handler = new UpgradeWizardStep( 186 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 187 new TreeService(new GedcomImportService()), 188 $mock_upgrade_service 189 ); 190 191 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Download']); 192 $handler->handle($request); 193 } 194 195 public function testStepDownload(): void 196 { 197 $mock_upgrade_service = $this->createMock(UpgradeService::class); 198 $mock_upgrade_service->method('downloadFile')->willReturn(123456); 199 $handler = new UpgradeWizardStep( 200 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 201 new TreeService(new GedcomImportService()), 202 $mock_upgrade_service 203 ); 204 205 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Download']); 206 $response = $handler->handle($request); 207 208 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 209 } 210 211 public function testStepUnzip(): void 212 { 213 $mock_upgrade_service = $this->createMock(UpgradeService::class); 214 $mock_upgrade_service->method('webtreesZipContents')->willReturn(new Collection()); 215 $handler = new UpgradeWizardStep( 216 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 217 new TreeService(new GedcomImportService()), 218 $mock_upgrade_service 219 ); 220 221 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Unzip']); 222 $response = $handler->handle($request); 223 224 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 225 } 226} 227