diff --git a/tests/UpdateControllerTest.php b/tests/UpdateControllerTest.php index f45c9d3d..d03ef86d 100644 --- a/tests/UpdateControllerTest.php +++ b/tests/UpdateControllerTest.php @@ -1,7 +1,9 @@ actAs('superAdmin'); } - /** - * @param string $version - * @param bool $is_pre_release - * @return string - */ - protected function generateFakeUpdateInfo($version, $is_pre_release = false) { - $time = \Carbon\Carbon::now(); - file_put_contents(vfs\vfsStream::url('root/update.json'), json_encode([ - 'app_name' => 'blessing-skin-server', - 'latest_version' => $version, - 'update_time' => $time->getTimestamp(), - 'releases' => [ - $version => [ - 'version' => $version, - 'pre_release' => $is_pre_release, - 'release_time' => $time->getTimestamp(), - 'release_note' => 'test', - 'release_url' => storage_path('testing/update.zip') - ] - ] - ])); - - return $time->toDateTimeString(); - } - - protected function generateFakeUpdateFile() - { - if (file_exists(storage_path('testing/update.zip'))) { - unlink(storage_path('testing/update.zip')); - } - - $zip = new ZipArchive(); - $zip->open(storage_path('testing/update.zip'), ZipArchive::CREATE); - $zip->addEmptyDir('coverage'); - $zip->close(); - } - public function testShowUpdatePage() { - option(['update_source' => 'http://xxx.xx/']); - $this->visit('/admin/update') - ->see(trans('admin.update.errors.connection')) - ->see(config('app.version')) - ->uncheck('check_update') - ->type(vfs\vfsStream::url('root/update.json'), 'update_source') - ->press('submit_update'); - $this->assertFalse(option('check_update')); - $this->assertEquals( - vfs\vfsStream::url('root/update.json'), - option('update_source') - ); + $this->setupGuzzleClientMock(); - $time = $this->generateFakeUpdateInfo('4.0.0'); + // Can't connect to update source + $this->appendToGuzzleQueue([ + new RequestException('Connection Error', new Request('GET', 'whatever')), + new RequestException('Connection Error', new Request('GET', 'whatever')), + ]); + $this->visit('/admin/update') + ->see(trans('admin.update.errors.connection', ['error' => 'Connection Error'])) + ->see(config('app.version')); + + // New version available + $time = time(); + $this->appendToGuzzleQueue(200, [], $this->generateFakeUpdateInfo('8.9.3', false, $time)); $this->visit('/admin/update') ->see(config('app.version')) - ->see('4.0.0') + ->see('8.9.3') ->see('test') - ->see($time); + ->see(Carbon\Carbon::createFromTimestamp($time)->toDateTimeString()); - file_put_contents(vfs\vfsStream::url('root/update.json'), json_encode([ - 'latest_version' => '4.0.0' - ])); + // Now using pre-release version + $this->appendToGuzzleQueue(200, [], $this->generateFakeUpdateInfo('0.0.1', false, $time)); $this->visit('/admin/update') ->see(trans('admin.update.info.pre-release')); } public function testCheckUpdates() { - option(['update_source' => 'http://xxx.xx/']); + $this->setupGuzzleClientMock(); - // Source is unavailable + // Update source is unavailable + $this->appendToGuzzleQueue([ + new RequestException('Connection Error', new Request('GET', 'whatever')), + new RequestException('Connection Error', new Request('GET', 'whatever')), + ]); $this->get('/admin/update/check') ->seeJson([ 'latest' => null, 'available' => false ]); - option(['update_source' => vfs\vfsStream::url('root/update.json')]); - $this->generateFakeUpdateInfo('4.0.0'); + // New version available + $this->appendToGuzzleQueue(200, [], $this->generateFakeUpdateInfo('8.9.3', false, time())); $this->get('/admin/update/check') ->seeJson([ - 'latest' => '4.0.0', + 'latest' => '8.9.3', 'available' => true ]); } public function testDownload() { - option(['update_source' => vfs\vfsStream::url('root/update.json')]); - $this->generateFakeUpdateInfo('0.1.0'); - $this->get('/admin/update/download'); + $this->setupGuzzleClientMock(); - $this->generateFakeUpdateFile(); + // Already up-to-date + $this->appendToGuzzleQueue(200, [], $this->generateFakeUpdateInfo(config('app.version'))); + $this->get('/admin/update/download')->dontSee(trans('general.illegal-parameters')); - // Prepare for downloading - Storage::disk('root')->deleteDirectory('storage/update_cache'); - $this->generateFakeUpdateInfo('4.0.0'); + // Lack write permission + File::deleteDirectory(storage_path('update_cache')); Storage::shouldReceive('disk') ->with('root') ->once() @@ -124,96 +88,154 @@ class UpdateControllerTest extends TestCase ->with('storage/update_cache') ->once() ->andReturn(false); - $this->get('/admin/update/download?action=prepare-download') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=prepare-download') ->see(trans('admin.update.errors.write-permission')); + // Prepare for downloading mkdir(storage_path('update_cache')); - $this->get('/admin/update/download?action=prepare-download') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=prepare-download') ->seeJson([ - 'release_url' => storage_path('testing/update.zip'), + 'release_url' => 'https://whatever.test/8.9.3/update.zip', ]) - ->assertCacheHas('tmp_path'); + ->seeInCache('tmp_path') + ->assertCacheMissing('download-progress'); // Start downloading $this->flushCache(); - $this->get('/admin/update/download?action=start-download') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=start-download') ->see('No temp path available, please try again.'); - unlink(storage_path('testing/update.zip')); + // Can't download update package + $this->appendToGuzzleQueue([ + new Response(200, [], $this->generateFakeUpdateInfo('8.9.3')), + new RequestException('Connection Error', new Request('GET', 'whatever')), + ]); $this->withCache(['tmp_path' => storage_path('update_cache/update.zip')]) ->get('/admin/update/download?action=start-download') ->see(trans('admin.update.errors.prefix')); + $this->assertFileNotExists(storage_path('update_cache/update.zip')); - $this->generateFakeUpdateFile(); + // Download update package + $fakeUpdatePackage = $this->generateFakeUpdateFile(); + $this->appendToGuzzleQueue([ + new Response(200, [], $this->generateFakeUpdateInfo('8.9.3')), + new Response(200, [], fopen($fakeUpdatePackage, 'r')), + ]); + $this->withCache(['tmp_path' => storage_path('update_cache/update.zip')]) + ->get('/admin/update/download?action=start-download') + ->seeJson([ + 'tmp_path' => storage_path('update_cache/update.zip') + ]); + $this->assertFileExists(storage_path('update_cache/update.zip')); - // TODO: This needs to be tested. - // TODO: I failed to find a good solution for testing guzzle http requests. - // - // $this->withCache(['tmp_path' => storage_path('update_cache/update.zip')]) - // ->get('/admin/update/download?action=start-download') - // ->seeJson([ - // 'tmp_path' => storage_path('update_cache/update.zip') - // ]); - // $this->assertFileExists(storage_path('update_cache/update.zip')); - - // Get file size + // No download progress available $this->flushCache(); - $this->get('/admin/update/download?action=get-progress') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=get-progress') ->see('[]'); - $this->withCache(['download-progress' => ['total' => 514, 'downloaded' => 114]]) + // Get download progress + $this->withNewVersionAvailable() + ->withCache(['download-progress' => ['total' => 514, 'downloaded' => 114]]) ->get('/admin/update/download?action=get-progress') ->seeJson([ 'total' => 514, 'downloaded' => 114 ]); - // Extract - $this->withCache(['tmp_path' => storage_path('update_cache/update')]) + // No such zip archive + $this->withNewVersionAvailable() + ->withCache(['tmp_path' => storage_path('update_cache/nope.zip')]) ->get('/admin/update/download?action=extract') ->see('No file available'); + // Can't extract zip archive file_put_contents(storage_path('update_cache/update.zip'), 'text'); - $this->withCache(['tmp_path' => storage_path('update_cache/update.zip')]) + $this->withNewVersionAvailable() + ->withCache(['tmp_path' => storage_path('update_cache/update.zip')]) ->get('/admin/update/download?action=extract') ->see(trans('admin.update.errors.unzip')); - copy( - storage_path('testing/update.zip'), - storage_path('update_cache/update.zip') - ); - $this->get('/admin/update/download?action=extract') + // Extract + copy(storage_path('testing/update.zip'), storage_path('update_cache/update.zip')); + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=extract') ->see(trans('admin.update.complete')); - + // Can't overwrite vendor directory, skip mkdir(storage_path('update_cache')); - copy( - storage_path('testing/update.zip'), - storage_path('update_cache/update.zip') - ); + copy(storage_path('testing/update.zip'), storage_path('update_cache/update.zip')); File::shouldReceive('copyDirectory') - ->with(storage_path('update_cache/4.0.0/vendor'), base_path('vendor')) - ->andThrow(new \Exception); + ->with(storage_path('update_cache/8.9.3/vendor'), base_path('vendor')) + ->andThrow(new Exception); File::shouldReceive('deleteDirectory') - ->with(storage_path('update_cache/4.0.0/vendor')); - $this->get('/admin/update/download?action=extract'); - + ->with(storage_path('update_cache/8.9.3/vendor')); + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=extract'); + // Can't apply update package File::shouldReceive('copyDirectory') - ->with(storage_path('update_cache/4.0.0'), base_path()) + ->with(storage_path('update_cache/8.9.3'), base_path()) ->andThrow(new Exception); File::shouldReceive('deleteDirectory') ->with(storage_path('update_cache')); File::shouldReceive('deleteDirectory') ->with(storage_path('update_cache')); - $this->get('/admin/update/download?action=extract') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=extract') ->see(trans('admin.update.errors.overwrite')); // Invalid action - $this->get('/admin/update/download?action=no') + $this->withNewVersionAvailable() + ->get('/admin/update/download?action=no') ->seeJson([ 'errno' => 1, 'msg' => trans('general.illegal-parameters') ]); } + + protected function withNewVersionAvailable() + { + $this->appendToGuzzleQueue(200, [], $this->generateFakeUpdateInfo('8.9.3')); + return $this; + } + + protected function generateFakeUpdateInfo($version, $preview = false, $time = null) + { + $time = $time ?: time(); + + return json_encode([ + 'app_name' => 'blessing-skin-server', + 'latest_version' => $version, + 'update_time' => $time, + 'releases' => [ + $version => [ + 'version' => $version, + 'pre_release' => $preview, + 'release_time' => $time, + 'release_note' => 'test', + 'release_url' => "https://whatever.test/$version/update.zip" + ] + ] + ]); + } + + protected function generateFakeUpdateFile() + { + $zipPath = storage_path('testing/update.zip'); + + if (file_exists($zipPath)) { + unlink($zipPath); + } + + $zip = new ZipArchive(); + $zip->open($zipPath, ZipArchive::CREATE); + $zip->addEmptyDir('coverage'); + $zip->close(); + + return $zipPath; + } }