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 39#[CoversClass(UpgradeWizardStep::class)] 40class UpgradeWizardStepTest extends TestCase 41{ 42 protected static bool $uses_database = true; 43 44 public function testIgnoreStepInvalid(): void 45 { 46 $handler = new UpgradeWizardStep( 47 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 48 new TreeService(new GedcomImportService()), 49 new UpgradeService(new TimeoutService()) 50 ); 51 52 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Invalid']); 53 54 $response = $handler->handle($request); 55 56 self::assertSame(StatusCodeInterface::STATUS_NO_CONTENT, $response->getStatusCode()); 57 } 58 59 public function testStepCheckOK(): void 60 { 61 $mock_upgrade_service = $this->createMock(UpgradeService::class); 62 $mock_upgrade_service->method('latestVersion')->willReturn('999.999.999'); 63 $handler = new UpgradeWizardStep( 64 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 65 new TreeService(new GedcomImportService()), 66 $mock_upgrade_service 67 ); 68 69 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 70 $response = $handler->handle($request); 71 72 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 73 } 74 75 public function testStepCheckUnavailable(): void 76 { 77 $this->expectException(HttpServerErrorException::class); 78 79 $mock_upgrade_service = $this->createMock(UpgradeService::class); 80 $mock_upgrade_service->method('latestVersion')->willReturn(''); 81 $handler = new UpgradeWizardStep( 82 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 83 new TreeService(new GedcomImportService()), 84 $mock_upgrade_service 85 ); 86 87 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 88 $handler->handle($request); 89 } 90 91 public function testStepCheckFail(): void 92 { 93 $this->expectException(HttpServerErrorException::class); 94 95 $mock_upgrade_service = $this->createMock(UpgradeService::class); 96 $mock_upgrade_service->method('latestVersion')->willReturn('0.0.0'); 97 $handler = new UpgradeWizardStep( 98 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 99 new TreeService(new GedcomImportService()), 100 $mock_upgrade_service 101 ); 102 103 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Check']); 104 $handler->handle($request); 105 } 106 107 public function testStepPrepare(): void 108 { 109 $handler = new UpgradeWizardStep( 110 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 111 new TreeService(new GedcomImportService()), 112 new UpgradeService(new TimeoutService()) 113 ); 114 115 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Prepare']); 116 $response = $handler->handle($request); 117 118 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 119 } 120 121 public function testStepPending(): void 122 { 123 $handler = new UpgradeWizardStep( 124 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 125 new TreeService(new GedcomImportService()), 126 new UpgradeService(new TimeoutService()) 127 ); 128 129 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Pending']); 130 $response = $handler->handle($request); 131 132 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 133 } 134 135 public function testStepPendingExist(): void 136 { 137 $tree_service = new TreeService(new GedcomImportService()); 138 $tree = $tree_service->create('name', 'title'); 139 $user = (new UserService())->create('user', 'name', 'email', 'password'); 140 141 Auth::login($user); 142 $tree->createIndividual("0 @@ INDI\n1 NAME Joe Bloggs"); 143 144 $handler = new UpgradeWizardStep( 145 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 146 new TreeService(new GedcomImportService()), 147 new UpgradeService(new TimeoutService()) 148 ); 149 150 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Pending']); 151 $response = $handler->handle($request); 152 153 self::assertSame(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, $response->getStatusCode()); 154 } 155 156 public function testStepExport(): void 157 { 158 $tree = $this->importTree('demo.ged'); 159 $all_trees = Collection::make([$tree->name() => $tree]); 160 $tree_service = $this->createMock(TreeService::class); 161 $tree_service->method('all')->willReturn($all_trees); 162 163 $handler = new UpgradeWizardStep( 164 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 165 $tree_service, 166 new UpgradeService(new TimeoutService()) 167 ); 168 169 $request = self::createRequest()->withQueryParams(['step' => 'Export', 'tree' => $tree->name()]); 170 $response = $handler->handle($request); 171 172 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 173 174 // Now overwrite the file we just created 175 $response = $handler->handle($request); 176 177 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 178 } 179 180 public function testStepDownloadFails(): void 181 { 182 $this->expectException(HttpServerErrorException::class); 183 184 $mock_upgrade_service = $this->createMock(UpgradeService::class); 185 $mock_upgrade_service->method('downloadFile')->will(self::throwException(new Exception())); 186 $handler = new UpgradeWizardStep( 187 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 188 new TreeService(new GedcomImportService()), 189 $mock_upgrade_service 190 ); 191 192 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Download']); 193 $handler->handle($request); 194 } 195 196 public function testStepDownload(): void 197 { 198 $mock_upgrade_service = $this->createMock(UpgradeService::class); 199 $mock_upgrade_service->method('downloadFile')->willReturn(123456); 200 $handler = new UpgradeWizardStep( 201 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 202 new TreeService(new GedcomImportService()), 203 $mock_upgrade_service 204 ); 205 206 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Download']); 207 $response = $handler->handle($request); 208 209 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 210 } 211 212 public function testStepUnzip(): void 213 { 214 $mock_upgrade_service = $this->createMock(UpgradeService::class); 215 $mock_upgrade_service->method('webtreesZipContents')->willReturn(new Collection()); 216 $handler = new UpgradeWizardStep( 217 new GedcomExportService(new Psr17Factory(), new Psr17Factory()), 218 new TreeService(new GedcomImportService()), 219 $mock_upgrade_service 220 ); 221 222 $request = self::createRequest(RequestMethodInterface::METHOD_POST, ['step' => 'Unzip']); 223 $response = $handler->handle($request); 224 225 self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); 226 } 227} 228