makeUser('sub1'); $this->actingAs($user) ->postJson('http://sub1.service.mir.md/push/subscribe', [ 'endpoint' => 'https://push.example.com/abc123', 'keys' => ['p256dh' => 'PUBLICKEY', 'auth' => 'AUTHTOKEN'], 'contentEncoding' => 'aes128gcm', ]) ->assertOk() ->assertJson(['ok' => true]); $this->assertDatabaseHas('push_subscriptions', [ 'endpoint' => 'https://push.example.com/abc123', 'user_id' => $user->id, 'public_key' => 'PUBLICKEY', 'content_encoding' => 'aes128gcm', ]); } public function test_subscribe_upserts_on_duplicate_endpoint(): void { [$company, $user] = $this->makeUser('sub2'); $payload = [ 'endpoint' => 'https://push.example.com/dup', 'keys' => ['p256dh' => 'KEY1', 'auth' => 'AUTH1'], ]; $this->actingAs($user)->postJson('http://sub2.service.mir.md/push/subscribe', $payload)->assertOk(); $payload['keys']['p256dh'] = 'KEY2'; $this->actingAs($user)->postJson('http://sub2.service.mir.md/push/subscribe', $payload)->assertOk(); $this->assertEquals(1, PushSubscription::where('endpoint', 'https://push.example.com/dup')->count()); $this->assertEquals('KEY2', PushSubscription::where('endpoint', 'https://push.example.com/dup')->value('public_key')); } public function test_subscribe_requires_auth(): void { $this->makeUser('sub3'); $this->postJson('http://sub3.service.mir.md/push/subscribe', [ 'endpoint' => 'https://push.example.com/noauth', 'keys' => ['p256dh' => 'X', 'auth' => 'Y'], ])->assertStatus(401); } public function test_validation_rejects_missing_keys(): void { [$company, $user] = $this->makeUser('sub4'); $this->actingAs($user) ->postJson('http://sub4.service.mir.md/push/subscribe', [ 'endpoint' => 'https://push.example.com/x', ]) ->assertStatus(422); } public function test_webpush_service_reports_configured(): void { $svc = app(WebPushService::class); $this->assertTrue($svc->configured()); $this->assertNotEmpty($svc->publicKey()); } public function test_send_to_user_with_no_subscriptions_returns_zero(): void { [$company, $user] = $this->makeUser('sub5'); $r = app(WebPushService::class)->sendToUser($user->id, 'T', 'B'); $this->assertEquals(0, $r['sent']); $this->assertEquals(0, $r['pruned']); } private function makeUser(string $slug): array { $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]); $company = Company::create([ 'plan_id' => $plan->id, 'slug' => $slug, 'name' => ucfirst($slug), 'status' => 'active', ]); app(TenantManager::class)->setCurrent($company); $user = User::create([ 'company_id' => $company->id, 'name' => 'Push User', 'email' => $slug . '@example.com', 'password' => bcrypt('secret'), 'role' => 'admin', 'status' => 'active', ]); return [$company, $user]; } }