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