create(); $store = WooStore::create([ 'user_id' => $user->id, 'site_url' => 'https://shop.example.com', 'site_name' => 'Example Shop', 'status' => WooStore::STATUS_ACTIVE, 'connected_at' => now(), 'plugin_token_hash' => hash('sha256', 'test-token'), ]); $payload = [ 'id' => 99, 'number' => '1099', 'status' => 'processing', 'currency' => 'GHS', 'total' => '75.00', 'billing' => ['first_name' => 'Kofi', 'last_name' => 'Annan', 'email' => 'kofi@example.com'], 'line_items' => [['name' => 'Cap', 'quantity' => 1, 'total' => '75.00']], 'needs_payment' => false, 'date_modified_gmt' => now()->utc()->format('Y-m-d H:i:s'), ]; $body = json_encode($payload, JSON_THROW_ON_ERROR); $signature = base64_encode(hash_hmac('sha256', $body, (string) $store->webhook_secret, true)); $this->call( 'POST', route('woo.webhooks.woocommerce', $store->public_id), [], [], [], [ 'CONTENT_TYPE' => 'application/json', 'HTTP_X_WC_WEBHOOK_SIGNATURE' => $signature, 'HTTP_X_WC_WEBHOOK_TOPIC' => 'order.created', ], $body, )->assertOk(); Notification::assertSentTo($user, WooOrderReceivedNotification::class); } public function test_order_updated_webhook_does_not_send_order_received_notification(): void { Notification::fake(); $user = User::factory()->create(); $store = WooStore::create([ 'user_id' => $user->id, 'site_url' => 'https://shop.example.com', 'status' => WooStore::STATUS_ACTIVE, 'connected_at' => now(), 'plugin_token_hash' => hash('sha256', 'test-token'), ]); WooOrder::create([ 'woo_store_id' => $store->id, 'external_order_id' => 42, 'order_number' => '1042', 'line_items' => [], 'currency' => 'GHS', 'total_minor' => 5000, ]); $payload = [ 'id' => 42, 'number' => '1042', 'status' => 'completed', 'currency' => 'GHS', 'total' => '50.00', 'billing' => [], 'line_items' => [], 'needs_payment' => false, 'date_modified_gmt' => now()->utc()->format('Y-m-d H:i:s'), ]; $body = json_encode($payload, JSON_THROW_ON_ERROR); $signature = base64_encode(hash_hmac('sha256', $body, (string) $store->webhook_secret, true)); $this->call( 'POST', route('woo.webhooks.woocommerce', $store->public_id), [], [], [], [ 'CONTENT_TYPE' => 'application/json', 'HTTP_X_WC_WEBHOOK_SIGNATURE' => $signature, 'HTTP_X_WC_WEBHOOK_TOPIC' => 'order.updated', ], $body, )->assertOk(); Notification::assertNothingSent(); } public function test_store_activation_sends_store_connected_notification(): void { Notification::fake(); $user = User::factory()->create(); $store = WooStore::create([ 'user_id' => $user->id, 'site_url' => 'https://shop.example.com', 'site_name' => 'Example Shop', 'status' => WooStore::STATUS_PENDING, ]); $token = app(InstallTokenService::class)->issue($store)['token']; $this->postJson('/api/v1/stores/activate', [ 'install_token' => $token, 'site_url' => 'https://shop.example.com', ])->assertOk(); Notification::assertSentTo($user, WooStoreConnectedNotification::class); } public function test_pro_expiry_alert_sent_once_per_milestone(): void { Notification::fake(); $user = User::factory()->create(); $subscription = ProSubscription::create([ 'user_id' => $user->id, 'status' => ProSubscription::STATUS_CANCELED, 'plan' => ProSubscription::PLAN_PRO, 'price_minor' => 4900, 'currency' => 'GHS', 'auto_renew' => false, 'current_period_end' => now()->addDays(7)->startOfDay(), ]); $service = app(WooProExpiryAlertService::class); $service->checkSubscription($subscription); $service->checkSubscription($subscription->fresh()); Notification::assertSentTo($user, WooProExpiringNotification::class, 1); $this->assertSame([7], $subscription->fresh()->metadata['expiry_alerts_sent']); } }