/*
* Copyright (c) 2009-2011 Dropbox Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.dropbox.client2;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.session.AccessTokenPair;
import static org.junit.Assert.*;
import com.dropbox.client2.DropboxAPI.Account;
import com.dropbox.client2.DropboxAPI.DropboxFileInfo;
import com.dropbox.client2.DropboxAPI.DropboxInputStream;
import com.dropbox.client2.DropboxAPI.DropboxLink;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.DropboxAPI.ThumbFormat;
import com.dropbox.client2.DropboxAPI.ThumbSize;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.WebAuthSession;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class DropboxAPITest {
private static DropboxAPI<?> api;
static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private final static String TESTS_DIR = "/" + dateFormat.format(new Date());
private File foo = new File("testfiles", "foo.txt");
private File song = new File("testfiles", "dropbox_song.mp3");
private File frog = new File("testfiles", "Costa Rican Frog.jpg");
static {
try {
AppKeyPair consumerTokenPair = new AppKeyPair(System.getProperty("app_key"), System.getProperty("app_secret"));
WebAuthSession session = new WebAuthSession(consumerTokenPair, AccessType.APP_FOLDER);
session.setAccessTokenPair(new AccessTokenPair(System.getProperty("access_key"), System.getProperty("access_secret")));
api = new DropboxAPI<WebAuthSession>(session);
} catch (Throwable t) {
t.printStackTrace();
assert false : "Total failure trying to start WebAuthSession." + t;
}
}
public void assertFile(Entry e, File f, String path){
assertEquals(e.bytes, f.length());
assertEquals(e.isDir, false);
assertEquals(e.path, path);
}
/**
* @return the suite of tests being tested
*/
@Test
public void accountInfo() throws Exception {
Account info = api.accountInfo();
assert info.country != null : "No country for account";
assert info.displayName != null : "No displayName for account";
assert info.quota > 0 : "0 quota in account";
assert info.quotaNormal > 0 : "0 normal quota in account";
assert info.referralLink != null : "No referral link for account";
assert info.uid > 0 : "No uid for account";
}
// Get metadata for a nonexistent directory
@Test
public void getMetadataBad() throws Exception {
try {
String path = TESTS_DIR + "iDoNotExist.txt";
Entry ent = api.metadata(path, 1000, null, true, null);
assert ent.isDeleted: "The " + path + " directory should not exist";
} catch (DropboxServerException e) {
if (e.error != DropboxServerException._404_NOT_FOUND) {
assert false: "Unexpected Dropbox Server Error: " + e.toString();
}
} catch (DropboxException e) {
assert false: "Unexpected Dropbox Error: " + e.toString();
}
}
// Create the /tests directory
@Test
public void createFolder() throws Exception {
String path = TESTS_DIR + "createdFolder";
Entry ent = api.createFolder(path);
assertEquals(ent.isDir, true);
}
// Try to create another one, and make sure we get an error
@Test
public void createFolderDupe() throws Exception {
try {
api.createFolder(TESTS_DIR);
assert false : "Able to create duplicate folder";
} catch (DropboxServerException e) {
if (e.error != DropboxServerException._403_FORBIDDEN) {
assert false: "Unexpected Dropbox Server Error: " + e.toString();
}
} catch (DropboxException e) {
assert false: "Unexpected Dropbox Error: " + e.toString();
}
}
// Get metadata for the new /tests directory
@Test
public void getMetadata() throws Exception {
String path = TESTS_DIR + "/metadatasong.mp3";
uploadFile(song, path);
api.metadata(path, 1000, null, true, null);
}
// Get metadata for the new /tests directory, saving the hash
@Test
public void getMetadataCached() throws Exception {
try {
Entry ent = api.metadata(TESTS_DIR, 1000, null, true, null);
api.metadata(TESTS_DIR, 1000, ent.hash, true, null);
assert false : "Directory should have been cached";
} catch (DropboxServerException e) {
if (e.error != DropboxServerException._304_NOT_MODIFIED) {
assert false: "Unexpected Dropbox Server Error: " + e.toString();
}
} catch (DropboxException e) {
assert false: "Unexpected Dropbox Error: " + e.toString();
}
}
// Put a simple text file into /tests/foo.txt
@Test
public void putFile() throws Exception {
assertPutFile(foo, TESTS_DIR + "/putfoo.txt");
assertPutFile(frog, TESTS_DIR + "/putfrog.jpg");
assertPutFile(song, TESTS_DIR + "/putsong.mp3");
}
public void assertPutFile(File src, String destPath) throws Exception{
FileInputStream fis = new FileInputStream(src);
Entry ent = api.putFile(destPath, fis, src.length(), null, null);
assertEquals(ent.path, destPath);
assertEquals(ent.bytes, src.length());
assertEquals(ent.isDir, false);
}
@Test
public void getFile() throws Exception {
assertGetFile(foo, TESTS_DIR + "/getfoo.txt");
assertGetFile(song, TESTS_DIR + "/getsong.mp3");
assertGetFile(frog, TESTS_DIR + "/getfrog.jpg");
}
public void assertGetFile(File src, String destPath) throws Exception{
uploadFile(src, destPath);
byte[] downloaded = Util.streamToBytes(api.getFileStream(destPath, null));
byte[] local = Util.streamToBytes(new FileInputStream(src));
assertArrayEquals(downloaded, local);
}
@Test
public void getThumbnail() throws Exception {
String path = TESTS_DIR + "/thumbnailfrog.jpg";
uploadFile(frog, path);
OutputStream out = new ByteArrayOutputStream();
DropboxFileInfo info = api.getThumbnail(path, out,
ThumbSize.BESTFIT_480x320, ThumbFormat.JPEG, null);
assert info != null : "No info returned";
assert info.getFileSize() > 0 : "Thumbnail length 0";
assert info.getMetadata().bytes > 0 : "Original file size 0";
assert info.getFileSize() != info.getMetadata().bytes : "Thumbnail equals original file size.";
}
@Test
public void getThumbnailStream() throws Exception {
String path = TESTS_DIR + "/thumbnailstreamfrog.jpg";
uploadFile(frog, path);
DropboxInputStream is = api.getThumbnailStream(path, ThumbSize.BESTFIT_480x320, ThumbFormat.JPEG);
assert is != null : "No info returned";
assert is.getFileInfo().getFileSize() > 0 : "Thumbnail length 0";
assert is.getFileInfo().getMetadata().bytes > 0 : "Original file size 0";
}
public void uploadFileOverwrite(File src, String target) throws Exception{
FileInputStream fis = new FileInputStream(src);
api.putFileOverwrite(target, fis, src.length(), null);
}
public void uploadFile(File src, String target) throws Exception{
FileInputStream fis = new FileInputStream(src);
api.putFile(target, fis, src.length(), null, null);
}
@Test
public void copy() throws Exception
{
String fromPath = TESTS_DIR + "/copyFrom.jpg";
String toPath = TESTS_DIR + "/copyTo.jpg";
uploadFile(frog, fromPath);
Entry ent = api.copy(fromPath, toPath);
assertFile(ent, frog, toPath);
ent = api.metadata(toPath, 1, null, false, null);
assertFile(ent, frog, toPath);
}
@Test
public void move() throws Exception
{
String fromPath = TESTS_DIR + "/moveFrom.jpg";
String toPath = TESTS_DIR + "/moveTo.jpg";
uploadFile(frog, fromPath);
Entry moveEnt = api.move(fromPath, toPath);
assertFile(moveEnt, frog, toPath);
moveEnt = api.metadata(toPath, 1, null, false, null);
assertFile(moveEnt, frog, toPath);
Entry oldEnt = api.metadata(fromPath, 1, null, false, null);
assertEquals(oldEnt.isDeleted, true);
assertEquals(oldEnt.bytes, 0);
assert oldEnt.isDeleted;
}
@Test
public void media() throws Exception {
String path = TESTS_DIR + "/dropbox_song.mp3";
uploadFile(song, path);
DropboxLink link = api.media(path, true);
assert link.url != null : "No url for streamed file";
link = api.media(path, false);
assert link.url != null : "No insecure url for streamed file";
}
@Test
public void share() throws Exception{
String path = TESTS_DIR + "/dropbox_song.mp3";
uploadFile(song, path);
DropboxLink link = api.share(path);
assert link.url != null : "No url for streamed file";
}
@Test
public void search() throws Exception {
try {
// Should be too short, and give an error
api.search("/", "", 1000, false);
assert false: "Short (empty) search string did not throw an error.";
} catch (DropboxServerException e) {
if (e.error != DropboxServerException._400_BAD_REQUEST) {
assert false: "Unexpected Dropbox Error: " + e.toString();
}
}
String searchDir = TESTS_DIR + "/searchDir/";
uploadFile(foo, searchDir + "text.txt");
uploadFile(foo, searchDir + "subFolder/text.txt");
uploadFile(foo, searchDir + "subFolder/cow.txt");
uploadFile(frog, searchDir + "frog.jpg");
uploadFile(frog, searchDir + "frog2.jpg");
uploadFile(frog, searchDir + "subFolder/frog2.jpg");
List<Entry> results = api.search(searchDir, "sadfasdf", 1000, false);
assertEquals(results.size(), 0);
results = api.search(searchDir, "jpg", 1000, false);
assertEquals(results.size(), 3);
assertFile(results.get(0), frog, searchDir + "frog.jpg");
assertFile(results.get(1), frog, searchDir + "frog2.jpg");
assertFile(results.get(2), frog, searchDir + "subFolder/frog2.jpg");
results = api.search(searchDir + "subFolder", "jpg", 1000, false);
assertEquals(results.size(), 1);
assertFile(results.get(0), frog, searchDir + "subFolder/frog2.jpg");
}
@Test
public void revisionsAndRestore() throws Exception {
String path = TESTS_DIR + "/revfoo.txt";
uploadFileOverwrite(foo, path);
uploadFileOverwrite(frog, path);
uploadFileOverwrite(foo, path);
List<Entry> revs = api.revisions(path, 1000);
assert revs.size() == 3 : "Not enough revs for file";
assertFile(revs.get(0), foo, path);
assertFile(revs.get(1), frog, path);
assertFile(revs.get(2), foo, path);
for (Entry rev: revs) {
System.out.println("Revision: " + rev.rev + " modified: " + rev.modified);
}
Entry reverted = api.restore(path, revs.get(1).rev);
assertFile(reverted, frog, path);
}
@Test
public void chunkedUploadsPlain() throws Exception{
chunkedUploadsTestBase(false);
}
//@Test
public void chunkedUploadsAbort() throws Exception{
try {
chunkedUploadsTestBase(true);
assert false: "No exception WTF?";
} catch(DropboxPartialFileException d) {
}
}
private void chunkedUploadsTestBase(boolean abort) throws Exception{
String path = TESTS_DIR + "/chunkedfile.dat";
Random r = new Random();
int n = 10*1024*1024;
byte[] bytes = new byte[n];
r.nextBytes(bytes);
System.out.println("Uploading");
final boolean[] progressListenerFired = {false};
final DropboxAPI.ChunkedUploader uploader = api.getChunkedUploader(new ByteArrayInputStream(bytes), n);
if (abort) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("KILLING");
uploader.abort();
} catch(Exception e) {
throw new AssertionError(e);
}
}
}).start();
}
while(!uploader.isComplete()) {
try {
uploader.upload(new ProgressListener(){
@Override
public void onProgress(long bytes, long total) {
System.out.println("progress: " + bytes);
progressListenerFired[0] = true;
}
});
} catch (Exception e) {
System.out.println(uploader.getOffset());
if (!uploader.getActive()) {
throw e;
}
}
}
uploader.finish(path, null);
DropboxAPI.DropboxInputStream byteStream = api.getFileStream(path, null);
byte[] returnedBytes = Util.streamToBytes(byteStream);
assertTrue(progressListenerFired[0]);
assertEquals(bytes.length, returnedBytes.length);
assertArrayEquals(returnedBytes, bytes);
}
}