createToken(TokenKind::Admin, role: Role::Admin); $resp = $this->request('GET', '/api/v1/admin/app-settings', [ 'Authorization' => 'Bearer ' . $token, ]); self::assertSame(200, $resp->getStatusCode()); $body = $this->decode($resp); self::assertTrue($body['audit_report_received_enabled']); self::assertTrue($body['audit_blocklist_request_enabled']); } public function testNonAdminRoleIsRejected(): void { $token = $this->createToken(TokenKind::Admin, role: Role::Operator); $resp = $this->request('GET', '/api/v1/admin/app-settings', [ 'Authorization' => 'Bearer ' . $token, ]); self::assertSame(403, $resp->getStatusCode()); } public function testPatchPersistsToggleAndEmitsAudit(): void { $token = $this->createToken(TokenKind::Admin, role: Role::Admin); $resp = $this->request( 'PATCH', '/api/v1/admin/app-settings', ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'], (string) json_encode(['audit_report_received_enabled' => false]), ); self::assertSame(200, $resp->getStatusCode()); $body = $this->decode($resp); self::assertFalse($body['audit_report_received_enabled']); self::assertTrue($body['audit_blocklist_request_enabled']); /** @var AppSettings $settings */ $settings = $this->container->get(AppSettings::class); self::assertFalse($settings->getBool(AppSettings::KEY_AUDIT_REPORT_RECEIVED_ENABLED, true)); $row = $this->db->fetchAssociative( "SELECT details_json FROM audit_log WHERE action = 'app_settings.updated' ORDER BY id DESC LIMIT 1" ); self::assertIsArray($row); $details = json_decode((string) $row['details_json'], true); self::assertIsArray($details); self::assertArrayHasKey('audit_report_received_enabled', $details['changes']); self::assertSame(true, $details['changes']['audit_report_received_enabled']['from']); self::assertSame(false, $details['changes']['audit_report_received_enabled']['to']); } public function testPatchWithNoChangesDoesNotEmitAudit(): void { $token = $this->createToken(TokenKind::Admin, role: Role::Admin); $resp = $this->request( 'PATCH', '/api/v1/admin/app-settings', ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'], (string) json_encode(['audit_report_received_enabled' => true]), ); self::assertSame(200, $resp->getStatusCode()); $count = (int) $this->db->fetchOne( "SELECT COUNT(*) FROM audit_log WHERE action = 'app_settings.updated'" ); self::assertSame(0, $count); } public function testPatchValidatesBooleanShape(): void { $token = $this->createToken(TokenKind::Admin, role: Role::Admin); $resp = $this->request( 'PATCH', '/api/v1/admin/app-settings', ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'], (string) json_encode(['audit_report_received_enabled' => 'maybe']), ); self::assertSame(400, $resp->getStatusCode()); } }