Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
PresenceTest
0.00% covered (danger)
0.00%
0 / 94
0.00% covered (danger)
0.00%
0 / 7
342
0.00% covered (danger)
0.00%
0 / 1
 setUpBeforeClass
0.00% covered (danger)
0.00%
0 / 20
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
 testComparePresenceDataWithFixture
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 testComparePresenceHistoryWithFixture
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
20
 testPresenceHistoryTimeRange
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
30
 testComparePresenceDataWithFixtureEncrypted
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 testFilters
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace tests;
3use Ably\AblyRest;
4use Ably\Exceptions\AblyRequestException;
5use Ably\Utils\Crypto;
6
7require_once __DIR__ . '/factories/TestApp.php';
8
9class PresenceTest extends \PHPUnit_Framework_TestCase {
10
11    protected static $testApp;
12    protected static $defaultOptions;
13    protected static $ably;
14
15    protected static $presenceFixture;
16    protected static $channel;
17
18    public static function setUpBeforeClass() {
19
20        self::$testApp = new TestApp();
21        self::$defaultOptions = self::$testApp->getOptions();
22        self::$ably = new AblyRest( array_merge( self::$defaultOptions, [
23            'key' => self::$testApp->getAppKeyDefault()->string,
24        ] ) );
25
26        $fixture = self::$testApp->getFixture();
27        self::$presenceFixture = $fixture->post_apps->channels[0]->presence;
28
29        $cipherParams = Crypto::getDefaultParams([
30            'key'       => $fixture->cipher->key,
31            'algorithm' => $fixture->cipher->algorithm,
32            'keyLength' => $fixture->cipher->keylength,
33            'mode'      => $fixture->cipher->mode,
34            'iv'        => $fixture->cipher->iv,
35            'base64Key' => true,
36            'base64Iv' => true,
37        ]);
38
39        $options = [
40            'cipher' => $cipherParams,
41        ];
42
43        self::$channel = self::$ably->channel('persisted:presence_fixtures', $options);
44    }
45
46    public static function tearDownAfterClass() {
47        self::$testApp->release();
48    }
49
50    /**
51     * Compare presence data with fixture
52     */
53    public function testComparePresenceDataWithFixture() {
54        $presence = self::$channel->presence->get();
55
56        // verify presence existence and count
57        $this->assertNotNull( $presence, 'Expected non-null presence data' );
58        $this->assertEquals( 6, count($presence->items), 'Expected 6 presence messages' );
59
60        // verify presence contents
61        $fixturePresenceMap = [];
62        foreach (self::$presenceFixture as $entry) {
63            $fixturePresenceMap[$entry->clientId] = $entry->data;
64        }
65
66        foreach ($presence->items as $entry) {
67            $this->assertNotNull( $entry->clientId, 'Expected non-null client ID' );
68            $this->assertTrue(
69                array_key_exists($entry->clientId, $fixturePresenceMap) && $fixturePresenceMap[$entry->clientId] == $entry->originalData,
70                'Expected presence contents to match'
71            );
72        }
73
74        // verify limit / pagination
75        $firstPage = self::$channel->presence->get( [ 'limit' => 3, 'direction' => 'forwards' ] );
76
77        $this->assertEquals( 3, count($firstPage->items), 'Expected 3 presence entries on the 1st page' );
78
79        $nextPage = $firstPage->next();
80        $this->assertEquals( 3, count($nextPage->items), 'Expected 3 presence entries on the 2nd page' );
81        $this->assertTrue( $nextPage->isLast(), 'Expected last page' );
82    }
83
84    /**
85     * Compare presence history with fixture
86     */
87    public function testComparePresenceHistoryWithFixture() {
88        $history = self::$channel->presence->history();
89
90        // verify history existence and count
91        $this->assertNotNull( $history, 'Expected non-null history data' );
92        $this->assertEquals( 6, count($history->items), 'Expected 6 history entries' );
93
94        // verify history contents
95        $fixtureHistoryMap = [];
96        foreach (self::$presenceFixture as $entry) {
97            $fixtureHistoryMap[$entry->clientId] = $entry->data;
98        }
99
100        foreach ($history->items as $entry) {
101            $this->assertNotNull( $entry->clientId, 'Expected non-null client ID' );
102            $this->assertTrue(
103                isset($fixtureHistoryMap[$entry->clientId]) && $fixtureHistoryMap[$entry->clientId] == $entry->originalData,
104                'Expected presence contents to match'
105            );
106        }
107
108        // verify limit / pagination - forwards
109        $firstPage = self::$channel->presence->history( [ 'limit' => 3, 'direction' => 'forwards' ] );
110
111        $this->assertEquals( 3, count($firstPage->items), 'Expected 3 presence entries' );
112
113        $nextPage = $firstPage->next();
114
115        $this->assertEquals( self::$presenceFixture[0]->clientId, $firstPage->items[0]->clientId, 'Expected least recent presence activity to be the first' );
116        $this->assertEquals( self::$presenceFixture[5]->clientId, $nextPage->items[2]->clientId, 'Expected most recent presence activity to be the last' );
117
118        // verify limit / pagination - backwards (default)
119        $firstPage = self::$channel->presence->history( [ 'limit' => 3 ] );
120
121        $this->assertEquals( 3, count($firstPage->items), 'Expected 3 presence entries' );
122
123        $nextPage = $firstPage->next();
124
125        $this->assertEquals( self::$presenceFixture[5]->clientId, $firstPage->items[0]->clientId, 'Expected most recent presence activity to be the first' );
126        $this->assertEquals( self::$presenceFixture[0]->clientId, $nextPage->items[2]->clientId, 'Expected least recent presence activity to be the last' );
127    }
128
129    /*
130     * Check whether time range queries work properly
131     */
132    public function testPresenceHistoryTimeRange() {
133        // ensure some time has passed since mock presence data was sent
134        $delay = 1000; // sleep for 1000ms
135        usleep($delay * 1000); // in microseconds
136
137        $timeOffset = self::$ably->time() - self::$ably->systemTime();
138        $now = $timeOffset + self::$ably->systemTime();
139
140        // test with start parameter
141        try {
142            $history = self::$channel->presence->history( [ 'start' => $now ] );
143            $this->assertEquals( 0, count($history->items), 'Expected 0 presence messages' );
144        } catch (AblyRequestException $e) {
145            $this->fail( 'Start parameter - ' . $e->getMessage() . ', HTTP code: ' . $e->getCode() );
146        }
147
148        // test with end parameter
149        try {
150            $history = self::$channel->presence->history( [ 'end' => $now ] );
151            $this->assertEquals( 6, count($history->items), 'Expected 6 presence messages' );
152        } catch (AblyRequestException $e) {
153            $this->fail( 'End parameter - ' . $e->getMessage() . ', HTTP code: ' . $e->getCode() );
154        }
155
156        // test with both start and end parameters - time range: ($now - 500ms) ... $now
157        try {
158            $history = self::$channel->presence->history( [ 'start' => $now - ($delay / 2), 'end' => $now ] );
159            $this->assertEquals( 0, count($history->items), 'Expected 0 presence messages' );
160        } catch (AblyRequestException $e) {
161            $this->fail( 'Start + end parameter - ' . $e->getMessage() . ', HTTP code: ' . $e->getCode() );
162        }
163
164        // test ISO 8601 date format
165        try {
166            $history = self::$channel->presence->history( [ 'end' => gmdate('c', $now / 1000) ] );
167            $this->assertEquals( 6, count($history->items), 'Expected 6 presence messages' );
168        } catch (AblyRequestException $e) {
169            $this->fail( 'ISO format: ' . $e->getMessage() . ', HTTP code: ' . $e->getCode() );
170        }
171    }
172
173    /**
174     * Compare presence data with fixture
175     */
176    public function testComparePresenceDataWithFixtureEncrypted() {
177        $presence = self::$channel->presence->get();
178
179        // verify presence existence and count
180        $this->assertNotNull( $presence, 'Expected non-null presence data' );
181        $this->assertEquals( 6, count($presence->items), 'Expected 6 presence messages' );
182
183        // verify presence contents
184        $messageMap = [];
185        foreach ($presence->items as $entry) {
186            $messageMap[$entry->clientId] = $entry->data;
187        }
188
189        $this->assertEquals( $messageMap['client_decoded'], $messageMap['client_encoded'], 'Expected decrypted and sample data to match' );
190    }
191
192    /**
193     * Ensure clientId and connectionId filters on Presence GET works
194     */
195    public function testFilters() {
196        $presenceClientFilter = self::$channel->presence->get( [ 'clientId' => 'client_string' ] );
197        $this->assertEquals( 1, count($presenceClientFilter->items), 'Expected the clientId filter to return 1 user' );
198
199        $connId = $presenceClientFilter->items[0]->connectionId;
200
201        $presenceConnFilter1 = self::$channel->presence->get( [ 'connectionId' => $connId ] );
202        $this->assertEquals( 6, count($presenceConnFilter1->items), 'Expected the connectionId filter to return 6 users' );
203
204        $presenceConnFilter2 = self::$channel->presence->get( [ 'connectionId' => '*FAKE CONNECTION ID*' ] );
205        $this->assertEquals( 0, count($presenceConnFilter2->items), 'Expected the connectionId filter to return no users' );
206    }
207}