Beispiel #1
0
 private function _testPatchExistingObjectWithOldVersionProperty($objectType)
 {
     $objectTypePlural = API::getPluralObjectType($objectType);
     $key = API::createDataObject($objectType, 'key');
     $json = API::createUnsavedDataObject($objectType);
     $json['version'] = 1;
     $response = API::userPatch(self::$config['userID'], "{$objectTypePlural}/{$key}", json_encode($json), ["Content-Type: application/json"]);
     $this->assert412($response);
 }
Beispiel #2
0
	/**
	 * @depends testGetFile
	 */
	public function testAddFilePartial($getFileData) {
		// Get serverDateModified
		$response = API::userGet(
			self::$config['userID'],
			"items/{$getFileData['key']}"
		);
		$json = API::getJSONFromResponse($response)['data'];
		$serverDateModified = $json['dateModified'];
		sleep(1);
		
		$originalVersion = $json['version'];
		
		// Get a sync timestamp from before the file is updated
		require_once 'include/sync.inc.php';
		$sessionID = Sync::login();
		$xml = Sync::updated($sessionID);
		$lastsync = (int) $xml['timestamp'];
		Sync::logout($sessionID);
		
		$oldFilename = "work/old";
		$fileContents = $getFileData['response']->getBody();
		file_put_contents($oldFilename, $fileContents);
		
		$newFilename = "work/new";
		$patchFilename = "work/patch";
		
		$algorithms = array(
			"bsdiff" => "bsdiff "
				. escapeshellarg($oldFilename) . " "
				. escapeshellarg($newFilename) . " "
				. escapeshellarg($patchFilename),
			"xdelta" => "xdelta3 -f -e -9 -S djw -s "
				. escapeshellarg($oldFilename) . " "
				. escapeshellarg($newFilename) . " "
				. escapeshellarg($patchFilename),
			"vcdiff" => "vcdiff encode "
				. "-dictionary " . escapeshellarg($oldFilename) . " "
				. " -target " . escapeshellarg($newFilename) . " "
				. " -delta " . escapeshellarg($patchFilename)
		);
		
		foreach ($algorithms as $algo => $cmd) {
			clearstatcache();
			
			// Create random contents
			file_put_contents($newFilename, uniqid(self::getRandomUnicodeString(), true));
			$newHash = md5_file($newFilename);
			
			// Get upload authorization
			$fileParams = array(
				"md5" => $newHash,
				"filename" => "test_" . $fileContents,
				"filesize" => filesize($newFilename),
				"mtime" => filemtime($newFilename) * 1000,
				"contentType" => "text/plain",
				"charset" => "utf-8"
			);
			$response = API::userPost(
				self::$config['userID'],
				"items/{$getFileData['key']}/file",
				$this->implodeParams($fileParams),
				array(
					"Content-Type: application/x-www-form-urlencoded",
					"If-Match: " . md5_file($oldFilename)
				)
			);
			$this->assert200($response);
			$json = json_decode($response->getBody());
			$this->assertNotNull($json);
			
			exec($cmd, $output, $ret);
			if ($ret != 0) {
				echo "Warning: Error running $algo -- skipping file upload test\n";
				continue;
			}
			
			$patch = file_get_contents($patchFilename);
			$this->assertNotEquals("", $patch);
			
			self::$toDelete[] = "$newHash";
			
			// Upload patch file
			$response = API::userPatch(
				self::$config['userID'],
				"items/{$getFileData['key']}/file?algorithm=$algo&upload=" . $json->uploadKey,
				$patch,
				array(
					"If-Match: " . md5_file($oldFilename)
				)
			);
			$this->assert204($response);
			
			unlink($patchFilename);
			rename($newFilename, $oldFilename);
			
			// Verify attachment item metadata
			$response = API::userGet(
				self::$config['userID'],
				"items/{$getFileData['key']}"
			);
			$json = API::getJSONFromResponse($response)['data'];
			$this->assertEquals($fileParams['md5'], $json['md5']);
			$this->assertEquals($fileParams['mtime'], $json['mtime']);
			$this->assertEquals($fileParams['contentType'], $json['contentType']);
			$this->assertEquals($fileParams['charset'], $json['charset']);
			
			// Make sure version has changed
			$this->assertNotEquals($originalVersion, $json['version']);
			
			// Make sure new attachment is passed via sync
			$sessionID = Sync::login();
			$xml = Sync::updated($sessionID, $lastsync);
			Sync::logout($sessionID);
			$this->assertGreaterThan(0, $xml->updated[0]->count());
			
			// Verify file on S3
			$response = API::userGet(
				self::$config['userID'],
				"items/{$getFileData['key']}/file"
			);
			$this->assert302($response);
			$location = $response->getHeader("Location");
			
			$response = HTTP::get($location);
			$this->assert200($response);
			$this->assertEquals($fileParams['md5'], md5($response->getBody()));
			$t = $fileParams['contentType'];
			$this->assertEquals(
				$t . (($t && $fileParams['charset']) ? "; charset={$fileParams['charset']}" : ""),
				$response->getHeader("Content-Type")
			);
		}
	}
