Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
codinguser committed May 3, 2017
2 parents bcdab71 + 65e3fbc commit 52f7297
Show file tree
Hide file tree
Showing 186 changed files with 2,638 additions and 3,144 deletions.
12 changes: 9 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
GnuCash Android is built by people like you! Please [join us](https://github.com/codinguser/gnucash-android).

## Git and Pull requests
## Reporting Issues
* The GitHub issue tracker is used for collecting and managing bugs, feature requests and general development planning.
* When creating a request, first search to make sure a similar one doesn't already exist in the tracker.
* Be as specific as possible when providing descriptions of the problems encountered and what the expected behaviour should be.
* It is also possible to report issues by creating tickets directly from within the app (in the Help Center)

## Code Contributions
* Contributions are submitted, reviewed, and accepted using Github pull requests. [Read this article](https://help.github.com/articles/using-pull-requests) for some details. We use the _Fork and Pull_ model, as described there.
* You can maintain your stable installation of GnuCash and test with another installation.
The two instances of GnuCash Android will live side-by-side on your device and not affect each other. You can install the development version by executing `gradle installDD` inside the root project directory
Expand All @@ -18,8 +24,8 @@ The two instances of GnuCash Android will live side-by-side on your device and n
* Try to make clean commits that are easily readable (including descriptive commit messages!)
* Test before you push make sure all test pass on your machine.
* Unit tests can be run with `gradle test`
* UI tests can be run with `gradle cDDAT`
* Make small pull requests that are easy to review but make sure they do add value by themselves.
* UI tests can be run with `gradle spoonDD`. This will run the tests on all connected devices/emulators.
* Make small pull requests that are easy to review but which also add value.

## Coding style
* Do write comments. You don't have to comment every line, but if you come up with something thats a bit complex/weird, just leave a comment. Bear in mind that you will probably leave the project at some point and that other people will read your code. Undocumented huge amounts of code are nearly worthless!
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ android:
- platform-tools
- tools
- tools #not a typo. Needed for SDK update
- build-tools-24.0.3
- build-tools-25.0.0

# The SDK version used to compile your project
- android-24
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
Change Log
===============================================================================
Version 2.2.0 *(2017-05-05)*
----------------------------
* Feature #646: Option to select backup file using Storage Access Framework
* Feature #565: Regular automatic backups (even when not explicitly set by user)
* Feature #656: Added Bitcoin (BTC) currency support
* Feature #634: Added support for renaming books
* Fixed #672: Crash when exporting multi-currency transactions to Google Drive
* Fixed #654: Crash when editing account if its default transfer account no longer exists
* Fixed #625: Hourly backups were being executed on a monthly basis
* Fixed #607: Widgets stop functioning after switching books
* Fixed #641: Weekday is ignored for weekly scheduled actions
* Improved #635: Improved support for BYN currency
* Improved #661: Removed need for WRITE_EXTERNAL_STORAGE permission for Android 4.4 (KitKat) and above
* This release raises the minimum API level to 19 (KitKat)

Version 2.1.7 *(2017-04-18)*
----------------------------
* Properly handle crashes during migration of backup/export files to new location
Expand Down
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ Accounts | Transactions | Reports
:-------------------------:|:-------------------------:|:-------------------------:
![Accounts List](docs/images/v2.0.0_home.png) | ![Transactions List](docs/images/v2.0.0_transactions_list.png) | ![Reports](docs/images/v2.0.0_reports.png)

The application supports Android 2.3.3 Gingerbread (API level 10) and above.
The application supports Android 4.4 KitKat (API level 10) and above.

Features include:

* An easy-to-use interface.

* Chart of Accounts: A master account can have a hierarchy of detail accounts underneath it.
* **Chart of Accounts**: A master account can have a hierarchy of detail accounts underneath it.
This allows similar account types (e.g. Cash, Bank, Stock) to be grouped into one master account (e.g. Assets).

* Split Transactions: A single transaction can be split into several pieces to record taxes, fees, and other compound entries.
* **Split Transactions**: A single transaction can be split into several pieces to record taxes, fees, and other compound entries.

* Double Entry: Every transaction must debit one account and credit another by an equal amount.
* **Double Entry**: Every transaction must debit one account and credit another by an equal amount.
This ensures that the "books balance": that the difference between income and outflow exactly
equals the sum of all assets, be they bank, cash, stock or other.

* Income/Expense Account Types (Categories): These serve not only to categorize your cash flow, but when used properly with the double-entry feature, these can provide an accurate Profit&Loss statement.
* **Income/Expense Account Types (Categories)**: These serve not only to categorize your cash flow, but when used properly with the double-entry feature, these can provide an accurate Profit&Loss statement.

* Scheduled Transactions: GnuCash has the ability to automatically create and enter transactions.
* **Scheduled Transactions**: GnuCash has the ability to automatically create and enter transactions.

* Export to GnuCash XML, QIF or OFX. Also, scheduled exports to 3rd-party sync services like DropBox and Google Drive
* **Export to GnuCash XML**, QIF or OFX. Also, scheduled exports to 3rd-party sync services like DropBox and Google Drive

* Reports: View summary of transactions (income and expenses) as pie/bar/line charts
* **Reports**: View summary of transactions (income and expenses) as pie/bar/line charts


# Installation
Expand Down Expand Up @@ -88,17 +88,17 @@ Google+ Community: https://plus.google.com/communities/104728406764752407046

There are several ways you could contribute to the development.

* Pull requests are always welcome! You could contribute code by fixing bugs, adding new features or automated tests.
Take a look at the [bug tracker](https://github.com/codinguser/gnucash-android/issues?state=open)
for ideas where to start. Also make sure to read our [contribution guidlines](https://github.com/codinguser/gnucash-android/blob/master/.github/CONTRIBUTING.md)

* One way is providing translations for locales which are not yet available, or improving translations.
Please visit [CrowdIn](https://crowdin.com/project/gnucash-android) in order to update and create new translations

* You could as well contribute code, fixing bugs, new features or automated tests. Pull requests are always welcome.
Take a look at the [bug tracker](https://github.com/codinguser/gnucash-android/issues?state=open)
for ideas where to start. Also take a look at the [contribution guidlines](https://github.com/codinguser/gnucash-android/blob/master/.github/CONTRIBUTING.md)

For development, it is recommended to use the Android Studio for development which is available for free.
Import the project into the IDE using the build.gradle file. The IDE will resolve dependencies automatically.

#Licence
# Licence
GnuCash Android is free software; you can redistribute it and/or
modify it under the terms of the Apache license, version 2.0.
You may obtain a copy of the License at
Expand Down
27 changes: 15 additions & 12 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ apply plugin: 'io.fabric'
apply plugin: 'android-apt'

def versionMajor = 2
def versionMinor = 1
def versionPatch = 7
def versionBuild = 0
def versionMinor = 2
def versionPatch = 0
def versionBuild = 4

def buildTime() {
def df = new SimpleDateFormat("yyyyMMdd HH:mm 'UTC'")
Expand All @@ -22,11 +22,11 @@ def gitSha() {

android {
compileSdkVersion 24
buildToolsVersion '24.0.3'
buildToolsVersion '25.0.0'
defaultConfig {
applicationId "org.gnucash.android"
testApplicationId 'org.gnucash.android.test'
minSdkVersion 10
minSdkVersion 19
targetSdkVersion 23
versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
Expand Down Expand Up @@ -85,6 +85,7 @@ android {
}
debug {
debuggable true
minifyEnabled false
// testCoverageEnabled true
signingConfig signingConfigs.debug
}
Expand Down Expand Up @@ -167,6 +168,7 @@ afterEvaluate {
spoon {
debug = true
grantAllPermissions = true
codeCoverage = true
}
initCrashlyticsPropertiesIfNeeded()
}
Expand All @@ -190,7 +192,7 @@ android.productFlavors.all { flavour ->
}


def androidSupportVersion = "24.2.1"
def androidSupportVersion = "25.3.1"
def androidEspressoVersion = "2.2.2"
def androidSupportTestVersion = "0.5"

Expand All @@ -209,31 +211,32 @@ dependencies {
'com.android.support:cardview-v7:' + androidSupportVersion,
'com.android.support:preference-v7:' + androidSupportVersion,
'com.android.support:recyclerview-v7:' + androidSupportVersion,
'com.code-troopers.betterpickers:library:3.0.1',
'com.code-troopers.betterpickers:library:3.1.0',
'org.jraf:android-switch-backport:2.0.1@aar',
'com.github.PhilJay:MPAndroidChart:v2.1.3',
'joda-time:joda-time:2.9.4',
'com.google.android.gms:play-services-drive:9.6.1',
'io.github.kobakei:ratethisapp:1.1.0',
'io.github.kobakei:ratethisapp:1.1.3',
'com.squareup:android-times-square:1.6.5@aar',
'com.github.techfreak:wizardpager:1.0.3',
'net.objecthunter:exp4j:0.4.7',
'org.apache.jackrabbit:jackrabbit-webdav:2.13.3',
'com.dropbox.core:dropbox-core-sdk:2.1.2',
'com.facebook.stetho:stetho:1.4.1',
'com.android.support:multidex:1.0.1'
)

compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
debugCompile 'com.facebook.stetho:stetho:1.4.2'

compile 'com.jakewharton:butterknife:8.5.1'
apt 'com.jakewharton:butterknife-compiler:8.5.1'

compile ('com.uservoice:uservoice-android-sdk:1.2.5') {
exclude module: 'commons-logging'
exclude module: 'httpcore'
exclude module: 'httpclient'
}

compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') {
compile('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {
transitive = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ public static void preventFirstRunDialogs(Context context) {
}


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void testDisplayAccountsList(){
AccountsActivity.createDefaultAccounts("EUR", mAccountsActivity);
mAccountsActivity.recreate();
Expand Down Expand Up @@ -462,7 +461,6 @@ public void testIntentAccountCreation(){
/**
* Tests that the setup wizard is displayed on first run
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void shouldShowWizardOnFirstRun() throws Throwable {
Editor editor = PreferenceManager.getDefaultSharedPreferences(mAccountsActivity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
import android.content.pm.PackageManager;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Build;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.contrib.DrawerActions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.runner.AndroidJUnit4;
Expand Down Expand Up @@ -53,6 +55,7 @@
import org.gnucash.android.model.Transaction;
import org.gnucash.android.ui.account.AccountsActivity;
import org.gnucash.android.ui.settings.PreferenceActivity;
import org.gnucash.android.util.BookUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
Expand Down Expand Up @@ -139,139 +142,6 @@ public void setUp() throws Exception {
mAccountsDbAdapter.addRecord(account, DatabaseAdapter.UpdateMethod.insert);

}

/**
* Tests the export of an OFX file with the transactions from the application.
* The exported file name contains a timestamp with minute precision.
* If this test fails, it may be due to the file being created and tested in different minutes of the clock
* Just try rerunning it again.
*/
@Test
public void testOfxExport(){
SharedPreferences.Editor prefsEditor = PreferenceActivity.getActiveBookSharedPreferences()
.edit();
prefsEditor.putBoolean(mAcccountsActivity.getString(R.string.key_use_double_entry), false)
.commit();
testExport(ExportFormat.OFX);
prefsEditor.putBoolean(mAcccountsActivity.getString(R.string.key_use_double_entry), true)
.commit();
}

@Test
public void whenInSingleEntry_shouldHideXmlExportOption(){
SharedPreferences.Editor prefsEditor = PreferenceActivity.getActiveBookSharedPreferences()
.edit();
prefsEditor.putBoolean(mAcccountsActivity.getString(R.string.key_use_double_entry), false)
.commit();

DrawerActions.openDrawer(R.id.drawer_layout);
onView(withText(R.string.nav_menu_export)).perform(click());
onView(withId(R.id.radio_xml_format)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));

prefsEditor.putBoolean(mAcccountsActivity.getString(R.string.key_use_double_entry), true)
.commit();
}

/**
* Test the export of transactions in the QIF format
*/
@Test
public void testQifExport(){
testExport(ExportFormat.QIF);
}

@Test
public void testXmlExport(){
testExport(ExportFormat.XML);
}

/**
* Generates export for the specified format and tests that the file actually is created
* @param format Export format to use
*/
public void testExport(ExportFormat format){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mAcccountsActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
mAcccountsActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 0x23);

onView(withId(AlertDialog.BUTTON_POSITIVE)).perform(click());
}
}

File folder = new File(Exporter.getExportFolderPath(BooksDbAdapter.getInstance().getActiveBookUID()));
folder.mkdirs();
assertThat(folder).exists();

for (File file : folder.listFiles()) {
file.delete();
}

onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
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());

assertThat(folder.listFiles().length).isEqualTo(1);
File exportFile = folder.listFiles()[0];
assertThat(exportFile.getName()).endsWith(format.getExtension());
}

@Test
public void testDeleteTransactionsAfterExport(){
assertThat(mTransactionsDbAdapter.getRecordsCount()).isGreaterThan(0);

SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getActivity()).edit(); //PreferenceActivity.getActiveBookSharedPreferences(getActivity()).edit();
editor.putBoolean(mAcccountsActivity.getString(R.string.key_delete_transactions_after_export), true);
editor.commit();

PreferenceActivity.getActiveBookSharedPreferences()
.edit()
.putBoolean(mAcccountsActivity.getString(R.string.key_use_double_entry), true)
.apply();

testExport(ExportFormat.XML);

assertThat(mTransactionsDbAdapter.getRecordsCount()).isEqualTo(0);
List<Transaction> transactions = mTransactionsDbAdapter.getAllTransactions();

editor.putBoolean(mAcccountsActivity.getString(R.string.key_delete_transactions_after_export), false).commit();
}

/**
* Test creating a scheduled export
* Does not work on Travis yet
*/
@Test
public void testShouldCreateExportSchedule(){
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
onView(withText(R.string.nav_menu_export)).perform(click());

onView(withText(ExportFormat.XML.name())).perform(click());
onView(withId(R.id.input_recurrence)).perform(click());

//switch on recurrence dialog
onView(allOf(isAssignableFrom(CompoundButton.class), isDisplayed(), isEnabled())).perform(click());
onView(withText("OK")).perform(click());

onView(withId(R.id.menu_save)).perform(click());
ScheduledActionDbAdapter scheduledactionDbAdapter = ScheduledActionDbAdapter.getInstance(); //new ScheduledActionDbAdapter(mDb, new RecurrenceDbAdapter(mDb));
List<ScheduledAction> scheduledActions = scheduledactionDbAdapter.getAllEnabledScheduledActions();
assertThat(scheduledActions)
.hasSize(1)
.extracting("mActionType").contains(ScheduledAction.ActionType.BACKUP);

ScheduledAction action = scheduledActions.get(0);
assertThat(action.getRecurrence().getPeriodType()).isEqualTo(PeriodType.WEEK);
assertThat(action.getEndTime()).isEqualTo(0);
}

@Test
public void testCreateBackup(){
Expand Down
Loading

0 comments on commit 52f7297

Please sign in to comment.