/** * @depends testSyncEmpty */ public function testSync() { $xml = Sync::updated(self::$sessionID); // Upload $data = file_get_contents("data/sync1upload.xml"); $data = str_replace('libraryID=""', 'libraryID="' . self::$config['libraryID'] . '"', $data); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Download $xml = Sync::updated(self::$sessionID); unset($xml->updated->groups); $xml['timestamp'] = ""; $xml['updateKey'] = ""; $xml['earliest'] = ""; $this->assertXmlStringEqualsXmlFile("data/sync1download.xml", $xml->asXML()); // Test fully cached download $xml = Sync::updated(self::$sessionID); unset($xml->updated->groups); $xml['timestamp'] = ""; $xml['updateKey'] = ""; $xml['earliest'] = ""; $this->assertXmlStringEqualsXmlFile("data/sync1download.xml", $xml->asXML()); // Test item-level cached download $xml = Sync::updated(self::$sessionID, 2); unset($xml->updated->groups); $xml['timestamp'] = ""; $xml['updateKey'] = ""; $xml['earliest'] = ""; $this->assertXmlStringEqualsXmlFile("data/sync1download.xml", $xml->asXML()); }
public function testSettings() { $settingKey = 'tagColors'; $value = array(array("name" => "_READ", "color" => "#990000")); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $lastSyncTimestamp = (int) $xml['timestamp']; $libraryVersion = API::getLibraryVersion(); // Create item via sync $data = '<data version="9"><settings><setting libraryID="' . self::$config['libraryID'] . '" name="' . $settingKey . '">' . htmlspecialchars(json_encode($value)) . '</setting></settings></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Check via sync $xml = Sync::updated(self::$sessionID, $lastSyncTimestamp); $updateKey = (string) $xml['updateKey']; $lastSyncTimestamp = $xml['timestamp']; $settingXML = $xml->updated[0]->settings[0]->setting[0]; $this->assertEquals(self::$config['libraryID'], (int) $settingXML['libraryID']); $this->assertEquals($settingKey, (string) $settingXML['name']); $this->assertEquals($value, json_decode((string) $settingXML, true)); // Get setting via API and check value $response = API::userGet(self::$config['userID'], "settings/{$settingKey}?key=" . self::$config['apiKey']); $this->assertEquals(200, $response->getStatus()); $json = json_decode($response->getBody(), true); $this->assertNotNull($json); $this->assertEquals($value, $json['value']); $this->assertEquals($libraryVersion + 1, $json['version']); // Delete via sync $xmlstr = '<data version="9">' . '<deleted>' . '<settings>' . '<setting libraryID="' . self::$config['libraryID'] . '" key="' . $settingKey . '"/>' . '</settings>' . '</deleted>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); $xml = Sync::waitForUpload(self::$sessionID, $response, $this); // Get setting via API and check value $response = API::userGet(self::$config['userID'], "settings/{$settingKey}?key=" . self::$config['apiKey']); $this->assertEquals(404, $response->getStatus()); // Check for missing via sync $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $lastSyncTimestamp = $xml['timestamp']; $this->assertEquals(0, $xml->updated[0]->settings->count()); $this->assertEquals(1, $xml->updated[0]->deleted[0]->settings[0]->setting->count()); $this->assertEquals(self::$config['libraryID'], (int) $xml->updated[0]->deleted[0]->settings[0]->setting[0]['libraryID']); $this->assertEquals($settingKey, (string) $xml->updated[0]->deleted[0]->settings[0]->setting[0]['key']); }
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 testCollectionItemUpdate() { $collectionKey = Sync::createCollection(self::$sessionID, self::$config['libraryID'], "Test", null, $this); $itemKey = Sync::createItem(self::$sessionID, self::$config['libraryID'], "book", null, $this); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Get the item version $itemXML = API::getItemXML($itemKey); $data = API::parseDataFromAtomEntry($itemXML); $json = json_decode($data['content'], true); $itemVersion = $json['itemVersion']; $this->assertNotNull($itemVersion); // Add via sync $collectionXML = $xml->updated[0]->collections[0]->collection[0]; $collectionXML['libraryID'] = self::$config['libraryID']; $collectionXML->addChild("items", $itemKey); $data = '<data version="9"><collections>' . $collectionXML->asXML() . '</collections>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data, true); Sync::waitForUpload(self::$sessionID, $response, $this); // Make sure item was updated $itemXML = API::getItemXML($itemKey); $data = API::parseDataFromAtomEntry($itemXML); $json = json_decode($data['content'], true); $this->assertGreaterThan($itemVersion, $json['itemVersion']); $itemVersion = $json['itemVersion']; $this->assertCount(1, $json['collections']); $this->assertContains($collectionKey, $json['collections']); // Remove via sync $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $collectionXML = $xml->updated[0]->collections[0]->collection[0]; $collectionXML['libraryID'] = self::$config['libraryID']; unset($collectionXML->items); $data = '<data version="9"><collections>' . $collectionXML->asXML() . '</collections>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data, true); Sync::waitForUpload(self::$sessionID, $response, $this); // Make sure item was removed $itemXML = API::getItemXML($itemKey); $data = API::parseDataFromAtomEntry($itemXML); $json = json_decode($data['content'], true); $this->assertGreaterThan($itemVersion, $json['itemVersion']); $this->assertCount(0, $json['collections']); }
public function testSyncUploadUnchanged() { $data1 = API::createItem("audioRecording", array("title" => "Test", "relations" => array('owl:sameAs' => 'http://zotero.org/groups/1/items/AAAAAAAA')), null, 'data'); // dc:relation already exists, so item shouldn't change $data2 = API::createItem("interview", array("relations" => array('dc:relation' => 'http://zotero.org/users/' . self::$config['userID'] . '/items/' . $data1['key'])), null, 'data'); // Upload unchanged via sync $xml = Sync::updated(self::$sessionID); $updateKey = $xml['updateKey']; $lastSyncTimestamp = $xml['timestamp']; $itemXML1 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$data1['key']}']")); $itemXML2 = array_shift($xml->updated[0]->items[0]->xpath("item[@key='{$data2['key']}']")); $itemXML1['libraryID'] = self::$config['libraryID']; $itemXML2['libraryID'] = self::$config['libraryID']; $xmlstr = '<data version="9">' . '<items>' . $itemXML1->asXML() . $itemXML2->asXML() . '</items>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); Sync::waitForUpload(self::$sessionID, $response, $this); // Check via API to make sure they're the same $response = API::userGet(self::$config['userID'], "items?key=" . self::$config['apiKey'] . "&format=versions"); $json = API::getJSONFromResponse($response); $this->assertEquals($data1['version'], $json[$data1['key']]); $this->assertEquals($data2['version'], $json[$data2['key']]); }
public function testGroupDeleteItemLibraryAccessDenied() { // Create item $xml = Sync::updated(self::$sessionID2); $updateKey = (string) $xml['updateKey']; $data = '<data version="9"><items><item libraryID="' . self::$config['ownedPrivateGroupLibraryID2'] . '" itemType="note" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="AAAAAAAA"><note>Test</note></item></items></data>'; $response = Sync::upload(self::$sessionID2, $updateKey, $data, true); Sync::waitForUpload(self::$sessionID2, $response, $this); // Delete item without permissions $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $data = '<data version="9"><deleted><items><item libraryID="' . self::$config['ownedPrivateGroupLibraryID2'] . '" key="AAAAAAAA"/>' . "</items></deleted></data>"; $response = Sync::upload(self::$sessionID, $updateKey, $data, true); $xml = Sync::waitForUpload(self::$sessionID, $response, $this, true); $this->assertTrue(isset($xml->error)); $this->assertEquals("LIBRARY_ACCESS_DENIED", $xml->error["code"]); }
public function testCircularRelatedItems() { $parentKey = API::createItem("book", false, null, 'key'); $noteKeys = [API::createNoteItem("Note 1", $parentKey, null, 'key'), API::createNoteItem("Note 2", $parentKey, null, 'key'), API::createNoteItem("Note 3", $parentKey, null, 'key'), API::createNoteItem("Note 4", $parentKey, null, 'key')]; $xml = Sync::updated(self::$sessionID); $updateKey = $xml['updateKey']; $note1XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[0]}']")); $note2XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[1]}']")); $note3XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[2]}']")); $note4XML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[3]}']")); $note1XML['libraryID'] = self::$config['libraryID']; $note2XML['libraryID'] = self::$config['libraryID']; $note3XML['libraryID'] = self::$config['libraryID']; $note4XML['libraryID'] = self::$config['libraryID']; $note1XML->related = implode(' ', [$parentKey, (string) $note2XML['key'], (string) $note3XML['key'], (string) $note4XML['key']]); $note2XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note3XML['key'], (string) $note4XML['key']]); $note3XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note2XML['key'], (string) $note4XML['key']]); $note4XML->related = implode(' ', [$parentKey, (string) $note1XML['key'], (string) $note2XML['key'], (string) $note3XML['key']]); $xmlstr = '<data version="9">' . '<items>' . $note1XML->asXML() . $note2XML->asXML() . $note3XML->asXML() . $note4XML->asXML() . '</items>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); Sync::waitForUpload(self::$sessionID, $response, $this); $xml = Sync::updated(self::$sessionID); $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[0]}']")); $keys = split(' ', $noteXML->related); $this->assertCount(4, $keys); $this->assertContains($parentKey, $keys); $this->assertContains((string) $noteKeys[1], $keys); $this->assertContains((string) $noteKeys[2], $keys); $this->assertContains((string) $noteKeys[3], $keys); $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[1]}']")); $keys = split(' ', $noteXML->related); $this->assertCount(4, $keys); $this->assertContains($parentKey, $keys); $this->assertContains((string) $noteKeys[0], $keys); $this->assertContains((string) $noteKeys[2], $keys); $this->assertContains((string) $noteKeys[3], $keys); $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[2]}']")); $keys = split(' ', $noteXML->related); $this->assertCount(4, $keys); $this->assertContains($parentKey, $keys); $this->assertContains((string) $noteKeys[0], $keys); $this->assertContains((string) $noteKeys[1], $keys); $this->assertContains((string) $noteKeys[3], $keys); $noteXML = array_shift($xml->updated[0]->items->xpath("//item[@key = '{$noteKeys[3]}']")); $keys = split(' ', $noteXML->related); $this->assertCount(4, $keys); $this->assertContains($parentKey, $keys); $this->assertContains((string) $noteKeys[0], $keys); $this->assertContains((string) $noteKeys[1], $keys); $this->assertContains((string) $noteKeys[2], $keys); }
public function testFullTextNoAccess() { API::groupClear(self::$config['ownedPrivateGroupID2']); // Add item to group as user 2 $user2SessionID = Sync::login(['username' => self::$config['username2'], 'password' => self::$config['password2']]); $xml = Sync::updated($user2SessionID); $updateKey = (string) $xml['updateKey']; $key = Zotero_Utilities::randomString(8, 'key', true); $dateAdded = date('Y-m-d H:i:s', time() - 1); $dateModified = date('Y-m-d H:i:s'); $xmlstr = '<data version="9">' . '<items>' . '<item libraryID="' . self::$config['ownedPrivateGroupLibraryID2'] . '" ' . 'itemType="attachment" ' . 'dateAdded="' . $dateAdded . '" ' . 'dateModified="' . $dateModified . '" ' . 'key="' . $key . '"/>' . '</items>' . '</data>'; $response = Sync::upload($user2SessionID, $updateKey, $xmlstr); Sync::waitForUpload($user2SessionID, $response, $this); // Make sure item exists $xml = Sync::updated($user2SessionID, 1); $this->assertEquals(1, $xml->updated[0]->items->count()); $this->assertEquals(1, $xml->updated[0]->items[0]->item->count()); // Try to add full-text content as user 1 $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $content = "This is some full-text content."; $totalChars = 2500; $xmlstr = '<data version="9">' . '<fulltexts>' . '<fulltext libraryID="' . self::$config['ownedPrivateGroupLibraryID2'] . '" ' . 'key="' . $key . '" ' . 'indexedChars="' . strlen($content) . '" ' . 'totalChars="' . $totalChars . '" ' . 'indexedPages="0" ' . 'totalPages="0">' . htmlspecialchars($content) . '</fulltext>' . '</fulltexts>' . '</data>'; $response = Sync::upload(self::$sessionID, $updateKey, $xmlstr); Sync::waitForUpload(self::$sessionID, $response, $this); // Retrieve it as user 2 $xml = Sync::updated($user2SessionID, 1, false, false, ["ft" => 1]); $this->assertEquals(0, $xml->updated[0]->fulltexts->count()); API::groupClear(self::$config['ownedPrivateGroupID2']); }
public function testTagDeleteUnmodifiedItemChange() { $key = 'AAAAAAAA'; $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Create item via sync $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="book" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $key . '"/></items>' . '<tags><tag libraryID="' . self::$config['libraryID'] . '" name="Test" ' . 'dateAdded="2009-03-07 04:54:56" ' . 'dateModified="2009-03-07 04:54:56" ' . 'key="BBBBBBBB">' . '<items>' . $key . '</items>' . '</tag></tags></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item via API $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $originalVersion = $data['version']; $this->assertCount(1, $json->tags); $this->assertTrue(isset($json->tags[0]->tag)); $this->assertEquals("Test", $json->tags[0]->tag); // Get item via sync $xml = Sync::updated(self::$sessionID); $this->assertEquals(1, sizeOf($xml->updated->items->item)); $this->assertEquals(1, sizeOf($xml->updated->tags->tag)); $this->assertEquals(1, sizeOf($xml->updated->tags->tag[0]->items)); $lastsync = (int) $xml['timestamp']; usleep(1500000); // Increment the library version, since we're testing the // version below API::createItem('newspaperArticle', false, false, 'key'); $libraryVersion = API::getLibraryVersion(); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Delete tag via sync, with unmodified item $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="book" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $key . '"/></items>' . '<deleted><tags><tag libraryID="' . self::$config['libraryID'] . '" key="BBBBBBBB"/>' . '</tags></deleted></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item via sync $xml = Sync::updated(self::$sessionID); $this->assertEquals(1, sizeOf(isset($xml->updated->tags->tag))); $this->assertFalse(isset($xml->updated->tags->tag[0]->items)); // Get item version via API $response = API::userGet(self::$config['userID'], "items/{$key}?key=" . self::$config['apiKey'] . "&content=json"); $xml = API::getXMLFromResponse($response); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content']); $this->assertEquals(0, (int) array_shift($xml->xpath('/atom:entry/zapi:numTags'))); $this->assertCount(0, $json->tags); // New item version should be greater than before $this->assertGreaterThan($originalVersion, $data['version']); // And should be one more than previous version $this->assertEquals($libraryVersion + 1, $data['version']); // Only the newspaperArticle should be updated $xml = Sync::updated(self::$sessionID, $lastsync); $this->assertEquals(1, $xml->updated[0]->items[0]->count()); }
public function testNoteWayTooLong() { $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $content = str_repeat("1", 10000000); // Create too-long note via sync $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="note" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="AAAAAAAA"><note>' . $content . '</note></item></items></data>'; // // < 4.0.27 // Sync::useZoteroVersion("4.0.26.4"); $response = Sync::upload(self::$sessionID, $updateKey, $data, true); $xml = Sync::waitForUpload(self::$sessionID, $response, $this, true); $this->assertTrue(isset($xml->error)); $this->assertEquals("ERROR_PROCESSING_UPLOAD_DATA", $xml->error["code"]); $this->assertRegExp('/^The note \'.+\' in your library is too long /', (string) $xml->error); $this->assertRegExp('/ copy and paste \'AAAAAAAA\' into /', (string) $xml->error); // // >=4.0.27 // Sync::useZoteroVersion(); $response = Sync::upload(self::$sessionID, $updateKey, $data, true); $xml = Sync::waitForUpload(self::$sessionID, $response, $this, true); $this->assertTrue(isset($xml->error)); $this->assertEquals("NOTE_TOO_LONG", $xml->error["code"]); $this->assertRegExp('/^The note \'.+\' in your library is too long /', (string) $xml->error); $this->assertRegExp('/\\/AAAAAAAA$/', (string) $xml->item); }
public function testComputerProgram() { $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $itemKey = 'AAAAAAAA'; // Create item via sync $data = '<data version="9"><items><item libraryID="' . self::$config['libraryID'] . '" itemType="computerProgram" ' . 'dateAdded="2009-03-07 04:53:20" ' . 'dateModified="2009-03-07 04:54:09" ' . 'key="' . $itemKey . '">' . '<field name="version">1.0</field>' . '</item></items></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Get item version via API $response = API::userGet(self::$config['userID'], "items/{$itemKey}?key=" . self::$config['apiKey'] . "&content=json"); $this->assertEquals(200, $response->getStatus()); $xml = API::getItemXML($itemKey); $data = API::parseDataFromAtomEntry($xml); $json = json_decode($data['content'], true); $this->assertEquals('1.0', $json['version']); $json['version'] = '1.1'; $response = API::userPut(self::$config['userID'], "items/{$itemKey}?key=" . self::$config['apiKey'], json_encode($json)); $this->assertEquals(204, $response->getStatus()); $xml = Sync::updated(self::$sessionID); $this->assertEquals('version', (string) $xml->updated[0]->items[0]->item[0]->field[0]['name']); }
public function testEmptyCreator() { $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; // Create creator via sync $data = '<data version="9"><creators>' . '<creator libraryID="' . self::$config['libraryID'] . '" ' . 'key="AAAAAAAA" dateAdded="2013-12-01 03:53:20" dateModified="2013-12-01 03:54:09">' . '<name></name>' . '<fieldMode>1</fieldMode>' . '</creator>' . '<creator libraryID="' . self::$config['libraryID'] . '" ' . 'key="BBBBBBBB" dateAdded="2013-12-01 04:53:20" dateModified="2013-12-01 04:54:09">' . '<name>' . chr(0xef) . chr(0xbb) . chr(0xbf) . '</name>' . '<fieldMode>1</fieldMode>' . '</creator>' . '</creators></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); // Creators should have been skipped $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $this->assertEquals(0, sizeOf($xml->updated->creators->creator)); // Create creator with valid name $data = '<data version="9"><creators>' . '<creator libraryID="' . self::$config['libraryID'] . '" ' . 'key="AAAAAAAA" dateAdded="2013-12-01 03:53:20" dateModified="2013-12-01 03:54:09">' . '<name>Test</name>' . '<fieldMode>1</fieldMode>' . '</creator>' . '</creators></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $this->assertEquals(1, sizeOf($xml->updated->creators->creator)); // Update with empty $data = '<data version="9"><creators>' . '<creator libraryID="' . self::$config['libraryID'] . '" ' . 'key="AAAAAAAA" dateAdded="2013-12-01 03:53:20" dateModified="2013-12-01 03:54:09">' . '<name>' . chr(0xef) . chr(0xbb) . chr(0xbf) . '</name>' . '<fieldMode>1</fieldMode>' . '</creator>' . '</creators></data>'; $response = Sync::upload(self::$sessionID, $updateKey, $data); Sync::waitForUpload(self::$sessionID, $response, $this); $xml = Sync::updated(self::$sessionID); $updateKey = (string) $xml['updateKey']; $this->assertEquals(1, sizeOf($xml->updated->creators->creator)); // Not ideal, but for now the updated creator should just be ignored $this->assertEquals("Test", (string) $xml->updated->creators->creator->name); }
public static function createSearch($sessionID, $libraryID, $name, $conditions, $context) { if ($conditions == 'default') { $conditions = array(array('condition' => 'title', 'operator' => 'contains', 'value' => 'test')); } $xml = Sync::updated($sessionID); $updateKey = (string) $xml['updateKey']; $key = Zotero_Utilities::randomString(8, 'key', true); $dateAdded = date('Y-m-d H:i:s', time() - 1); $dateModified = date('Y-m-d H:i:s', time()); $xmlstr = '<data version="9">' . '<searches>' . '<search libraryID="' . $libraryID . '" ' . 'name="' . $name . '" ' . 'dateAdded="' . $dateAdded . '" ' . 'dateModified="' . $dateModified . '" ' . 'key="' . $key . '">'; $i = 1; foreach ($conditions as $condition) { $xmlstr .= '<condition id="' . $i . '" ' . 'condition="' . $condition['condition'] . '" ' . 'operator="' . $condition['operator'] . '" ' . 'value="' . $condition['value'] . '"/>'; $i++; } $xmlstr .= '</search>' . '</searches>' . '</data>'; $response = Sync::upload($sessionID, $updateKey, $xmlstr); Sync::waitForUpload($sessionID, $response, $context); return $key; }