Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function update(WritePluginRequest $request, Plugin $plugin): array
{
throw_unless($plugin->isUpdateAvailable(), new PanelException("Plugin doesn't need updating"));

$this->pluginService->updatePlugin($plugin);
$plugin = $this->pluginService->updatePlugin($plugin);

return $this->response->item($plugin)
->transformWith(PluginData::class)
Expand Down
6 changes: 4 additions & 2 deletions app/Services/Helpers/PluginService.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,19 +313,21 @@ public function installPlugin(Plugin $plugin, bool $enable = true): void
}

/** @throws Exception */
public function updatePlugin(Plugin $plugin): void
public function updatePlugin(Plugin $plugin): Plugin
{
$downloadUrl = $plugin->getDownloadUrlForUpdate();
throw_unless($downloadUrl, new Exception('No download url found.'));

$this->downloadPluginFromUrl($downloadUrl, $plugin->id);

Plugin::refreshRows();
$plugin = $plugin->refresh();
$plugin = Plugin::findOrFail($plugin->id);

$this->installPlugin($plugin, false);

cache()->forget("plugins.$plugin->id.update");

return $plugin;
}

/** @throws Exception */
Expand Down
59 changes: 59 additions & 0 deletions tests/Integration/Services/PluginServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

namespace App\Tests\Integration\Services;

use App\Enums\PluginStatus;
use App\Models\Plugin;
use App\Services\Helpers\PluginService;
use App\Tests\Integration\IntegrationTestCase;
use Exception;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Process;
use PHPUnit\Framework\Attributes\DataProvider;
use Spatie\TemporaryDirectory\TemporaryDirectory;
use ZipArchive;
Expand Down Expand Up @@ -43,6 +46,9 @@ protected function tearDown(): void
File::deleteDirectory($leftover);
}

// Don't leak the in-memory Sushi rows of the plugins removed above into later tests.
Plugin::refreshRows();

// TemporaryDirectory::make() does not clean up on its own; remove the upload fixtures.
foreach ($this->uploadDirs as $dir) {
$dir->delete();
Expand Down Expand Up @@ -388,6 +394,45 @@ public function test_import_keeps_the_existing_plugin_when_the_move_fails(): voi
$this->assertDirectoryDoesNotExist(plugin_path('.test-clean-plugin.bak'));
}

public function test_update_downloads_and_reinstalls_the_new_version(): void
{
$this->importedPlugins[] = 'test-update-plugin';

// Updates are resolved against the panel version, which is null on canary.
config()->set('app.version', '1.0.0');
Process::fake();

$updateUrl = 'https://example.test/test-update-plugin/update.json';
$downloadUrl = 'https://example.test/test-update-plugin/2.0.0.zip';

$this->service->downloadPluginFromFile($this->makeUpload('test-update-plugin.zip', [
'test-update-plugin/plugin.json' => $this->updatableManifest('test-update-plugin', '1.0.0', $updateUrl),
]));

$update = file_get_contents($this->makeUpload('2.0.0.zip', [
'test-update-plugin/plugin.json' => $this->updatableManifest('test-update-plugin', '2.0.0', $updateUrl),
])->getPathname());

Http::fake([
$updateUrl => Http::response(['*' => ['version' => '2.0.0', 'download_url' => $downloadUrl]]),
$downloadUrl => Http::response($update),
]);

Plugin::refreshRows();
$plugin = Plugin::findOrFail('test-update-plugin');

$updated = $this->service->updatePlugin($plugin);

$this->assertSame('2.0.0', $updated->version);
$this->assertSame('2.0.0', $this->installedVersion('test-update-plugin'));

// installPlugin() ran against the reloaded row and recorded the plugin as installed but disabled.
$this->assertSame(PluginStatus::Disabled->value, File::json(plugin_path('test-update-plugin', 'plugin.json'))['meta']['status']);

Plugin::refreshRows();
$this->assertSame('2.0.0', Plugin::findOrFail('test-update-plugin')->version);
}

private function installedVersion(string $id): string
{
return File::json(plugin_path($id, 'plugin.json'))['version'];
Expand All @@ -398,6 +443,20 @@ private function manifest(string $id, string $version = '1.0.0'): string
return json_encode(['id' => $id, 'version' => $version]);
}

private function updatableManifest(string $id, string $version, string $updateUrl): string
{
return json_encode([
'id' => $id,
'name' => 'Test Update Plugin',
'author' => 'Pelican',
'version' => $version,
'category' => 'plugin',
'update_url' => $updateUrl,
'namespace' => 'TestUpdatePlugin',
'class' => 'TestUpdatePlugin',
]);
}

/**
* Build a zip on disk from the given [path => contents] map and wrap it in an UploadedFile.
*
Expand Down
Loading