Beispiel #3
0
	public function testParentItemPatch() {
		$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']);
		
		$json = array(
			'title' => 'Test'
		);
		
		// With PATCH, parent shouldn't be removed even though unspecified
		$response = API::userPatch(
			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->assertArrayHasKey('parentItem', $json);
		$childVersion = $json['version'];
		
		// But it should be removed with parentItem: false
		$json = [
			'parentItem' => false
		];
		$response = API::userPatch(
			self::$config['userID'],
			"items/$childKey",
			json_encode($json),
			["If-Unmodified-Since-Version: " . $childVersion]
		);
		$this->assert204($response);
		$json = API::getItem($childKey, $this, 'json')['data'];
		$this->assertArrayNotHasKey('parentItem', $json);
	}
Beispiel #4
0
 public function testCollectionItemChange()
 {
     $collectionKey1 = API::createCollection('Test', false, $this, 'key');
     $collectionKey2 = API::createCollection('Test', false, $this, 'key');
     $json = API::createItem("book", array('collections' => array($collectionKey1)), $this, 'json');
     $itemKey1 = $json['key'];
     $itemVersion1 = $json['version'];
     $this->assertEquals([$collectionKey1], $json['data']['collections']);
     $json = API::createItem("journalArticle", array('collections' => array($collectionKey2)), $this, 'json');
     $itemKey2 = $json['key'];
     $itemVersion2 = $json['version'];
     $this->assertEquals([$collectionKey2], $json['data']['collections']);
     $json = API::getCollection($collectionKey1, $this);
     $this->assertEquals(1, $json['meta']['numItems']);
     $json = API::getCollection($collectionKey2, $this);
     $this->assertEquals(1, $json['meta']['numItems']);
     $collectionData2 = $json['data'];
     $libraryVersion = API::getLibraryVersion();
     // Add items to collection
     $response = API::userPatch(self::$config['userID'], "items/{$itemKey1}", json_encode(array("collections" => array($collectionKey1, $collectionKey2))), array("Content-Type: application/json", "If-Unmodified-Since-Version: {$itemVersion1}"));
     $this->assert204($response);
     // Item version should change
     $json = API::getItem($itemKey1, $this);
     $this->assertEquals($libraryVersion + 1, $json['version']);
     // Collection timestamp shouldn't change, but numItems should
     $json = API::getCollection($collectionKey2, $this);
     $this->assertEquals(2, $json['meta']['numItems']);
     $this->assertEquals($collectionData2['version'], $json['version']);
     $collectionData2 = $json['data'];
     $libraryVersion = API::getLibraryVersion();
     // Remove collections
     $response = API::userPatch(self::$config['userID'], "items/{$itemKey2}", json_encode(array("collections" => array())), array("Content-Type: application/json", "If-Unmodified-Since-Version: {$itemVersion2}"));
     $this->assert204($response);
     // Item version should change
     $json = API::getItem($itemKey2, $this);
     $this->assertEquals($libraryVersion + 1, $json['version']);
     // Collection timestamp shouldn't change, but numItems should
     $json = API::getCollection($collectionKey2, $this);
     $this->assertEquals(1, $json['meta']['numItems']);
     $this->assertEquals($collectionData2['version'], $json['version']);
     // Check collections arrays and numItems
     $json = API::getItem($itemKey1, $this);
     $this->assertCount(2, $json['data']['collections']);
     $this->assertContains($collectionKey1, $json['data']['collections']);
     $this->assertContains($collectionKey2, $json['data']['collections']);
     $json = API::getItem($itemKey2, $this);
     $this->assertCount(0, $json['data']['collections']);
     $json = API::getCollection($collectionKey1, $this);
     $this->assertEquals(1, $json['meta']['numItems']);
     $json = API::getCollection($collectionKey2, $this);
     $this->assertEquals(1, $json['meta']['numItems']);
 }