private function _testAPINewerTimestamp($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $xml = Sync::updated(self::$sessionID); $lastSyncTimestamp = $xml['timestamp']; // Create via sync switch ($objectType) { case 'collection': $keys[] = Sync::createCollection(self::$sessionID, self::$config['libraryID'], "Test", false, $this); break; case 'item': $keys[] = Sync::createItem(self::$sessionID, self::$config['libraryID'], "book", false, $this); break; case 'search': $keys[] = Sync::createSearch(self::$sessionID, self::$config['libraryID'], "Test", 'default', $this); break; } $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&newertime={$lastSyncTimestamp}&format=keys"); $this->assertEquals(200, $response->getStatus()); $responseKeys = explode("\n", trim($response->getBody())); $this->assertCount(sizeOf($keys), $responseKeys); foreach ($keys as $key) { $this->assertContains($key, $responseKeys); } // Should be empty with later timestamp $xml = Sync::updated(self::$sessionID); $lastSyncTimestamp = $xml['timestamp']; $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&newertime=" . ($lastSyncTimestamp + 2) . "&format=keys"); $this->assertEquals(200, $response->getStatus()); $this->assertEquals("", trim($response->getBody())); }
private function _testDeleteAndDeleted($objectType) { API::userClear(self::$config['userID']); $objectTypePlural = API::getPluralObjectType($objectType); $xml = Sync::updated(self::$sessionID); $lastSyncTimestamp = (int) $xml['timestamp']; // Create via sync switch ($objectType) { case 'item': $keys[] = Sync::createItem(self::$sessionID, self::$config['libraryID'], "book", false, $this); break; case 'setting': $settingKey = "tagColors"; $response = API::userPut(self::$config['userID'], "settings/{$settingKey}?key=" . self::$config['apiKey'], json_encode(array("value" => array(array("name" => "_READ", "color" => "#990000")))), array("Content-Type: application/json", "If-Unmodified-Since-Version: 0")); $this->assertEquals(204, $response->getStatus()); $keys[] = $settingKey; break; } // Check via API foreach ($keys as $key) { $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$key}?key=" . self::$config['apiKey']); $this->assertEquals(200, $response->getStatus()); $version = $response->getHeader("Last-Modified-Version"); $this->assertNotNull($version); } // Get empty deleted via API $response = API::userGet(self::$config['userID'], "deleted?key=" . self::$config['apiKey'] . "&newer={$version}"); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertEmpty($json[$objectTypePlural]); // Get empty deleted via API with newertime $response = API::userGet(self::$config['userID'], "deleted?key=" . self::$config['apiKey'] . "&newertime={$lastSyncTimestamp}"); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertEmpty($json[$objectTypePlural]); // Delete via sync foreach ($keys as $key) { switch ($objectType) { case 'item': Sync::deleteItem(self::$sessionID, self::$config['libraryID'], $key, $this); break; case 'setting': // Delete via sync $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $xmlstr = '<data version="9">' . '<deleted>' . '<settings>' . '<setting libraryID="' . self::$config['libraryID'] . '" key="' . $key . '"/>' . '</settings>' . '</deleted>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); Sync::waitForUpload(self::$sessionID, $response, $this); break; } } // Check 404 via API foreach ($keys as $key) { $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$key}?key=" . self::$config['apiKey']); $this->assertEquals(404, $response->getStatus()); } // Get deleted via API $response = API::userGet(self::$config['userID'], "deleted?key=" . self::$config['apiKey'] . "&newer={$version}"); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertArrayHasKey($objectTypePlural, $json); $this->assertCount(sizeOf($keys), $json[$objectTypePlural]); foreach ($keys as $key) { $this->assertContains($key, $json[$objectTypePlural]); } // Get deleted via API with newertime $response = API::userGet(self::$config['userID'], "deleted?key=" . self::$config['apiKey'] . "&newertime={$lastSyncTimestamp}"); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertArrayHasKey($objectTypePlural, $json); $this->assertCount(sizeOf($keys), $json[$objectTypePlural]); foreach ($keys as $key) { $this->assertContains($key, $json[$objectTypePlural]); } // Should be empty with later newertime $xml = Sync::updated(self::$sessionID); $lastSyncTimestamp = (int) $xml['timestamp']; $response = API::userGet(self::$config['userID'], "deleted?key=" . self::$config['apiKey'] . "&newertime=" . ($lastSyncTimestamp + 2)); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertEmpty($json[$objectTypePlural]); }
public function testDateModified() { // In case this is ever extended to other objects $objectType = 'item'; $objectTypePlural = API::getPluralObjectType($objectType); switch ($objectType) { case 'item': $itemData = array("title" => "Test"); $xml = API::createItem("videoRecording", $itemData, $this, 'atom'); break; } $data = API::parseDataFromAtomEntry($xml); $objectKey = $data['key']; $json = json_decode($data['content'], true); $dateModified1 = (string) array_shift($xml->xpath('//atom:entry/atom:updated')); // Make sure we're in the next second sleep(1); // // If no explicit dateModified, use current timestamp // $json['title'] = "Test 2"; $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], json_encode($json)); $this->assert204($response); switch ($objectType) { case 'item': $xml = API::getItemXML($objectKey); break; } $dateModified2 = (string) array_shift($xml->xpath('//atom:entry/atom:updated')); $this->assertNotEquals($dateModified1, $dateModified2); $json = json_decode(API::parseDataFromAtomEntry($xml)['content'], true); // Make sure we're in the next second sleep(1); // // If existing dateModified, use current timestamp // $json['title'] = "Test 3"; $json['dateModified'] = trim(preg_replace("/[TZ]/", " ", $dateModified2)); $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], json_encode($json)); $this->assert204($response); switch ($objectType) { case 'item': $xml = API::getItemXML($objectKey); break; } $dateModified3 = (string) array_shift($xml->xpath('//atom:entry/atom:updated')); $this->assertNotEquals($dateModified2, $dateModified3); $json = json_decode(API::parseDataFromAtomEntry($xml)['content'], true); // // If explicit dateModified, use that // $newDateModified = "2013-03-03 21:33:53"; $json['title'] = "Test 4"; $json['dateModified'] = $newDateModified; $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}?key=" . self::$config['apiKey'], json_encode($json)); $this->assert204($response); switch ($objectType) { case 'item': $xml = API::getItemXML($objectKey); break; } $dateModified4 = (string) array_shift($xml->xpath('//atom:entry/atom:updated')); $this->assertEquals($newDateModified, trim(preg_replace("/[TZ]/", " ", $dateModified4))); }
private function _testObjectKeyParameter($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $xmlArray = array(); switch ($objectType) { case 'collection': $xmlArray[] = API::createCollection("Name", false, $this); $xmlArray[] = API::createCollection("Name", false, $this); break; case 'item': $xmlArray[] = API::createItem("book", false, $this); $xmlArray[] = API::createItem("book", false, $this); break; case 'search': $xmlArray[] = API::createSearch("Name", array(array("condition" => "title", "operator" => "contains", "value" => "test")), $this); $xmlArray[] = API::createSearch("Name", array(array("condition" => "title", "operator" => "contains", "value" => "test")), $this); break; } $keys = array(); foreach ($xmlArray as $xml) { $data = API::parseDataFromAtomEntry($xml); $keys[] = $data['key']; } $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&content=json&{$objectType}Key={$keys[0]}"); $this->assert200($response); $this->assertNumResults(1, $response); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $this->assertEquals($keys[0], $data['key']); $response = API::userGet(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'] . "&content=json&{$objectType}Key={$keys[0]},{$keys[1]}&order={$objectType}KeyList"); $this->assert200($response); $this->assertNumResults(2, $response); $xml = API::getXMLFromResponse($response); $xpath = $xml->xpath('//atom:entry/zapi:key'); $key = (string) array_shift($xpath); $this->assertEquals($keys[0], $key); $key = (string) array_shift($xpath); $this->assertEquals($keys[1], $key); }
private function _testUploadUnmodified($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); switch ($objectType) { case 'collection': $xml = API::createCollection("Name", false, $this); break; case 'item': $xml = API::createItem("book", array("title" => "Title"), $this); break; case 'search': $xml = API::createSearch("Name", 'default', $this); break; } $version = (int) array_shift($xml->xpath('//atom:entry/zapi:version')); $this->assertNotEquals(0, $version); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$data['key']}?key=" . self::$config['apiKey'], json_encode($json)); $this->assert204($response); $this->assertEquals($version, $response->getHeader("Last-Modified-Version")); switch ($objectType) { case 'collection': $xml = API::getCollectionXML($data['key']); break; case 'item': $xml = API::getItemXML($data['key']); break; case 'search': $xml = API::getSearchXML($data['key']); break; } $data = API::parseDataFromAtomEntry($xml); $this->assertEquals($version, $data['version']); }
private function _testMultiObjectWriteInvalidObject($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode([[]]), array("Content-Type: application/json")); $this->assert400($response, "Uploaded data must be a JSON object"); $response = API::userPost(self::$config['userID'], "{$objectTypePlural}?key=" . self::$config['apiKey'], json_encode(array("{$objectTypePlural}" => array("foo" => "bar"))), array("Content-Type: application/json")); $this->assert400($response, "'{$objectTypePlural}' must be an array"); }