Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 151
0.00% covered (danger)
0.00%
0 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
ClientIdTest
0.00% covered (danger)
0.00%
0 / 150
0.00% covered (danger)
0.00%
0 / 13
182
0.00% covered (danger)
0.00%
0 / 1
 setUpBeforeClass
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 tearDownAfterClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 testInitWithKeyAndClientId
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 testInitWithWildcardClientId
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 testGetClientIdNull
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
2
 testGetClientIdNonNull
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
2
 testWildcardClientIdMsg
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
2
 testClientIdLib
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
2
 testClientIdPrecedence
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 testRSA8f1
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 testRSA8f2
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 testRSA8f3
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 testRSA8f4
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace tests;
3use Ably\AblyRest;
4use Ably\Models\Message;
5use Ably\Models\TokenParams;
6
7require_once __DIR__ . '/factories/TestApp.php';
8
9class ClientIdTest extends \PHPUnit_Framework_TestCase {
10
11    protected static $testApp;
12    protected static $defaultOptions;
13
14    public static function setUpBeforeClass() {
15        self::$testApp = new TestApp();
16        self::$defaultOptions = self::$testApp->getOptions();
17    }
18
19    public static function tearDownAfterClass() {
20        self::$testApp->release();
21    }
22
23    /**
24     * Init library with a key and clientId; expect token auth to be chosen; expect Auth::clientId to return the id
25     */
26    public function testInitWithKeyAndClientId() {
27        $ably = new AblyRest( array_merge( self::$defaultOptions, [
28            'key'      => self::$testApp->getAppKeyDefault()->string,
29            'clientId' => 'testClientId',
30        ] ) );
31
32        $this->assertFalse( $ably->auth->isUsingBasicAuth(), 'Expected token auth to be used' );
33
34        $ably->auth->authorize();
35        $this->assertEquals( 'testClientId', $ably->auth->clientId, 'Expected clientId result to match the provided id' );
36        $this->assertEquals( 'testClientId', $ably->auth->getTokenDetails()->clientId, 'Expected clientId in tokenDetails to match the provided id' );
37    }
38
39    /**
40     * Init library with a key and a wildcard clientId; this should throw an exception as wildcard is not allowed here
41     */
42    public function testInitWithWildcardClientId() {
43        $this->setExpectedException( 'Ably\Exceptions\AblyException', '', 40003 );
44
45        $ably = new AblyRest( array_merge( self::$defaultOptions, [
46            'key'      => self::$testApp->getAppKeyDefault()->string,
47            'clientId' => '*',
48        ] ) );
49    }
50
51    /**
52     * Check is Auth::clientId is returning expected null values
53     */
54    public function testGetClientIdNull() {
55        // no clientId provided anywhere, should be null
56        $ably = new AblyRest( array_merge( self::$defaultOptions, [
57            'key' => self::$testApp->getAppKeyDefault()->string,
58        ] ) );
59
60        $ably->auth->authorize(); // switch to token based auth
61
62        $this->assertNull( $ably->auth->getTokenDetails()->clientId, 'Expected tokenDetails clientId to be null' );
63        $this->assertNull( $ably->auth->clientId, 'Expected clientId to be null' );
64
65        // test not yet authorised lib without a clientId specified on ClientOptions
66        $ablyImplicitCId = new AblyRest( array_merge( self::$defaultOptions, [
67            'key' => self::$testApp->getAppKeyDefault()->string,
68            'defaultTokenParams' => new TokenParams( [
69                'clientId' => 'testClientId',
70            ] ),
71        ] ) );
72
73        $this->assertNull( $ablyImplicitCId->auth->clientId, 'Expected clientId to be null prior to authorising' );
74
75        $ablyImplicitCId->auth->authorize();
76
77        $this->assertEquals( 'testClientId', $ablyImplicitCId->auth->clientId, 'Expected clientId to match after authorising' );
78    }
79
80    /**
81     * Check is Auth::clientId is returning expected non null values
82     */
83    public function testGetClientIdNonNull() {
84        // test wildcard clientId provided via tokenDetails
85        $ablyKey = new AblyRest( array_merge( self::$defaultOptions, [
86            'key' => self::$testApp->getAppKeyDefault()->string,
87        ] ) );
88
89        $wildcardToken = $ablyKey->auth->requestToken( [ 'clientId' => '*' ] );
90
91        $ablyWildcard = new AblyRest( array_merge( self::$defaultOptions, [
92            'tokenDetails' => $wildcardToken,
93        ] ) );
94
95        $this->assertEquals( '*', $ablyWildcard->auth->getTokenDetails()->clientId, 'Expected tokenDetails clientId to be *' );
96        $this->assertEquals( '*', $ablyWildcard->auth->clientId, 'Expected clientId to be *' );
97
98        // test specified clientId specified in ClientOptions
99        $ablyCid = new AblyRest( array_merge( self::$defaultOptions, [
100            'key' => self::$testApp->getAppKeyDefault()->string,
101            'clientId' => 'testClientId',
102        ] ) );
103
104        $this->assertEquals( 'testClientId', $ablyCid->auth->clientId );
105
106        // test clientId overridden by authOptions
107        $ablyCid->auth->authorize( [], [ 'clientId' => 'overriddenClientId_authOptions' ] );
108        $this->assertEquals( 'overriddenClientId_authOptions', $ablyCid->auth->clientId );
109
110        // test clientId overridden by tokenParams
111        $ablyCid->auth->authorize( [ 'clientId' => 'overriddenClientId_tokenParams' ] );
112        $this->assertEquals( 'overriddenClientId_tokenParams', $ablyCid->auth->clientId );
113    }
114
115    /**
116     * Check if messages can be assigned a clientId with a wildcard lib instance
117     */
118    public function testWildcardClientIdMsg() {
119        $ablyKey = new AblyRest( array_merge( self::$defaultOptions, [
120            'key' => self::$testApp->getAppKeyDefault()->string,
121        ] ) );
122
123        $wildcardToken = $ablyKey->auth->requestToken( [ 'clientId' => '*' ] );
124
125        $ablyWildcard = new AblyRest( array_merge( self::$defaultOptions, [
126            'tokenDetails' => $wildcardToken,
127        ] ) );
128
129        $clientId = 'testClientId';
130        $msg = new Message();
131        $msg->data = 'test';
132        $msg->clientId = $clientId;
133
134        $keyChan = $ablyKey->channels->get( 'persisted:clientIdTestKey' );
135        $keyChan->publish( $msg );
136        $retrievedMsg = $keyChan->history()->items[0];
137
138        $this->assertEquals( $clientId, $retrievedMsg->clientId, 'Expected clientIds to match');
139        
140        $tokenChan = $ablyWildcard->channels->get( 'persisted:clientIdTestToken' );
141        $tokenChan->publish( $msg );
142        $retrievedMsg = $tokenChan->history()->items[0];
143
144        $this->assertEquals( $clientId, $retrievedMsg->clientId, 'Expected clientIds to match');
145    }
146
147    /**
148     * Check if messages are assigned a clientID automatically with a non-anonymous lib instance
149     * Verify that clientID mismatch produces an exception within the library
150     */
151    public function testClientIdLib() {
152        $clientId = 'testClientId';
153
154        $ablyCId = new AblyRest( array_merge( self::$defaultOptions, [
155            'key' => self::$testApp->getAppKeyDefault()->string,
156            'clientId' => $clientId,
157        ] ) );
158
159        $this->assertEquals( $clientId, $ablyCId->auth->clientId, 'Expected a token with specified clientId to be used' );
160
161        $msg = new Message();
162        $msg->data = 'test';
163
164        $channel = $ablyCId->channels->get( 'persisted:clientIdTestLib' );
165        $channel->publish( $msg );
166        $retrievedMsg = $channel->history()->items[0];
167
168        $this->assertEquals( $clientId, $retrievedMsg->clientId, 'Expected clientIds to match');
169        $this->assertFalse( $ablyCId->auth->isUsingBasicAuth(), 'Expected library to switch to token auth');
170        $this->assertEquals( $clientId, $ablyCId->auth->getTokenDetails()->clientId, 'Expected auth token to be bound to the provided clientId');
171
172        $msg = new Message();
173        $msg->data = 'test';
174        $msg->clientId = 'testClientId';
175
176        $channel = $ablyCId->channels->get( 'persisted:clientIdTestLib' );
177        $channel->publish( $msg ); // matching clientIds, this should work
178
179        $msg = new Message();
180        $msg->data = 'test';
181        $msg->clientId = 'DIFFERENT_clientId';
182
183        $this->setExpectedException( 'Ably\Exceptions\AblyException', '', 40102 );
184        $channel->publish( $msg ); // mismatched clientIds, should throw an exception
185    }
186
187    /**
188     * (RSA7a4) When a clientId value is provided in both ClientOptions#clientId and ClientOptions#defaultTokenParams,
189     * the ClientOptions#clientId takes precendence and is used for all Auth operations 
190     */
191    public function testClientIdPrecedence() {
192        $ablyCId = new AblyRest( array_merge( self::$defaultOptions, [
193            'key' => self::$testApp->getAppKeyDefault()->string,
194            'useTokenAuth' => true,
195            'clientId' => 'overriddenClientId',
196            'defaultTokenParams' => new TokenParams( [
197                'clientId' => 'tokenParamsClientId',
198            ] ),
199        ] ) );
200
201        $ablyCId->auth->authorize(); // obtain a token
202        $this->assertEquals( 'overriddenClientId', $ablyCId->auth->clientId, 'Expected defaultTokenParams to override provided clientId' );
203
204        $channel = $ablyCId->channels->get( 'persisted:testClientIdPrecedence' );
205        $channel->publish( 'testEvent', 'testData' );
206
207        $this->assertEquals( 'overriddenClientId', $channel->history()->items[0]->clientId, 'Expected message clientId to match' );
208    }
209
210    /**
211     * (RSA8f1) Request a token with a null value clientId, authenticate a client with the token,
212     * publish a message without an explicit clientId, and ensure the message published does not
213     * have a clientId. Check that Auth#clientId is null   
214     */
215    public function testRSA8f1() {
216        $ablyMain = new AblyRest( array_merge( self::$defaultOptions, [
217            'key' => self::$testApp->getAppKeyDefault()->string,
218        ] ) );
219
220        $tokenDetails = $ablyMain->auth->requestToken();
221
222        $ablyClient = new AblyRest( array_merge( self::$defaultOptions, [
223            'tokenDetails' => $tokenDetails,
224        ] ) );
225
226        $channel = $ablyClient->channels->get( 'persisted:RSA8f1' );
227        $channel->publish( 'testEvent', 'testData' );
228
229        $this->assertNull( $ablyClient->auth->clientId, 'Expected clientId to be null' );
230        $this->assertNull( $channel->history()->items[0]->clientId, 'Expected message not to have a clientId' );
231        $this->assertEquals( 'testData', $channel->history()->items[0]->data, 'Expected message payload to match' );
232    }
233
234    /**
235     * (RSA8f2) Request a token with a null value clientId, authenticate a client with the token,
236     * publish a message with an explicit clientId value, and ensure that the message is rejected    
237     */
238    public function testRSA8f2() {
239        $ablyMain = new AblyRest( array_merge( self::$defaultOptions, [
240            'key' => self::$testApp->getAppKeyDefault()->string,
241        ] ) );
242
243        $tokenDetails = $ablyMain->auth->requestToken();
244
245        $ablyClient = new AblyRest( array_merge( self::$defaultOptions, [
246            'tokenDetails' => $tokenDetails,
247        ] ) );
248
249        $channel = $ablyClient->channels->get( 'persisted:RSA8f2' );
250
251        $this->setExpectedException( 'Ably\Exceptions\AblyException', '', 40102 );
252        $channel->publish( 'testEvent', 'testData', 'testClientId' );
253    }
254
255    /**
256     * (RSA8f3) Request a token with a wildcard '*' value clientId, authenticate a client with the token,
257     * publish a message without an explicit clientId, and ensure the message published does not have
258     * a clientId. Check that Auth#clientId is a string with value '*'.
259     */
260    public function testRSA8f3() {
261        $ablyMain = new AblyRest( array_merge( self::$defaultOptions, [
262            'key' => self::$testApp->getAppKeyDefault()->string,
263        ] ) );
264
265        $tokenDetails = $ablyMain->auth->requestToken( [ 'clientId' => '*' ] );
266
267        $ablyClient = new AblyRest( array_merge( self::$defaultOptions, [
268            'tokenDetails' => $tokenDetails,
269        ] ) );
270
271        $channel = $ablyClient->channels->get( 'persisted:RSA8f3' );
272        $channel->publish( 'testEvent', 'testData' );
273
274        $this->assertEquals( '*', $ablyClient->auth->clientId, 'Expected clientId to be null' );
275        $this->assertNull( $channel->history()->items[0]->clientId, 'Expected message not to have a clientId' );
276        $this->assertEquals( 'testData', $channel->history()->items[0]->data, 'Expected message payload to match' );
277    }
278
279    /**
280     * (RSA8f4) Request a token with a wildcard '*' value clientId, authenticate a client with the token,
281     * publish a message with an explicit clientId value, and ensure that the message published has
282     * the provided clientId
283     */
284    public function testRSA8f4() {
285        $ablyMain = new AblyRest( array_merge( self::$defaultOptions, [
286            'key' => self::$testApp->getAppKeyDefault()->string,
287        ] ) );
288
289        $tokenDetails = $ablyMain->auth->requestToken( [ 'clientId' => '*' ] );
290
291        $ablyClient = new AblyRest( array_merge( self::$defaultOptions, [
292            'tokenDetails' => $tokenDetails,
293        ] ) );
294
295        $channel = $ablyClient->channels->get( 'persisted:RSA8f4' );
296        $channel->publish( 'testEvent', 'testData', 'testClientId' );
297
298        $this->assertEquals( 'testClientId', $channel->history()->items[0]->clientId, 'Expected message clientId to match' );
299        $this->assertEquals( 'testData', $channel->history()->items[0]->data, 'Expected message payload to match' );
300    }
301}