Completed
Push — master ( d312aa...bbe9f1 )
by Sam
03:12
created

ClientManagerTest::testConnectedClients()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Jalle19\StatusManager\Test\Manager;
4
5
use Jalle19\StatusManager\Event\Events;
6
use Jalle19\StatusManager\Event\InstanceStatusUpdatesEvent;
7
use Jalle19\StatusManager\Instance\InstanceStatusCollection;
8
use Jalle19\StatusManager\Message\Request\AuthenticationRequest;
9
use Jalle19\StatusManager\Message\Response\AuthenticationResponse;
10
use Ratchet\ConnectionInterface;
11
use React\EventLoop\Factory as EventLoopFactory;
12
13
/**
14
 * Class ClientManagerTest
15
 * @package   Jalle19\StatusManager\Test\Manager
16
 * @copyright Copyright &copy; Sam Stenvall 2016-
17
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
18
 */
19
class ClientManagerTest extends AbstractManagerTest
20
{
21
22
	/**
23
	 * @var DummyClientManager
24
	 */
25
	private $_manager;
26
27
	/**
28
	 * @var \PHPUnit_Framework_MockObject_MockObject|ConnectionInterface
29
	 */
30
	private $_clientMock;
31
32
	/**
33
	 * @var \PHPUnit_Framework_MockObject_MockObject|ConnectionInterface
34
	 */
35
	private $_anotherClientMock;
36
37
38
	/**
39
	 * @inheritdoc
40
	 */
41
	protected function setUp()
42
	{
43
		$this->_manager = new DummyClientManager($this->configuration, $this->logger, $this->eventDispatcher,
44
			EventLoopFactory::create());
0 ignored issues
show
Unused Code introduced by
The call to DummyClientManager::__construct() has too many arguments starting with \React\EventLoop\Factory::create().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
45
46
		// Create two clients and connect them
47
		$this->_clientMock = $this->getMockBuilder(ConnectionInterface::class)
48
		                          ->setMethods(['send', 'close'])
49
		                          ->getMock();
50
51
		$this->_anotherClientMock = clone $this->_clientMock;
52
53
		// Connect the clients
54
		$this->_manager->onOpen($this->_clientMock);
55
		$this->_manager->onOpen($this->_anotherClientMock);
56
57
		// Wire the event and message handling
58
		$this->eventDispatcher->addSubscriber($this->_manager);
59
		$this->_manager->registerMessageHandler($this->_manager);
60
	}
61
62
63
	/**
64
	 * Tests that clients are properly registered as connected
65
	 */
66
	public function testConnectedClients()
67
	{
68
		$this->assertEquals(2, $this->_manager->getConnectedClients()->count());
69
	}
70
71
72
	/**
73
	 * Tests that clients can only be authenticated with the correct access token
74
	 */
75
	public function testAuthentication()
76
	{
77
		// Authenticate the first client, check for success
78
		$response = $this->_manager->handleMessage(
79
			new AuthenticationRequest($this->configuration->getAccessToken()),
80
			$this->_clientMock);
81
82
		/* @var AuthenticationResponse $response */
83
		$this->assertEquals(AuthenticationResponse::STATUS_SUCCESS, $response->getStatus());
84
85
		// Authenticate the second client, check for failure
86
		$response = $this->_manager->handleMessage(
87
			new AuthenticationRequest('very invalid token'),
88
			$this->_anotherClientMock);
89
90
		/* @var AuthenticationResponse $response */
91
		$this->assertEquals(AuthenticationResponse::STATUS_FAILURE, $response->getStatus());
92
93
		$this->assertEquals(1, $this->_manager->getAuthenticatedClients()->count());
94
	}
95
96
97
	/**
98
	 * Tests that instance status updates are broadcast to all authenticated clients and not to those that are just
99
	 * connected but not authenticated
100
	 */
101
	public function testHandleStatusUpdates()
102
	{
103
		$this->_manager->handleMessage(
104
			new AuthenticationRequest($this->configuration->getAccessToken()),
105
			$this->_clientMock);
106
107
		$this->_clientMock->expects($this->once())->method('send');
1 ignored issue
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Ratchet\ConnectionInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
108
		$this->_anotherClientMock->expects($this->never())->method('send');
109
110
		$this->eventDispatcher->dispatch(Events::INSTANCE_STATUS_UPDATES, new InstanceStatusUpdatesEvent(
111
			new InstanceStatusCollection()
112
		));
113
	}
114
115
116
	/**
117
	 * Tests that requests from clients are sent back as responses
118
	 */
119
	public function testMessageHandling()
120
	{
121
		$authenticationRequest = new AuthenticationRequest($this->configuration->getAccessToken());
122
123
		// Authenticate the client
124
		$this->_manager->handleMessage($authenticationRequest, $this->_clientMock);
125
126
		$expectedResponse = new AuthenticationResponse(AuthenticationResponse::STATUS_SUCCESS);
127
		$this->_clientMock->expects($this->once())->method('send')->with(json_encode($expectedResponse));
1 ignored issue
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Ratchet\ConnectionInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
128
129
		$this->_manager->onMessage($this->_clientMock, json_encode($authenticationRequest));
130
	}
131
132
}
133