diff --git a/app/Http/Controllers/MarketController.php b/app/Http/Controllers/MarketController.php index d1a1aa85..111bf82f 100644 --- a/app/Http/Controllers/MarketController.php +++ b/app/Http/Controllers/MarketController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use Exception; +use App\Services\Plugin; use Illuminate\Support\Arr; use Illuminate\Http\Request; use App\Services\PluginManager; @@ -30,11 +31,10 @@ class MarketController extends Controller $this->guzzle = $guzzle; } - public function marketData() + public function marketData(PluginManager $manager) { - $plugins = collect($this->getAllAvailablePlugins())->map(function ($item) { - $plugin = plugin($item['name']); - $manager = app('plugins'); + $plugins = collect($this->getAllAvailablePlugins())->map(function ($item) use ($manager) { + $plugin = $manager->get($item['name']); if ($plugin) { $item['enabled'] = $plugin->isEnabled(); @@ -48,9 +48,8 @@ class MarketController extends Controller unset($item['require']); $item['dependencies'] = [ - 'isRequirementsSatisfied' => $manager->isRequirementsSatisfied($requirements), - 'requirements' => $requirements, - 'unsatisfiedRequirements' => $manager->getUnsatisfiedRequirements($requirements), + 'all' => $requirements, + 'unsatisfied' => $manager->getUnsatisfied(new Plugin('', $item)), ]; return $item; @@ -59,13 +58,13 @@ class MarketController extends Controller return $plugins; } - public function checkUpdates() + public function checkUpdates(PluginManager $manager) { - $pluginsHaveUpdate = collect($this->getAllAvailablePlugins())->filter(function ($item) { - $plugin = plugin($item['name']); - - return $plugin && Comparator::greaterThan($item['version'], $plugin->version); - }); + $pluginsHaveUpdate = collect($this->getAllAvailablePlugins()) + ->filter(function ($item) use ($manager) { + $plugin = $manager->get($item['name']); + return $plugin && Comparator::greaterThan($item['version'], $plugin->version); + }); return json([ 'available' => $pluginsHaveUpdate->isNotEmpty(), @@ -98,7 +97,7 @@ class MarketController extends Controller protected function getPluginMetadata($name) { - return collect($this->getAllAvailablePlugins())->where('name', $name)->first(); + return collect($this->getAllAvailablePlugins())->firstWhere('name', $name); } protected function getAllAvailablePlugins() diff --git a/tests/Concerns/GeneratesFakePlugins.php b/tests/Concerns/GeneratesFakePlugins.php index e2a47739..3395c475 100644 --- a/tests/Concerns/GeneratesFakePlugins.php +++ b/tests/Concerns/GeneratesFakePlugins.php @@ -115,31 +115,4 @@ trait GeneratesFakePlugins file_put_contents("$plugin_dir/bootstrap.php", "open($zipPath, ZipArchive::CREATE); - $zip->addEmptyDir($name); - $zip->addFromString("$name/package.json", json_encode( - $this->generateFakePlguinInfo($info) - )); - $zip->close(); - - return $zipPath; - } } diff --git a/tests/MarketControllerTest.php b/tests/MarketControllerTest.php index 99c1bafb..feb2aca2 100644 --- a/tests/MarketControllerTest.php +++ b/tests/MarketControllerTest.php @@ -2,18 +2,17 @@ namespace Tests; +use App\Services\Plugin; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; +use App\Services\PluginManager; use App\Services\PackageManager; -use Illuminate\Support\Facades\File; use Tests\Concerns\MocksGuzzleClient; -use Tests\Concerns\GeneratesFakePlugins; use GuzzleHttp\Exception\RequestException; class MarketControllerTest extends TestCase { use MocksGuzzleClient; - use GeneratesFakePlugins; protected function setUp(): void { @@ -26,7 +25,10 @@ class MarketControllerTest extends TestCase $this->setupGuzzleClientMock(); // Try to download a non-existent plugin - $this->appendToGuzzleQueue(200, [], $this->generateFakePluginsRegistry()); + $this->appendToGuzzleQueue(200, [], json_encode([ + 'version' => 1, + 'packages' => [], + ])); $this->postJson('/admin/plugins/market/download', [ 'name' => 'non-existent-plugin', ])->assertJson([ @@ -35,17 +37,36 @@ class MarketControllerTest extends TestCase ]); // Download - $fakeRegistry = $this->generateFakePluginsRegistry('fake-test-download', '0.0.1'); + $fakeRegistry = json_encode(['packages' => [ + [ + 'name' => 'fake', + 'version' => '0.0.0', + 'dist' => ['url' => 'http://nowhere.test/', 'shasum' => 'deadbeef'], + ], + ]]); $this->appendToGuzzleQueue([new Response(200, [], $fakeRegistry)]); - app()->instance(PackageManager::class, new Concerns\FakePackageManager(null, true)); + $this->mock(PackageManager::class, function ($mock) { + $mock->shouldReceive('download') + ->withArgs(['http://nowhere.test/', storage_path('packages/fake_0.0.0.zip'), 'deadbeef']) + ->once() + ->andThrow(new \Exception()); + }); $this->postJson('/admin/plugins/market/download', [ - 'name' => 'fake-test-download', + 'name' => 'fake', ])->assertJson(['code' => 1]); $this->appendToGuzzleQueue([new Response(200, [], $fakeRegistry)]); - app()->bind(PackageManager::class, Concerns\FakePackageManager::class); + $this->mock(PackageManager::class, function ($mock) { + $mock->shouldReceive('download') + ->withArgs(['http://nowhere.test/', storage_path('packages/fake_0.0.0.zip'), 'deadbeef']) + ->once() + ->andReturnSelf(); + $mock->shouldReceive('extract') + ->with(base_path('plugins')) + ->once(); + }); $this->postJson('/admin/plugins/market/download', [ - 'name' => 'fake-test-download', + 'name' => 'fake', ])->assertJson(['code' => 0, 'message' => trans('admin.plugins.market.install-success')]); } @@ -53,20 +74,30 @@ class MarketControllerTest extends TestCase { $this->setupGuzzleClientMock(); + $fakeRegistry = json_encode(['packages' => [ + [ + 'name' => 'fake', + 'version' => '0.0.1', + 'dist' => ['url' => 'http://nowhere.test/', 'shasum' => 'deadbeef'], + ], + ]]); + // Not installed - $this->appendToGuzzleQueue(200, [], $this->generateFakePluginsRegistry('fake-test-update', '0.0.1')); + $this->appendToGuzzleQueue(200, [], $fakeRegistry); $this->getJson('/admin/plugins/market/check') ->assertJson([ 'available' => false, 'plugins' => [], ]); - // Generate fake plugin and refresh plugin manager - $this->generateFakePlugin(['name' => 'fake-test-update', 'version' => '0.0.1']); - $this->app->singleton('plugins', \App\Services\PluginManager::class); - + $this->mock(PluginManager::class, function ($mock) { + $mock->shouldReceive('get') + ->with('fake') + ->twice() + ->andReturn(new Plugin('', ['name' => 'fake', 'version' => '0.0.1'])); + }); // Plugin up-to-date - $this->appendToGuzzleQueue(200, [], $this->generateFakePluginsRegistry('fake-test-update', '0.0.1')); + $this->appendToGuzzleQueue(200, [], $fakeRegistry); $this->getJson('/admin/plugins/market/check') ->assertJson([ 'available' => false, @@ -74,30 +105,64 @@ class MarketControllerTest extends TestCase ]); // New version available - $this->appendToGuzzleQueue(200, [], $this->generateFakePluginsRegistry('fake-test-update', '2.3.3')); + $fakeRegistry = json_encode(['packages' => [ + [ + 'name' => 'fake', + 'version' => '2.3.3', + 'dist' => ['url' => 'http://nowhere.test/', 'shasum' => 'deadbeef'], + ], + ]]); + $this->appendToGuzzleQueue(200, [], $fakeRegistry); $this->getJson('/admin/plugins/market/check') ->assertJson([ 'available' => true, 'plugins' => [[ - 'name' => 'fake-test-update', + 'name' => 'fake', ]], ]); } public function testMarketData() { - $registry = $this->generateFakePluginsRegistry(); - $package = json_decode($registry, true)['packages'][0]; - $this->generateFakePlugin($package); $this->setupGuzzleClientMock([ new RequestException('Connection Error', new Request('POST', 'whatever')), - new Response(200, [], $registry), - new Response(200, [], json_encode(array_merge(json_decode($registry, true), ['version' => 0]))), + new Response(200, [], json_encode(['version' => 1, 'packages' => [ + [ + 'name' => 'fake1', + 'title' => 'Fake', + 'version' => '1.0.0', + 'description' => '', + 'author' => '', + 'dist' => [], + 'require' => [], + ], + [ + 'name' => 'fake2', + 'title' => 'Fake', + 'version' => '0.0.0', + 'description' => '', + 'author' => '', + 'dist' => [], + 'require' => [], + ], + ]])), + new Response(200, [], json_encode(['version' => 0])), ]); // Expected an exception, but unable to be asserted. $this->getJson('/admin/plugins/market-data'); + $this->mock(PluginManager::class, function ($mock) { + $mock->shouldReceive('get') + ->with('fake1') + ->once() + ->andReturn(new Plugin('', ['name' => 'fake1', 'version' => '0.0.1'])); + $mock->shouldReceive('get') + ->with('fake2') + ->once() + ->andReturn(null); + $mock->shouldReceive('getUnsatisfied')->twice(); + }); $this->getJson('/admin/plugins/market-data') ->assertJsonStructure([ [ @@ -112,20 +177,7 @@ class MarketControllerTest extends TestCase ], ]); - File::deleteDirectory(config('plugins.directory').DIRECTORY_SEPARATOR.$package['name']); - - $this - ->getJson('/admin/plugins/market-data') + $this->getJson('/admin/plugins/market-data') ->assertJson(['message' => 'Only version 1 of market registry is accepted.']); } - - protected function tearDown(): void - { - // Clean fake plugins - File::deleteDirectory(config('plugins.directory').DIRECTORY_SEPARATOR.'fake-test-download'); - File::deleteDirectory(config('plugins.directory').DIRECTORY_SEPARATOR.'fake-test-update'); - File::delete(config('plugins.directory').DIRECTORY_SEPARATOR.'whatever'); - - parent::tearDown(); - } } diff --git a/tests/PluginControllerTest.php b/tests/PluginControllerTest.php index f4057ddd..7ed827b1 100644 --- a/tests/PluginControllerTest.php +++ b/tests/PluginControllerTest.php @@ -4,14 +4,11 @@ namespace Tests; use App\Services\Plugin; use App\Services\PluginManager; -use Illuminate\Support\Facades\File; -use Tests\Concerns\GeneratesFakePlugins; use Illuminate\Foundation\Testing\DatabaseTransactions; class PluginControllerTest extends TestCase { use DatabaseTransactions; - use GeneratesFakePlugins; protected function setUp(): void {