diff --git a/src/Sender/RequestBuilder.php b/src/Sender/RequestBuilder.php index 6ee13e8..b6a8803 100644 --- a/src/Sender/RequestBuilder.php +++ b/src/Sender/RequestBuilder.php @@ -31,7 +31,7 @@ public function createRequest( ): RequestInterface { $request = new Request('POST', $subscription->getEndpoint()); $request = $this->withOptionalHeaders($request, $message); - $request = $request->withHeader('TTL', $ttl); + $request = $request->withHeader('TTL', (string) $ttl); if (null !== $message->getPayload() && null !== $subscription->getPublicKey() && null !== $subscription->getAuthToken()) { $request = $request @@ -57,11 +57,11 @@ public function createRequest( return $request ->withBody(GuzzleUtils::streamFor($content)) - ->withHeader('Content-Length', Utils::safeStrlen($content)); + ->withHeader('Content-Length', (string) Utils::safeStrlen($content)); } return $request - ->withHeader('Content-Length', 0); + ->withHeader('Content-Length', '0'); } /** @@ -85,8 +85,7 @@ public function withVAPIDAuthentication(RequestInterface $request, array $vapid, if ($request->hasHeader('Crypto-Key')) { $request = $request->withHeader('Crypto-Key', $request->getHeaderLine('Crypto-Key').';'.$vapidHeaders['Crypto-Key']); } else { - $headers['Crypto-Key'] = $vapidHeaders['Crypto-Key']; - $request->withHeader('Crypto-Key', $vapidHeaders['Crypto-Key']); + $request = $request->withHeader('Crypto-Key', $vapidHeaders['Crypto-Key']); } } elseif ('aes128gcm' === $subscription->getContentEncoding() && self::FCM_BASE_URL === substr($endpoint, 0, strlen(self::FCM_BASE_URL))) { $request = $request->withUri(new Uri(str_replace('fcm/send', 'wp', $endpoint))); @@ -110,7 +109,7 @@ private function withOptionalHeaders(RequestInterface $request, PushMessage $mes { foreach (['urgency', 'topic'] as $option) { if (null !== $message->getOption($option)) { - $request = $request->withHeader($option, $message->getOption($option)); + $request = $request->withHeader($option, (string) $message->getOption($option)); } } diff --git a/tests/Sender/RequestBuilderTest.php b/tests/Sender/RequestBuilderTest.php new file mode 100644 index 0000000..813d3d9 --- /dev/null +++ b/tests/Sender/RequestBuilderTest.php @@ -0,0 +1,116 @@ +requestBuilder = new RequestBuilder(); + } + + public function testCreateRequestWithoutPayload(): void + { + $user = new TestUser('test-user'); + $subscription = new TestUserSubscription( + $user, + 'https://fcm.googleapis.com/fcm/send/test-token', + 'BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=', + 'tBNxuxajfzpWUZAH-5B20A==', + 'sub-hash' + ); + + $message = new PushMessage(); + $message->setUrgency('high'); + $message->setTopic('updates'); + + $request = $this->requestBuilder->createRequest($message, $subscription, 120); + + $this->assertSame('POST', $request->getMethod()); + $this->assertSame('https://fcm.googleapis.com/fcm/send/test-token', (string)$request->getUri()); + $this->assertSame(['120'], $request->getHeader('TTL')); + $this->assertSame(['0'], $request->getHeader('Content-Length')); + $this->assertSame(['high'], $request->getHeader('urgency')); + $this->assertSame(['updates'], $request->getHeader('topic')); + } + + public function testCreateRequestWithPayload(): void + { + $user = new TestUser('test-user'); + $subscription = new TestUserSubscription( + $user, + 'https://fcm.googleapis.com/fcm/send/test-token', + 'BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=', + 'tBNxuxajfzpWUZAH-5B20A==', + 'sub-hash' + ); + + $message = new PushMessage('{"title":"Hello World"}'); + $request = $this->requestBuilder->createRequest($message, $subscription, 3600); + + $this->assertSame(['3600'], $request->getHeader('TTL')); + $this->assertSame(['application/octet-stream'], $request->getHeader('Content-Type')); + $this->assertSame(['aesgcm'], $request->getHeader('Content-Encoding')); + $this->assertTrue($request->hasHeader('Content-Length')); + $contentLength = $request->getHeaderLine('Content-Length'); + $this->assertIsNumeric($contentLength); + $this->assertGreaterThan(0, (int)$contentLength); + $this->assertTrue($request->hasHeader('Encryption')); + $this->assertTrue($request->hasHeader('Crypto-Key')); + } + + public function testWithVAPIDAuthentication(): void + { + $vapidKeys = VAPID::createVapidKeys(); + $user = new TestUser('test-user'); + $subscription = new TestUserSubscription( + $user, + 'https://fcm.googleapis.com/fcm/send/test-token', + 'BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=', + 'tBNxuxajfzpWUZAH-5B20A==', + 'sub-hash' + ); + + $message = new PushMessage(); + $request = $this->requestBuilder->createRequest($message, $subscription, 0); + + $vapid = VAPID::validate([ + 'subject' => 'mailto:admin@example.com', + 'publicKey' => $vapidKeys['publicKey'], + 'privateKey' => $vapidKeys['privateKey'], + ]); + + $authenticatedRequest = $this->requestBuilder->withVAPIDAuthentication($request, $vapid, $subscription); + + $this->assertTrue($authenticatedRequest->hasHeader('Authorization')); + $this->assertTrue($authenticatedRequest->hasHeader('Crypto-Key')); + } + + public function testWithGCMAuthentication(): void + { + $user = new TestUser('test-user'); + $subscription = new TestUserSubscription( + $user, + 'https://fcm.googleapis.com/fcm/send/test-token', + 'BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=', + 'tBNxuxajfzpWUZAH-5B20A==', + 'sub-hash' + ); + + $message = new PushMessage(); + $request = $this->requestBuilder->createRequest($message, $subscription, 0); + + $authenticatedRequest = $this->requestBuilder->withGCMAuthentication($request, 'sample-api-key'); + + $this->assertSame(['key=sample-api-key'], $authenticatedRequest->getHeader('Authorization')); + } +}