Skip to content

Commit

Permalink
Fix: export start time not respected
Browse files Browse the repository at this point in the history
Add tests for creating backup
Use cache directory as primary export destination
Code refactoring
  • Loading branch information
codinguser committed Nov 16, 2015
1 parent 5544ffc commit 9ab4e04
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
Expand All @@ -69,6 +70,8 @@
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
Expand Down Expand Up @@ -192,6 +195,11 @@ public void testExport(ExportFormat format){

DrawerActions.openDrawer(R.id.drawer_layout);
onView(withText(R.string.nav_menu_export)).perform(click());

onView(withId(R.id.spinner_export_destination)).perform(click());
String[] destinations = getActivity().getResources().getStringArray(R.array.export_destinations);

onView(withText(destinations[0])).perform(click());
onView(withText(format.name())).perform(click());

onView(withId(R.id.menu_save)).perform(click());
Expand Down Expand Up @@ -243,6 +251,26 @@ public void testShouldCreateExportSchedule(){
assertThat(action.getEndTime()).isEqualTo(0);
}

@Test
public void testCreateBackup(){
DrawerActions.openDrawer(R.id.drawer_layout);
onView(withText(R.string.title_settings)).perform(click());
onView(withText(R.string.header_backup_and_export_settings)).perform(click());

onView(withText(R.string.title_create_backup_pref)).perform(click());
assertToastDisplayed(R.string.toast_backup_successful);
}

/**
* Checks that a specific toast message is displayed
* @param toastString String that should be displayed
*/
private void assertToastDisplayed(int toastString) {
onView(withText(toastString))
.inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView()))))
.check(matches(isDisplayed()));
}

//todo: add testing of export flag to unit test
//todo: add test of ignore exported transactions to unit tests
@Override
Expand Down
25 changes: 18 additions & 7 deletions app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,9 @@ private void shareFiles(List<String> paths) {
Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
shareIntent.setType("text/xml");

ArrayList<Uri> exportFiles = convertPathsToUris(paths);
shareIntent.putExtra(Intent.EXTRA_STREAM, exportFiles);
ArrayList<Uri> exportFiles = convertFilePathsToUris(paths);
// shareIntent.putExtra(Intent.EXTRA_STREAM, exportFiles);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportFiles);

shareIntent.putExtra(Intent.EXTRA_SUBJECT, mContext.getString(R.string.title_export_email,
mExportParams.getExportFormat().name()));
Expand Down Expand Up @@ -422,14 +423,24 @@ private void shareFiles(List<String> paths) {
}
}

// /some/path/file.ext -> file:///some/path/file.ext
//

/**
* Convert file paths to URIs by adding the file// prefix
* <p>e.g. /some/path/file.ext --> file:///some/path/file.ext</p>
* @param paths List of file paths to convert
* @return List of file URIs
*/
@NonNull
private ArrayList<Uri> convertPathsToUris(List<String> paths) {
private ArrayList<Uri> convertFilePathsToUris(List<String> paths) {
ArrayList<Uri> exportFiles = new ArrayList<>();

for (String file : paths)
exportFiles.add(Uri.parse("file://" + file));

for (String path : paths) {
File file = new File(path);
file.setReadable(true, false);
exportFiles.add(Uri.fromFile(file));
// exportFiles.add(Uri.parse("file://" + file));
}
return exportFiles;
}

Expand Down
26 changes: 2 additions & 24 deletions app/src/main/java/org/gnucash/android/export/ExportParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@

package org.gnucash.android.export;

import android.preference.PreferenceManager;
import android.util.Log;

import com.crashlytics.android.Crashlytics;

import org.gnucash.android.app.GnuCashApplication;
import org.gnucash.android.ui.export.ExportFormFragment;

import java.sql.Timestamp;
Expand Down Expand Up @@ -64,11 +58,6 @@ public enum ExportTarget {SD_CARD, SHARING, DROPBOX, GOOGLE_DRIVE }
*/
private ExportTarget mExportTarget = ExportTarget.SHARING;

/**
* File path for the internal saving of transactions before determining export destination.
*/
private String mTargetFilepath;

/**
* Creates a new set of paramters and specifies the export format
* @param format Format to use when exporting the transactions
Expand All @@ -91,8 +80,6 @@ public ExportFormat getExportFormat() {
*/
public void setExportFormat(ExportFormat exportFormat) {
this.mExportFormat = exportFormat;
this.mTargetFilepath = GnuCashApplication.getAppContext().getFilesDir() + "/"
+ Exporter.buildExportFilename(mExportFormat);
}

/**
Expand Down Expand Up @@ -144,19 +131,10 @@ public void setExportTarget(ExportTarget mExportTarget) {
this.mExportTarget = mExportTarget;
}

/**
* Returns the internal target file path for the exported transactions.
* This file path is not accessible outside the context of the application
* @return String path to exported transactions
*/
public String getInternalExportPath() {
return mTargetFilepath;
}

@Override
public String toString() {
return "Export " + mExportFormat.name() + " to " + mExportTarget.name() + " at "
+ mTargetFilepath;
return "Export all transactions created since " + mExportStartTime.toString()
+ " as "+ mExportFormat.name() + " to " + mExportTarget.name();
}

/**
Expand Down
44 changes: 42 additions & 2 deletions app/src/main/java/org/gnucash/android/export/Exporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.gnucash.android.db.SplitsDbAdapter;
import org.gnucash.android.db.TransactionsDbAdapter;

import java.io.File;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -72,7 +73,16 @@ public abstract class Exporter {
/**
* Export options
*/
protected ExportParams mParameters;
protected ExportParams mExportParams;

/**
* Cache directory to which files will be first exported before moved to final destination.
* <p>There is a different cache dir per export format, which has the name of the export format.<br/>
* The cache dir is cleared every time a new {@link Exporter} is instantiated.
* The files created here are only accessible within this application, and should be copied to SD card before they can be shared
* </p>
*/
protected File mCacheDir;

private static final SimpleDateFormat EXPORT_FILENAME_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);

