ResponseReaderTest.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. /*
  3. * This file is part of Chrome PHP.
  4. *
  5. * (c) Soufiane Ghzal <sghzal@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace HeadlessChromium\Test\Communication;
  11. use HeadlessChromium\Communication\Connection;
  12. use HeadlessChromium\Communication\Message;
  13. use HeadlessChromium\Communication\Response;
  14. use HeadlessChromium\Communication\ResponseReader;
  15. use HeadlessChromium\Communication\Socket\MockSocket;
  16. use HeadlessChromium\Exception\NoResponseAvailable;
  17. use HeadlessChromium\Exception\OperationTimedOut;
  18. use PHPUnit\Framework\TestCase;
  19. /**
  20. * @covers \HeadlessChromium\Communication\ResponseReader
  21. */
  22. class ResponseReaderTest extends TestCase
  23. {
  24. public function testMessage(): void
  25. {
  26. $message = new Message('foo', ['bar' => 'baz']);
  27. $mockSocket = new MockSocket();
  28. $connection = new Connection($mockSocket);
  29. $responseReader = new ResponseReader($message, $connection);
  30. $this->assertSame($message, $responseReader->getMessage());
  31. $this->assertSame($connection, $responseReader->getConnection());
  32. // no response
  33. $this->assertFalse($responseReader->hasResponse());
  34. try {
  35. $responseReader->waitForResponse(1);
  36. $this->fail('exception not thrown');
  37. } catch (OperationTimedOut $e) {
  38. $this->assertTrue(true);
  39. }
  40. $this->assertFalse($responseReader->checkForResponse());
  41. // add response
  42. $mockSocket->addReceivedData(\json_encode(['id' => $message->getId(), 'foo' => 'qux']));
  43. $this->assertTrue($responseReader->checkForResponse());
  44. $this->assertTrue($responseReader->hasResponse());
  45. $this->assertInstanceOf(Response::class, $responseReader->getResponse());
  46. $this->assertSame($responseReader->waitForResponse(1), $responseReader->getResponse());
  47. $this->assertEquals(['id' => $message->getId(), 'foo' => 'qux'], $responseReader->getResponse()->getData());
  48. }
  49. public function testWaitForResponse(): void
  50. {
  51. $message = new Message('foo', ['bar' => 'baz']);
  52. $mockSocket = new MockSocket();
  53. $connection = new Connection($mockSocket);
  54. $responseReader = new ResponseReader($message, $connection);
  55. try {
  56. $responseReader->waitForResponse(1);
  57. $this->fail('exception not thrown');
  58. } catch (OperationTimedOut $e) {
  59. $this->assertTrue(true);
  60. }
  61. // receive data
  62. $mockSocket->addReceivedData(\json_encode(['id' => $message->getId(), 'foo' => 'qux']));
  63. // timeout should not be reached and response should be get immediately
  64. $response = $responseReader->waitForResponse(0);
  65. $this->assertInstanceOf(Response::class, $response);
  66. // response should be stored
  67. $this->assertTrue($responseReader->hasResponse());
  68. $this->assertSame($response, $responseReader->getResponse());
  69. $this->assertSame($response, $responseReader->waitForResponse(0));
  70. }
  71. /**
  72. * Tests that waitForResponse will stop dispatching data once it got the response for its message.
  73. *
  74. * @throws NoResponseAvailable
  75. * @throws OperationTimedOut
  76. */
  77. public function testWaitForResponseIsAtomic(): void
  78. {
  79. $message = new Message('foo', ['bar' => 'baz']);
  80. $mockSocket = new MockSocket();
  81. $connection = new Connection($mockSocket);
  82. $emitWatcher = new \stdClass();
  83. $emitWatcher->emittedCount = 0;
  84. $connection->on('method:qux.quux', function () use ($emitWatcher): void {
  85. ++$emitWatcher->emittedCount;
  86. });
  87. $responseReader = new ResponseReader($message, $connection);
  88. // receive data
  89. $mockSocket->addReceivedData(\json_encode(['id' => $message->getId(), 'foo' => 'qux']));
  90. $mockSocket->addReceivedData(\json_encode(['method' => 'qux.quux', 'params' => []]));
  91. // wait for response should not read the second message (method:qux.quux)
  92. $response = $responseReader->waitForResponse(1);
  93. $this->assertEquals(['id' => $message->getId(), 'foo' => 'qux'], $response->getData());
  94. $this->assertEquals(0, $emitWatcher->emittedCount);
  95. // next call to read line should read the second message (method:qux.quux)
  96. $connection->readLine();
  97. $this->assertEquals(1, $emitWatcher->emittedCount);
  98. }
  99. public function testExceptionNoResponse(): void
  100. {
  101. $message = new Message('foo', ['bar' => 'baz']);
  102. $mockSocket = new MockSocket();
  103. $connection = new Connection($mockSocket);
  104. $responseReader = new ResponseReader($message, $connection);
  105. $this->expectException(NoResponseAvailable::class);
  106. $responseReader->getResponse();
  107. }
  108. }