Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
255 lines (199 sloc) 8.68 KB
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\User, App\Source, App\Channel, App\Entry;
class PagingTest extends TestCase
{
use RefreshDatabase;
private function _microsub($user_id, $params) {
return $this->withHeaders([
'Authorization' => 'Bearer 1234'
])->get('/microsub/'.$user_id.'?'.http_build_query($params));
}
public function testPagingWithBatchOrdering() {
$user = factory(User::class)->create();
$channel = $user->channels()->where('user_id', $user->id)->where('uid', '!=', 'notifications')->first();
Cache::shouldReceive('get')
->with('token:1234')
->andReturn('{"scope": ["create", "update", "media", "read"], "client_id": "https://aperture.p3k.io", "me": "https://aaronparecki.com/","user_id": '.$user->id.'}');
$source = factory(Source::class)->create();
// Generate 30 entries all with the same created_at date
$entries = [];
for($i=30; $i>=1; $i--) {
$date = '2017-10-01 08:00:00';
$published = '2017-12-'.sprintf('%02d',$i).' 08:00:00';
$entries[] = factory(Entry::class)->create([
'source_id' => $source->id,
'published' => $published,
'created_at' => $date,
'updated_at' => $date,
]);
}
// Add all the entries to the channel with different batch_orders
foreach($entries as $i=>$entry) {
$channel->entries()->attach($entry->id, ['created_at'=>$entry->created_at, 'batch_order'=>$i]);
}
// Retrieve the latest 20 entries
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 5
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
$this->assertCount(5, $data['items']);
// Check the timestamps of the first and last item
$this->assertEquals('2017-12-30T08:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-12-26T08:00:00+00:00', $data['items'][4]['published']);
$this->assertArrayHasKey('before', $data['paging']);
$this->assertArrayHasKey('after', $data['paging']);
$before = $data['paging']['before'];
$after = $data['paging']['after'];
// Fetch the next page of data
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 5,
'after' => $after
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
// The next 5 items should be returned
$this->assertCount(5, $data['items']);
// Check the timestamps of the first and last item
$this->assertEquals('2017-12-25T08:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-12-21T08:00:00+00:00', $data['items'][4]['published']);
}
public function testPagingParameters()
{
$user = factory(User::class)->create();
$channel = $user->channels()->where('user_id', $user->id)->where('uid', '!=', 'notifications')->first();
Cache::shouldReceive('get')
->with('token:1234')
->andReturn('{"scope": ["create", "update", "media", "read"], "client_id": "https://aperture.p3k.io", "me": "https://aaronparecki.com/","user_id": '.$user->id.'}');
$source = factory(Source::class)->create();
// Generate 30 entries all dated different days in October
$entries = [];
for($i=30; $i>=1; $i--) {
$date = '2017-10-'.sprintf('%02d',$i).' 08:00:00';
$entries[] = factory(Entry::class)->create([
'source_id' => $source->id,
'published' => $date,
'created_at' => $date,
'updated_at' => $date,
]);
}
// Add all the entries to the channel
foreach($entries as $i=>$entry) {
$channel->entries()->attach($entry->id, ['created_at'=>$entry->created_at, 'batch_order'=>0]);
}
// Retrieve the latest 20 entries
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 20
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
$this->assertCount(20, $data['items']);
// Check the timestamps of the first and last item
$this->assertEquals('2017-10-30T08:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-10-11T08:00:00+00:00', $data['items'][19]['published']);
// Make sure both "before" and "after" cursors are returned
$this->assertArrayHasKey('before', $data['paging']);
$this->assertArrayHasKey('after', $data['paging']);
$before = $data['paging']['before'];
$after = $data['paging']['after'];
// Fetch the next page of data
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 20,
'after' => $after
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
// The remaining 10 items should be returned
$this->assertCount(10, $data['items']);
// Check the timestamps of the first and last item
$this->assertEquals('2017-10-10T08:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-10-01T08:00:00+00:00', $data['items'][9]['published']);
// There should not be an "after" page since this is the end of the list
$this->assertArrayNotHasKey('after', $data['paging']);
// There should not be a "before" page since it would be the same as the "after" parameter provided in the request
$this->assertArrayNotHasKey('before', $data['paging']);
// Poll for new items, there should be none
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 20,
'before' => $before
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
$this->assertCount(0, $data['items']);
$this->assertArrayNotHasKey('after', $data['paging']);
$this->assertArrayNotHasKey('before', $data['paging']);
// Add 30 new entries newer than the existing ones
// Generate 30 entries all dated different days in November
$entries = [];
for($i=30; $i>=1; $i--) {
$date = '2017-11-'.sprintf('%02d',$i).' 07:00:00';
$entries[] = factory(Entry::class)->create([
'source_id' => $source->id,
'published' => $date,
'created_at' => $date,
'updated_at' => $date,
]);
}
// Add all the entries to the channel
foreach($entries as $i=>$entry) {
$channel->entries()->attach($entry->id, ['created_at'=>$entry->created_at, 'batch_order'=>0]);
}
// Request newer items in the timeline using the previously stored "before"
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 20,
'before' => $before,
]);
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
$this->assertCount(20, $data['items']);
// Check the timestamps of the first and last item
$this->assertEquals('2017-11-30T07:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-11-11T07:00:00+00:00', $data['items'][19]['published']);
// Make sure both "before" and "after" cursors are returned
$this->assertArrayHasKey('before', $data['paging']);
$this->assertArrayHasKey('after', $data['paging']);
// Use the new "after" and make a request to load the next set
$after = $data['paging']['after'];
$response = $this->_microsub($user->id, [
'action' => 'timeline',
'channel' => $channel->uid,
'limit' => 20,
'before' => $before, // use the same "before" we used previously
'after' => $after // use the new "after"
]);
echo "\nREQUEST FOR NEW PAGE\n";
echo "\nBEFORE: $before\nAFTER: $after\n\n";
$response->assertStatus(200);
$data = json_decode($response->content(), true);
$this->assertArrayHasKey('items', $data);
// The remaining 10 items should be returned, none from October
$this->assertCount(10, $data['items']);
$this->assertEquals('2017-11-10T07:00:00+00:00', $data['items'][0]['published']);
$this->assertEquals('2017-11-01T07:00:00+00:00', $data['items'][9]['published']);
// There should not be a "before" or "after" paging response since no more items can be fetched
$this->assertArrayNotHasKey('after', $data['paging']);
$this->assertArrayNotHasKey('before', $data['paging']);
}
}