diff --git a/app/Http/Controllers/PluginWebhookController.php b/app/Http/Controllers/PluginWebhookController.php index 73ace98b..a6360637 100644 --- a/app/Http/Controllers/PluginWebhookController.php +++ b/app/Http/Controllers/PluginWebhookController.php @@ -18,12 +18,16 @@ public function __invoke(Request $request, string $secret, PluginSyncService $sy return response()->json(['error' => 'Invalid webhook secret'], 404); } + $event = $request->header('X-GitHub-Event'); + + if ($event === 'ping') { + return response()->json(['success' => true, 'message' => 'pong']); + } + if (! $plugin->isApproved()) { return response()->json(['error' => 'Plugin is not approved'], 403); } - $event = $request->header('X-GitHub-Event'); - if ($event === 'release') { // Sync plugin metadata to update latest_version $syncService->sync($plugin); diff --git a/tests/Feature/PluginWebhookTest.php b/tests/Feature/PluginWebhookTest.php new file mode 100644 index 00000000..ac4776df --- /dev/null +++ b/tests/Feature/PluginWebhookTest.php @@ -0,0 +1,70 @@ +create(); + + $response = $this->postJson( + route('webhooks.plugins', $plugin->webhook_secret), + [], + ['X-GitHub-Event' => 'ping'] + ); + + $response->assertOk() + ->assertJson(['success' => true, 'message' => 'pong']); + } + + #[Test] + public function ping_event_succeeds_for_approved_plugin(): void + { + $plugin = Plugin::factory()->approved()->create(); + + $response = $this->postJson( + route('webhooks.plugins', $plugin->webhook_secret), + [], + ['X-GitHub-Event' => 'ping'] + ); + + $response->assertOk() + ->assertJson(['success' => true, 'message' => 'pong']); + } + + #[Test] + public function non_ping_event_returns_403_for_unapproved_plugin(): void + { + $plugin = Plugin::factory()->create(); + + $response = $this->postJson( + route('webhooks.plugins', $plugin->webhook_secret), + [], + ['X-GitHub-Event' => 'push'] + ); + + $response->assertForbidden() + ->assertJson(['error' => 'Plugin is not approved']); + } + + #[Test] + public function invalid_secret_returns_404(): void + { + $response = $this->postJson( + route('webhooks.plugins', 'invalid-secret'), + [], + ['X-GitHub-Event' => 'ping'] + ); + + $response->assertNotFound(); + } +}