// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.server;
import com.google.appinventor.server.storage.StorageIo;
import com.google.appinventor.server.storage.StorageIoInstanceHolder;
import com.google.appinventor.server.storage.UnauthorizedAccessException;
import com.google.appinventor.shared.rpc.project.Project;
import com.google.appinventor.shared.rpc.project.ProjectSourceZip;
import com.google.appinventor.shared.rpc.project.RawFile;
import com.google.appinventor.shared.rpc.project.TextFile;
import com.google.appinventor.shared.storage.StorageUtil;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Tests for {@link FileExporterImpl}.
*
*/
public class FileExporterImplTest extends LocalDatastoreTestCase {
private static final String USER_ID = "1";
// The following represent a fake project, containing both source and
// output files, for the purpose of testing.
private static final String FAKE_PROJECT_TYPE = "FakeProjectType";
private static final String PROJECT_NAME = "Project1";
private static final String FORM1_NAME = "Screen1";
private static final String FORM1_QUALIFIED_NAME = "com.yourdomain." + FORM1_NAME;
private static final String FORM1_CONTENT = "Form A\nEnd Form";
private static final String IMAGE1_NAME = "Image.jpg";
private static final byte[] IMAGE_CONTENT = { (byte) 0, (byte) 1, (byte) 32, (byte) 255};
private static final String TARGET1_NAME = "Project1.apk";
private static final String TARGET1_QUALIFIED_NAME = "build/target1/" + TARGET1_NAME;
private static final byte[] TARGET1_CONTENT = "pk1".getBytes();
private static final String TARGET2_NAME = "Project2.pak";
private static final String TARGET2_QUALIFIED_NAME = "build/target2/" + TARGET2_NAME;
private static final byte[] TARGET2_CONTENT = "pk2".getBytes();
private static final String SETTINGS = "";
private static final String HISTORY = "1:History";
private StorageIo storageIo;
private FileExporterImpl exporter;
private long projectId;
@Override
protected void setUp() throws Exception {
super.setUp();
storageIo = StorageIoInstanceHolder.INSTANCE;
exporter = new FileExporterImpl();
Project project = new Project(PROJECT_NAME);
project.setProjectType(FAKE_PROJECT_TYPE);
project.setProjectHistory(HISTORY);
project.addTextFile(new TextFile(FORM1_QUALIFIED_NAME, ""));
projectId = storageIo.createProject(USER_ID, project, SETTINGS);
storageIo.uploadFile(projectId, FORM1_QUALIFIED_NAME, USER_ID, FORM1_CONTENT,
StorageUtil.DEFAULT_CHARSET);
storageIo.addSourceFilesToProject(USER_ID, projectId, false, IMAGE1_NAME);
storageIo.uploadRawFile(projectId, IMAGE1_NAME, USER_ID, true, IMAGE_CONTENT);
storageIo.addOutputFilesToProject(USER_ID, projectId, TARGET1_QUALIFIED_NAME);
storageIo.uploadRawFile(projectId, TARGET1_QUALIFIED_NAME, USER_ID,
true, TARGET1_CONTENT);
storageIo.addOutputFilesToProject(USER_ID, projectId, TARGET2_QUALIFIED_NAME);
storageIo.uploadRawFile(projectId, TARGET2_QUALIFIED_NAME, USER_ID,
true, TARGET2_CONTENT);
}
private Map<String, byte[]> testExportProjectSourceZipHelper(ProjectSourceZip project)
throws IOException {
ZipInputStream zis =
new ZipInputStream(new ByteArrayInputStream(project.getContent()));
Map<String, byte[]> content = new HashMap<String, byte[]>();
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteStreams.copy(zis, baos);
content.put(zipEntry.getName(), baos.toByteArray());
}
assertEquals(content.size(), project.getFileCount());
assertTrue(content.containsKey(FORM1_QUALIFIED_NAME));
assertTrue(content.containsKey(IMAGE1_NAME));
assertFalse(content.containsKey(TARGET1_NAME));
assertEquals(FORM1_CONTENT, new String(content.get(FORM1_QUALIFIED_NAME),
StorageUtil.DEFAULT_CHARSET));
assertTrue(Arrays.equals(IMAGE_CONTENT, content.get(IMAGE1_NAME)));
return content;
}
public void testExportProjectSourceZipWithoutHistory() throws IOException {
ProjectSourceZip project = exporter.exportProjectSourceZip(USER_ID, projectId,
false, false, null, false, false, false, false);
Map<String, byte[]> content = testExportProjectSourceZipHelper(project);
assertEquals(2, content.size());
/* Do not expect remix history when includeProjectHistory parameter is false
* as in the publish case. */
assertFalse(content.containsKey(FileExporter.REMIX_INFORMATION_FILE_PATH));
}
// TODO(user): Add test with properly formatted history
public void testExportProjectSourceZipWithHistory() throws IOException {
ProjectSourceZip project = exporter.exportProjectSourceZip(USER_ID, projectId,
true, false, null, false, false, false, false);
Map<String, byte[]> content = testExportProjectSourceZipHelper(project);
assertEquals(3, content.size());
// Expect the remix file to be in
assertTrue(content.containsKey(FileExporter.REMIX_INFORMATION_FILE_PATH));
assertEquals(HISTORY, new String(content.get(FileExporter.REMIX_INFORMATION_FILE_PATH),
StorageUtil.DEFAULT_CHARSET));
}
public void testExportProjectSourceZipWithNonExistingProject() throws IOException {
try {
exporter.exportProjectSourceZip(USER_ID, projectId + 1, false, false, null, false, false, false, false);
fail();
} catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException ||
e.getCause() instanceof IllegalArgumentException);
}
}
public void testExportProjectOutputFileWithTarget() throws IOException {
RawFile file = exporter.exportProjectOutputFile(USER_ID, projectId, "target1");
assertEquals(TARGET1_NAME, file.getFileName());
assertTrue(Arrays.equals(TARGET1_CONTENT, file.getContent()));
}
public void testExportProjectOutputFileWithNonExistingTraget() throws IOException {
try {
exporter.exportProjectOutputFile(USER_ID, projectId, "target3");
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
public void testExportFile() throws IOException {
RawFile file = exporter.exportFile(USER_ID, projectId, FORM1_QUALIFIED_NAME);
assertEquals(FORM1_QUALIFIED_NAME, file.getFileName());
assertEquals(FORM1_CONTENT, new String(file.getContent(), StorageUtil.DEFAULT_CHARSET));
}
public void testExportFileWithNonExistingFile() throws IOException {
final String nonExistingFileName = FORM1_QUALIFIED_NAME + "1";
try {
exporter.exportFile(USER_ID, projectId, nonExistingFileName);
fail();
} catch (RuntimeException e) {
// expected
// note that FileExporter throws an explicit RuntimeException
}
}
// TODO(user): Add test of exportAllProjectsSourceZip().
}