Expand All @@ -95,7 +105,7 @@ public abstract class Exporter {
protected Context mContext;

public Exporter(ExportParams params, SQLiteDatabase db) {
this.mParameters = params;
this.mExportParams = params;
mContext = GnuCashApplication.getAppContext();
if (db == null) {
mAccountsDbAdapter = AccountsDbAdapter.getInstance();
Expand All @@ -112,6 +122,10 @@ public Exporter(ExportParams params, SQLiteDatabase db) {
mPricesDbAdapter = new PricesDbAdapter(db);
mCommoditiesDbAdapter = new CommoditiesDbAdapter(db);
}

mCacheDir = new File(mContext.getCacheDir(), params.getExportFormat().name());
mCacheDir.mkdir();
purgeDirectory(mCacheDir);
}

/**
Expand Down Expand Up @@ -150,6 +164,32 @@ public static long getExportTime(String filename){
*/
public abstract List<String> generateExport() throws ExporterException;

/**
* Recursively delete all files in a directory
* @param directory File descriptor for directory
*/
private void purgeDirectory(File directory){
for (File file : directory.listFiles()) {
if (file.isDirectory())
purgeDirectory(file);
else
file.delete();
}
}

/**
* Returns the path to the file where the exporter should save the export during generation
* <p>This path is a temporary cache file whose file extension matches the export format.<br>
* This file is deleted every time a new export is started</p>
* @return Absolute path to file
*/
protected String getExportCacheFilePath(){
String cachePath = mCacheDir.getAbsolutePath();
if (!cachePath.endsWith("/"))
cachePath += "/";
return cachePath + buildExportFilename(mExportParams.getExportFormat());
}

/**
* Returns the MIME type for this exporter.
* @return MIME type as string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private void generateOfx(Document doc, Element parent){


//add account details (transactions) to the XML document
account.toOfx(doc, statementTransactionResponse, mParameters.getExportStartTime());
account.toOfx(doc, statementTransactionResponse, mExportParams.getExportStartTime());

//mark as exported
accountsDbAdapter.markAsExported(account.getUID());
Expand All @@ -114,15 +114,15 @@ private void generateOfx(Document doc, Element parent){

// FIXME: Move code to generateExport()
private String generateOfxExport() throws ExporterException {
mAccountsList = mAccountsDbAdapter.getExportableAccounts(mParameters.getExportStartTime());
mAccountsList = mAccountsDbAdapter.getExportableAccounts(mExportParams.getExportStartTime());

DocumentBuilderFactory docFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder;
try {
docBuilder = docFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new ExporterException(mParameters, e);
throw new ExporterException(mExportParams, e);
}

Document document = docBuilder.newDocument();
Expand Down Expand Up @@ -158,23 +158,23 @@ public List<String> generateExport() throws ExporterException {
BufferedWriter writer = null;

try {
File file = new File(mParameters.getInternalExportPath());
File file = new File(getExportCacheFilePath());
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
writer.write(generateOfxExport());
} catch (IOException e) {
throw new ExporterException(mParameters, e);
throw new ExporterException(mExportParams, e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
throw new ExporterException(mParameters, e);
throw new ExporterException(mExportParams, e);
}
}
}

List<String> exportedFiles = new ArrayList<>();
exportedFiles.add(mParameters.getInternalExportPath());
exportedFiles.add(getExportCacheFilePath());

return exportedFiles;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public List<String> generateExport() throws ExporterException {
final String newLine = "\n";
TransactionsDbAdapter transactionsDbAdapter = mTransactionsDbAdapter;
try {
String lastExportTimeStamp = PreferenceManager.getDefaultSharedPreferences(mContext).getString(Exporter.PREF_LAST_EXPORT_TIME, Exporter.TIMESTAMP_ZERO);
String lastExportTimeStamp = mExportParams.getExportStartTime().toString();
Cursor cursor = transactionsDbAdapter.fetchTransactionsWithSplitsWithTransactionAccount(
new String[]{
TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID + " AS trans_uid",
Expand Down Expand Up @@ -95,7 +95,7 @@ public List<String> generateExport() throws ExporterException {
"acct1_currency ASC, trans_time ASC, trans_uid ASC"
);

File file = new File(mParameters.getInternalExportPath());
File file = new File(getExportCacheFilePath());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

try {
Expand Down Expand Up @@ -190,7 +190,7 @@ public List<String> generateExport() throws ExporterException {
precision = 3;
break;
default:
throw new ExporterException(mParameters, "split quantity has illegal denominator: "+ quantity_denom);
throw new ExporterException(mExportParams, "split quantity has illegal denominator: "+ quantity_denom);
}
Double quantity = 0.0;
if (quantity_denom != 0) {
Expand Down Expand Up @@ -220,7 +220,7 @@ public List<String> generateExport() throws ExporterException {
PreferenceManager.getDefaultSharedPreferences(mContext).edit().putString(Exporter.PREF_LAST_EXPORT_TIME, timeStamp).apply();
return splitQIF(file);
} catch (IOException e) {
throw new ExporterException(mParameters, e);
throw new ExporterException(mExportParams, e);
}
}

Expand Down
Loading

0 comments on commit 9ab4e04

Please sign in to comment.