Skip to content

Commit

Permalink
Fix of codinguser#891 - New lines are replaced with spaces for descri…
Browse files Browse the repository at this point in the history
…ption and memo lines of the QIF export.

Empty memos are no longer exported (field is optional in QIF).
Also fixed export test and added new test for no new lines export.
Increased Robolectric version from 4.3.1 to 4.5.1 because of failing build (see robolectric/robolectric#5456).
  • Loading branch information
Thumas committed Jun 27, 2021
1 parent 00f5b8f commit 8393afb
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,14 @@ dependencies {
}


testImplementation 'org.robolectric:robolectric:4.3.1'
testImplementation 'org.robolectric:robolectric:4.5.1'

testImplementation(
'junit:junit:4.12',
'joda-time:joda-time:2.9.4',
'org.assertj:assertj-core:3.14.0'
)
testImplementation 'org.robolectric:shadows-multidex:4.3.1'
testImplementation 'org.robolectric:shadows-multidex:4.5.1'

androidTestImplementation (
'com.android.support:support-annotations:' + androidSupportVersion,
Expand Down
19 changes: 11 additions & 8 deletions app/src/main/java/org/gnucash/android/export/qif/QifExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public List<String> generateExport() throws ExporterException {
currentAccountUID = accountUID;
writer.append(QifHelper.ACCOUNT_HEADER).append(newLine);
writer.append(QifHelper.ACCOUNT_NAME_PREFIX)
.append(cursor.getString(cursor.getColumnIndexOrThrow("acct1_full_name")))
.append(QifHelper.sanitizeQifLine(cursor.getString(cursor.getColumnIndexOrThrow("acct1_full_name"))))
.append(newLine);
writer.append(QifHelper.ENTRY_TERMINATOR).append(newLine);
writer.append(QifHelper.getQifHeader(cursor.getString(cursor.getColumnIndexOrThrow("acct1_type"))))
Expand All @@ -158,12 +158,15 @@ public List<String> generateExport() throws ExporterException {
.append(newLine);
// Payee / description
writer.append(QifHelper.PAYEE_PREFIX)
.append(cursor.getString(cursor.getColumnIndexOrThrow("trans_desc")))
.append(QifHelper.sanitizeQifLine(cursor.getString(cursor.getColumnIndexOrThrow("trans_desc"))))
.append(newLine);
// Notes, memo
writer.append(QifHelper.MEMO_PREFIX)
.append(cursor.getString(cursor.getColumnIndexOrThrow("trans_notes")))
.append(newLine);
String memo = QifHelper.sanitizeQifLine(cursor.getString(cursor.getColumnIndexOrThrow("trans_notes")));
if (!memo.isEmpty()) {
writer.append(QifHelper.MEMO_PREFIX)
.append(memo)
.append(newLine);
}
// deal with imbalance first
double imbalance = cursor.getDouble(cursor.getColumnIndexOrThrow("trans_acct_balance"));
BigDecimal decimalImbalance = BigDecimal.valueOf(imbalance).setScale(2, BigDecimal.ROUND_HALF_UP);
Expand All @@ -186,10 +189,10 @@ public List<String> generateExport() throws ExporterException {
// amount associated with the header account will not be exported.
// It can be auto balanced when importing to GnuCash
writer.append(QifHelper.SPLIT_CATEGORY_PREFIX)
.append(cursor.getString(cursor.getColumnIndexOrThrow("acct2_full_name")))
.append(QifHelper.sanitizeQifLine(cursor.getString(cursor.getColumnIndexOrThrow("acct2_full_name"))))
.append(newLine);
String splitMemo = cursor.getString(cursor.getColumnIndexOrThrow("split_memo"));
if (splitMemo != null && splitMemo.length() > 0) {
String splitMemo = QifHelper.sanitizeQifLine(cursor.getString(cursor.getColumnIndexOrThrow("split_memo")));
if (!splitMemo.isEmpty()) {
writer.append(QifHelper.SPLIT_MEMO_PREFIX)
.append(splitMemo)
.append(newLine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,11 @@ public static String getQifHeader(AccountType accountType){
public static String getQifHeader(String accountType) {
return getQifHeader(AccountType.valueOf(accountType));
}

static String sanitizeQifLine(String line) {
if (line == null) {
return "";
}
return line.replaceAll("\\r?\\n", " ");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.gnucash.android.export.ExportFormat;
import org.gnucash.android.export.ExportParams;
import org.gnucash.android.export.qif.QifExporter;
import org.gnucash.android.export.qif.QifHelper;
import org.gnucash.android.model.Account;
import org.gnucash.android.model.Book;
import org.gnucash.android.model.Commodity;
Expand Down Expand Up @@ -156,13 +157,39 @@ public void memoAndDescription_shouldBeExported() throws IOException {
String expectedDescription = "my description";
String expectedMemo = "my memo";

checkGivenMemoAndDescription(expectedDescription,expectedDescription,expectedMemo,expectedMemo);
}

/**
* Test that new lines in the memo and description fields of transactions are not exported.
*/
@Test
public void memoAndDescription_doNotExportNewLines() throws IOException {
final String lineBreak = "\r\n";
final String expectedLineBreakReplacement = " ";

final String descriptionFirstLine = "Test description";
final String descriptionSecondLine = "with 2 lines";
final String originalDescription = descriptionFirstLine + lineBreak + descriptionSecondLine;
final String expectedDescription = descriptionFirstLine + expectedLineBreakReplacement + descriptionSecondLine;

final String memoFirstLine = "My memo has multiply lines";
final String memoSecondLine = "This is the second line";
final String memoThirdLine = "This is the third line";
final String originalMemo = memoFirstLine + lineBreak + memoSecondLine + lineBreak + memoThirdLine;
final String expectedMemo = memoFirstLine + expectedLineBreakReplacement + memoSecondLine + expectedLineBreakReplacement + memoThirdLine;

checkGivenMemoAndDescription(originalDescription,expectedDescription,originalMemo,expectedMemo);
}

private void checkGivenMemoAndDescription(final String originalDescription, final String expectedDescription, final String originalMemo, final String expectedMemo) throws IOException {
AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(mDb);

Account account = new Account("Basic Account");
Transaction transaction = new Transaction("One transaction");
transaction.addSplit(new Split(Money.createZeroInstance("EUR"), account.getUID()));
transaction.setDescription(expectedDescription);
transaction.setNote(expectedMemo);
transaction.setDescription(originalDescription);
transaction.setNote(originalMemo);
account.addTransaction(transaction);

accountsDbAdapter.addRecord(account);
Expand All @@ -179,8 +206,8 @@ public void memoAndDescription_shouldBeExported() throws IOException {
File file = new File(exportedFiles.get(0));
String fileContent = readFileContent(file);
assertThat(file).exists().hasExtension("qif");
assertThat(fileContent.contains(expectedDescription));
assertThat(fileContent.contains(expectedMemo));
assertThat(fileContent).contains(QifHelper.PAYEE_PREFIX + expectedDescription);
assertThat(fileContent).contains(QifHelper.MEMO_PREFIX + expectedMemo);
}

@NonNull
Expand Down

0 comments on commit 8393afb

Please sign in to comment.