public function testModifyItemNotification() { $json = API::createItem("book", false, $this, 'jsonData'); $json['title'] = 'test'; $response = API::userPut(self::$config['userID'], "items/{$json['key']}", json_encode($json)); $this->assertCountNotifications(1, $response); $this->assertHasNotification(['event' => 'topicUpdated', 'topic' => '/users/' . self::$config['userID']], $response); }
/** * @depends testNewSearch */ public function testModifySearch($data) { $key = $data['key']; $version = $data['version']; // Remove one search condition array_shift($data['conditions']); $name = $data['name']; $conditions = $data['conditions']; $response = API::userPut(self::$config['userID'], "searches/{$key}", json_encode($data), array("Content-Type: application/json", "If-Unmodified-Since-Version: {$version}")); $this->assert204($response); $data = API::getSearch($key, $this, 'json')['data']; $this->assertEquals($name, (string) $data['name']); $this->assertInternalType('array', $data['conditions']); $this->assertCount(sizeOf($conditions), $data['conditions']); foreach ($conditions as $i => $condition) { foreach ($condition as $key => $val) { $this->assertEquals($val, $data['conditions'][$i][$key]); } } }
public function testCreatorSummaryAtom() { $xml = API::createItem("book", array("creators" => array(array("creatorType" => "author", "name" => "Test"))), $this, 'atom'); $data = API::parseDataFromAtomEntry($xml); $itemKey = $data['key']; $json = json_decode($data['content'], true); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("Test", $creatorSummary); $json['creators'][] = array("creatorType" => "author", "firstName" => "Alice", "lastName" => "Foo"); $response = API::userPut(self::$config['userID'], "items/{$itemKey}", json_encode($json)); $this->assert204($response); $xml = API::getItemXML($itemKey); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("Test and Foo", $creatorSummary); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content'], true); $json['creators'][] = array("creatorType" => "author", "firstName" => "Bob", "lastName" => "Bar"); $response = API::userPut(self::$config['userID'], "items/{$itemKey}", json_encode($json)); $this->assert204($response); $xml = API::getItemXML($itemKey); $creatorSummary = (string) array_shift($xml->xpath('//atom:entry/zapi:creatorSummary')); $this->assertEquals("Test et al.", $creatorSummary); }
private function _testUploadUnmodified($objectType) { $objectTypePlural = API::getPluralObjectType($objectType); switch ($objectType) { case 'collection': $data = API::createCollection("Name", false, $this, 'jsonData'); break; case 'item': $data = API::createItem("book", array("title" => "Title"), $this, 'jsonData'); break; case 'search': $data = API::createSearch("Name", 'default', $this, 'jsonData'); break; } $version = $data['version']; $this->assertNotEquals(0, $version); $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$data['key']}", json_encode($data)); $this->assert204($response); $this->assertEquals($version, $response->getHeader("Last-Modified-Version")); switch ($objectType) { case 'collection': $json = API::getCollection($data['key'], $this, 'json'); break; case 'item': $json = API::getItem($data['key'], $this, 'json'); break; case 'search': $json = API::getSearch($data['key'], $this, 'json'); break; } $this->assertEquals($version, $json['version']); }
public function testParentItem() { $json = API::createItem("book", false, $this, 'jsonData'); $parentKey = $json['key']; $parentVersion = $json['version']; $json = API::createAttachmentItem("linked_url", [], $parentKey, $this, 'jsonData'); $childKey = $json['key']; $childVersion = $json['version']; $this->assertArrayHasKey('parentItem', $json); $this->assertEquals($parentKey, $json['parentItem']); // Remove the parent, making the child a standalone attachment unset($json['parentItem']); $response = API::userPut( self::$config['userID'], "items/$childKey", json_encode($json), array("If-Unmodified-Since-Version: " . $childVersion) ); $this->assert204($response); $json = API::getItem($childKey, $this, 'json')['data']; $this->assertArrayNotHasKey('parentItem', $json); }
public function testAddFileClientV4Zip() { API::userClear(self::$config['userID']); $auth = array( 'username' => self::$config['username'], 'password' => self::$config['password'] ); // Get last storage sync $response = API::userGet( self::$config['userID'], "laststoragesync?auth=1", array(), $auth ); $this->assert404($response); $json = API::createItem("book", false, $this, 'jsonData'); $key = $json['key']; $fileContentType = "text/html"; $fileCharset = "UTF-8"; $fileFilename = "file.html"; $fileModtime = time(); $json = API::createAttachmentItem("imported_url", [], $key, $this, 'jsonData'); $key = $json['key']; $version = $json['version']; $json['contentType'] = $fileContentType; $json['charset'] = $fileCharset; $json['filename'] = $fileFilename; $response = API::userPut( self::$config['userID'], "items/$key", json_encode($json), array( "Content-Type: application/json" ) ); $this->assert204($response); // Get a sync timestamp from before the file is updated sleep(1); require_once 'include/sync.inc.php'; $sessionID = Sync::login(); $xml = Sync::updated($sessionID); $lastsync = (int) $xml['timestamp']; Sync::logout($sessionID); // Get file info $response = API::userGet( self::$config['userID'], "items/{$json['key']}/file?auth=1&iskey=1&version=1&info=1", array(), $auth ); $this->assert404($response); $zip = new \ZipArchive(); $file = "work/$key.zip"; if ($zip->open($file, \ZIPARCHIVE::CREATE) !== TRUE) { throw new Exception("Cannot open ZIP file"); } $zip->addFromString($fileFilename, self::getRandomUnicodeString()); $zip->addFromString("file.css", self::getRandomUnicodeString()); $zip->close(); $hash = md5_file($file); $filename = $key . ".zip"; $size = filesize($file); $fileContents = file_get_contents($file); // Get upload authorization $response = API::userPost( self::$config['userID'], "items/{$json['key']}/file?auth=1&iskey=1&version=1", $this->implodeParams(array( "md5" => $hash, "filename" => $filename, "filesize" => $size, "mtime" => $fileModtime, "zip" => 1 )), array( "Content-Type: application/x-www-form-urlencoded" ), $auth ); $this->assert200($response); $this->assertContentType("application/xml", $response); $xml = new SimpleXMLElement($response->getBody()); self::$toDelete[] = "$hash"; $boundary = "---------------------------" . rand(); $postData = ""; foreach ($xml->params->children() as $key => $val) { $postData .= "--" . $boundary . "\r\nContent-Disposition: form-data; " . "name=\"$key\"\r\n\r\n$val\r\n"; } $postData .= "--" . $boundary . "\r\nContent-Disposition: form-data; " . "name=\"file\"\r\n\r\n" . $fileContents . "\r\n"; $postData .= "--" . $boundary . "--"; // Upload to S3 $response = HTTP::post( (string) $xml->url, $postData, array( "Content-Type: multipart/form-data; boundary=" . $boundary ) ); $this->assert201($response); // // Register upload // $response = API::userPost( self::$config['userID'], "items/{$json['key']}/file?auth=1&iskey=1&version=1", "update=" . $xml->key . "&mtime=" . $fileModtime, array( "Content-Type: application/x-www-form-urlencoded" ), $auth ); $this->assert204($response); // Verify attachment item metadata $response = API::userGet( self::$config['userID'], "items/{$json['key']}" ); $json = API::getJSONFromResponse($response)['data']; $this->assertEquals($hash, $json['md5']); $this->assertEquals($fileFilename, $json['filename']); $this->assertEquals($fileModtime, $json['mtime']); // Make sure attachment item wasn't updated (or else the client // will get a conflict when it tries to update the metadata) $sessionID = Sync::login(); $xml = Sync::updated($sessionID, $lastsync); Sync::logout($sessionID); $this->assertEquals(0, $xml->updated[0]->count()); $response = API::userGet( self::$config['userID'], "laststoragesync?auth=1", array(), array( 'username' => self::$config['username'], 'password' => self::$config['password'] ) ); $this->assert200($response); $mtime = $response->getBody(); $this->assertRegExp('/^[0-9]{10}$/', $mtime); // File exists $response = API::userPost( self::$config['userID'], "items/{$json['key']}/file?auth=1&iskey=1&version=1", $this->implodeParams(array( "md5" => $hash, "filename" => $filename, "filesize" => $size, "mtime" => $fileModtime + 1000, "zip" => 1 )), array( "Content-Type: application/x-www-form-urlencoded" ), $auth ); $this->assert200($response); $this->assertContentType("application/xml", $response); $this->assertEquals("<exists/>", $response->getBody()); // Make sure attachment item still wasn't updated $sessionID = Sync::login(); $xml = Sync::updated($sessionID, $lastsync); Sync::logout($sessionID); $this->assertEquals(0, $xml->updated[0]->count()); }
public function testDeleteCollectionRelation() { $relations = array("owl:sameAs" => "http://zotero.org/groups/1/collections/AAAAAAAA"); $data = API::createCollection("Test", array("relations" => $relations), $this, 'jsonData'); // Remove all relations $data['relations'] = new \stdClass(); unset($relations['owl:sameAs']); $response = API::userPut(self::$config['userID'], "collections/{$data['key']}", json_encode($data)); $this->assert204($response); // Make sure it's gone $data = API::getCollection($data['key'], $this, 'json')['data']; $this->assertCount(sizeOf($relations), $data['relations']); foreach ($relations as $predicate => $object) { $this->assertEquals($object, $data['relations'][$predicate]); } }
private function _testSinceContent($param) { API::userClear(self::$config['userID']); // Store content for one item $key = API::createItem("book", false, $this, 'key'); $json = API::createAttachmentItem("imported_url", [], $key, $this, 'jsonData'); $key1 = $json['key']; $content = "Here is some full-text content"; $response = API::userPut(self::$config['userID'], "items/{$key1}/fulltext", json_encode(["content" => $content]), array("Content-Type: application/json")); $this->assert204($response); $contentVersion1 = $response->getHeader("Last-Modified-Version"); $this->assertGreaterThan(0, $contentVersion1); // And another $key = API::createItem("book", false, $this, 'key'); $json = API::createAttachmentItem("imported_url", [], $key, $this, 'jsonData'); $key2 = $json['key']; $response = API::userPut(self::$config['userID'], "items/{$key2}/fulltext", json_encode(["content" => $content]), array("Content-Type: application/json")); $this->assert204($response); $contentVersion2 = $response->getHeader("Last-Modified-Version"); $this->assertGreaterThan(0, $contentVersion2); // Get newer one $response = API::userGet(self::$config['userID'], "fulltext?{$param}={$contentVersion1}"); $this->assert200($response); $this->assertContentType("application/json", $response); $this->assertEquals($contentVersion2, $response->getHeader("Last-Modified-Version")); $json = API::getJSONFromResponse($response); $this->assertCount(1, $json); $this->assertArrayHasKey($key2, $json); $this->assertEquals($contentVersion2, $json[$key2]); // Get both with since=0 $response = API::userGet(self::$config['userID'], "fulltext?{$param}=0"); $this->assert200($response); $this->assertContentType("application/json", $response); $json = API::getJSONFromResponse($response); $this->assertCount(2, $json); $this->assertArrayHasKey($key1, $json); $this->assertEquals($contentVersion1, $json[$key1]); $this->assertArrayHasKey($key1, $json); $this->assertEquals($contentVersion2, $json[$key2]); }
public function testCollectionChildItemError() { $collectionKey = API::createCollection('Test', false, $this, 'key'); $key = API::createItem("book", array(), $this, 'key'); $json = API::createNoteItem("Test Note", $key, $this, 'jsonData'); $json['collections'] = [$collectionKey]; $response = API::userPut(self::$config['userID'], "items/{$json['key']}", json_encode($json), array("Content-Type: application/json")); $this->assert400($response); $this->assertEquals("Child items cannot be assigned to collections", $response->getBody()); }
private function _testResponseJSONPut($objectType) { API::userClear(self::$config['userID']); $objectTypePlural = API::getPluralObjectType($objectType); switch ($objectType) { case 'collection': $json1 = ["name" => "Test 1"]; break; case 'item': $json1 = API::getItemTemplate('book'); $json1->title = "Test 1"; break; case 'search': $conditions = array(array('condition' => 'title', 'operator' => 'contains', 'value' => 'value')); $json1 = ["name" => "Test 1", "conditions" => $conditions]; break; } $response = API::userPost(self::$config['userID'], $objectTypePlural, json_encode([$json1]), array("Content-Type: application/json")); $this->assert200($response); $json = API::getJSONFromResponse($response); $this->assert200ForObject($response, false, 0); $objectKey = $json['success'][0]; $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}"); $this->assert200($response); $json = API::getJSONFromResponse($response); switch ($objectType) { case 'item': $json['data']['title'] = "Test 2"; break; case 'collection': case 'search': $json['data']['name'] = "Test 2"; break; } $response = API::userPut(self::$config['userID'], "{$objectTypePlural}/{$objectKey}", json_encode($json), array("Content-Type: application/json")); $this->assert204($response); // Check $response = API::userGet(self::$config['userID'], "{$objectTypePlural}/{$objectKey}"); $this->assert200($response); $json = API::getJSONFromResponse($response); switch ($objectTypePlural) { case 'item': $this->assertEquals("Test 2", $json['data']['title']); break; case 'collection': case 'search': $this->assertEquals("Test 2", $json['data']['name']); break; } }
public function testOverlongSetting() { $settingKey = "tagColors"; $value = array(array("name" => $this->content = str_repeat("abcdefghij", 1001), "color" => "#990000")); $json = array("value" => $value, "version" => 0); $response = API::userPut(self::$config['userID'], "settings/{$settingKey}", json_encode($json), array("Content-Type: application/json")); $this->assert400($response, "'value' cannot be longer than 1000 characters"); }
public function testKeyCreateAndModifyWithCredentials() { API::useAPIKey(""); $name = "Test " . uniqid(); // Can't create on /users/:userID/keys with credentials $response = API::userPost(self::$config['userID'], 'keys', json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert403($response); // Create with credentials $response = API::post('keys', json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]]), [], []); $this->assert201($response); $json = API::getJSONFromResponse($response); $key = $json['key']; $this->assertEquals($json['userID'], self::$config['userID']); $this->assertEquals($json['name'], $name); $this->assertEquals(['user' => ['library' => true, 'files' => true]], $json['access']); $name = "Test " . uniqid(); // Can't modify on /users/:userID/keys/:key with credentials $response = API::userPut(self::$config['userID'], "keys/{$key}", json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert403($response); // Modify with credentials $response = API::put("keys/{$key}", json_encode(['username' => self::$config['username'], 'password' => self::$config['password'], 'name' => $name, 'access' => ['user' => ['library' => true]]])); $this->assert200($response); $json = API::getJSONFromResponse($response); $key = $json['key']; $this->assertEquals($json['name'], $name); $response = API::userDelete(self::$config['userID'], "keys/{$key}"); $this->assert204($response); }