/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.endtoendtest.sync;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.maps.mytracks.R;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import android.app.Instrumentation;
import android.content.Context;
import android.util.Log;
import android.widget.ListView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import junit.framework.Assert;
/**
* Utilites for Google Drive sync endtoend test.
*
* @author Youtao Liu
*/
public class SyncTestUtils {
private static final String TAG = SyncTestUtils.class.getSimpleName();
public static boolean isCheckedRunSyncTest = false;
public static final String KML_FILE_POSTFIX = ".kml";
public static final long MAX_TIME_TO_WAIT_SYNC = 100000;
/**
* Sets up sync tests.
*
* @param instrumentation the instrumentation is used for test
* @param trackListActivity the startup activity
* @return a Google Drive object
*/
public static Drive setUpForSyncTest(Instrumentation instrumentation,
TrackListActivity trackListActivity) throws IOException, GoogleAuthException {
if (!isCheckedRunSyncTest || RunConfiguration.getInstance().getRunSyncTest()) {
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
if (!isCheckedRunSyncTest) {
isCheckedRunSyncTest = true;
}
if (RunConfiguration.getInstance().getRunSyncTest()) {
enableSync(GoogleUtils.ACCOUNT_1);
Drive drive1 = getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
removeKMLFiles(drive1);
EndToEndTestUtils.deleteAllTracks();
enableSync(GoogleUtils.ACCOUNT_2);
Drive drive2 = getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
removeKMLFiles(drive2);
EndToEndTestUtils.deleteAllTracks();
return drive2;
}
return null;
}
/**
* Gets drive object of Google Drive.
*
* @param context the context of application
* @return a Google Drive object
*/
public static Drive getGoogleDrive(Context context) throws IOException, GoogleAuthException {
String googleAccount = PreferencesUtils.getString(context, R.string.google_account_key,
PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT);
GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential(context,
googleAccount, SendToGoogleUtils.DRIVE_SCOPE);
return SyncUtils.getDriveService(credential);
}
/**
* Gets KML files from Google Drive of current account.
*
* @param context the context of application
* @param drive a Google Drive object
* @return KML file on Google drive
* @throws IOException
*/
public static List<File> getDriveFiles(Context context, Drive drive) throws IOException {
File folder = SyncUtils.getMyTracksFolder(context, drive);
if (folder == null) {
return new ArrayList<File>();
}
String folderId = folder.getId();
return drive.files().list()
.setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId)).execute()
.getItems();
}
/**
* Finds whether a file is existed by the name of track.
*
* @param trackName name of track
* @param drive a Google Drive object
* @return the file be found
* @throws IOException
*/
public static File getFile(String trackName, Drive drive) throws IOException {
List<File> files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(),
drive);
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
String title = file.getTitle();
if (title.equals(trackName + KML_FILE_POSTFIX)) {
return file;
}
}
return null;
}
/**
* Removes all KML files on Google Drive.
*
* @param drive a Google Drive object
* @throws IOException
*/
public static void removeKMLFiles(Drive drive) throws IOException {
List<File> files = getDriveFiles(
EndToEndTestUtils.trackListActivity.getApplicationContext(), drive);
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
removeFile(file, drive);
}
}
/**
* Removes one file on Google Drive.
*
* @param file the file to remove
* @param drive a Google Drive object
* @throws IOException
*/
public static void removeFile(File file, Drive drive) throws IOException {
drive.files().trash(file.getId()).execute();
}
/**
* Enables sync feature in MyTracks settings.
*
* @param accountName the account which is used to sync with
*/
public static void enableSync(String accountName) {
// EndToEndTestUtils.instrumentation.waitForIdleSync();
// EndToEndTestUtils.findMenuItem(
// EndToEndTestUtils.activityMytracks.getString(R.string.menu_settings), true);
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google));
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google_account_title));
// EndToEndTestUtils.instrumentation.waitForIdleSync();
//
// // Whether test account is bound.
// if (EndToEndTestUtils.SOLO.waitForText(accountName, 1, EndToEndTestUtils.SHORT_WAIT_TIME)) {
// EndToEndTestUtils.SOLO.clickOnText(accountName);
// EndToEndTestUtils.instrumentation.waitForIdleSync();
//
// if (EndToEndTestUtils.findTextView(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google_account_confirm_title)) != null) {
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.generic_yes));
// }
// } else {
// Assert.fail();
// return;
// }
//
// EndToEndTestUtils.SOLO.waitForDialogToClose(EndToEndTestUtils.SHORT_WAIT_TIME);
// EndToEndTestUtils.instrumentation.waitForIdleSync();
// CheckBox syncCheckBox = EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class).get(0);
// if (!syncCheckBox.isChecked()) {
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.menu_sync_drive));
//
// EndToEndTestUtils.SOLO.waitForText(
// EndToEndTestUtils.activityMytracks.getString(R.string.sync_drive_confirm_message).split(
// "%")[0], 1, EndToEndTestUtils.SHORT_WAIT_TIME);
// Assert.assertTrue(EndToEndTestUtils.SOLO.searchText(accountName, true));
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.generic_yes));
// }
//
// // Add this sleep to work around a exception after switch account.
// EndToEndTestUtils.sleep(15000);
// EndToEndTestUtils.SOLO.goBack();
// EndToEndTestUtils.SOLO.goBack();
// EndToEndTestUtils.instrumentation.waitForIdleSync();
}
/**
* Checks the files number on Google Drive
*
* @param drive a Google Drive object
* @throws IOException
*/
public static void checkFilesNumber(Drive drive) throws IOException {
EndToEndTestUtils.instrumentation.waitForIdleSync();
long startTime = System.currentTimeMillis();
int trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
List<File> files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(),
drive);
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
try {
if (files.size() == trackNumber) {
return;
}
trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(), drive);
EndToEndTestUtils.sleep(EndToEndTestUtils.SHORT_WAIT_TIME);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
} catch (GoogleJsonResponseException e) {
Log.e(TAG, e.getMessage(), e);
}
}
Assert.assertEquals(files.size(), trackNumber);
}
/**
* Checks the files number on Google Drive
*
* @param number number of files on Google Drive
*/
public static void checkTracksNumber(int number) {
long startTime = System.currentTimeMillis();
int trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
if (trackNumber == number) {
return;
}
trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
Log.d(TAG, trackNumber + ":" + number);
}
Assert.assertEquals(trackNumber, number);
}
/**
* Checks one file on Google Drive
*
* @param trackName the name of track
* @param shouldExist true means this track should be existed
* @param drive a Google Drive object
* @return true means the actual result is same as expectation
* @throws IOException
*/
public static boolean checkFile(String trackName, boolean shouldExist, Drive drive)
throws IOException {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
boolean exist = getFile(trackName, drive) != null;
if (exist == shouldExist) {
return true;
}
}
Assert.fail();
return false;
}
/**
* Gets the content of a file on Google Drive.
*
* @param file file to read
* @param drive a Google Drive object
* @return the string content of the file
* @throws IOException
*/
public static String getContentOfFile(File file, Drive drive) throws IOException {
HttpResponse resp = drive.getRequestFactory()
.buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
BufferedReader br = new BufferedReader(new InputStreamReader(resp.getContent()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
String fileContent = sb.toString();
br.close();
return fileContent;
}
}