package ru.orangesoftware.financisto2.test.model; import android.content.Intent; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import ru.orangesoftware.financisto2.model.Account; import ru.orangesoftware.financisto2.model.Attribute; import ru.orangesoftware.financisto2.model.Category; import ru.orangesoftware.financisto2.model.Currency; import ru.orangesoftware.financisto2.model.Transaction; import ru.orangesoftware.financisto2.model.TransactionAttribute; import ru.orangesoftware.financisto2.model.TransactionStatus; import ru.orangesoftware.financisto2.test.builders.AccountBuilder; import ru.orangesoftware.financisto2.test.builders.CategoryBuilder; import ru.orangesoftware.financisto2.test.builders.CurrencyBuilder; import ru.orangesoftware.financisto2.test.builders.TransactionBuilder; import ru.orangesoftware.financisto2.test.db.AbstractDbTest; import static ru.orangesoftware.financisto2.test.builders.AttributeBuilder.attributeValue; /** * Created by IntelliJ IDEA. * User: Denis Solonenko * Date: 4/29/11 1:00 AM */ public class TransactionTest extends AbstractDbTest { Account a1; Account a2; Map<String, Category> categories; @Override public void setUp() throws Exception { super.setUp(); Currency c1 = CurrencyBuilder.withDb(db).name("USD").title("Dollar").symbol("$").create(); Currency c2 = CurrencyBuilder.withDb(db).name("SGD").title("Singapore Dollar").symbol("S$").create(); a1 = AccountBuilder.createDefault(db, c1); a2 = AccountBuilder.createDefault(db, c2); categories = CategoryBuilder.createDefaultHierarchy(categoryRepository); } public void test_should_create_splits() { Transaction t = TransactionBuilder.withDb(db).account(a1).amount(200).payee("P1").category(Category.splitCategory(context)) .withSplit(categories.get("A1"), 60) .withSplit(categories.get("A2"), 40) .withTransferSplit(a2, 100, 50) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(3, splits.size()); Transaction split1 = splits.get(0); assertEquals(t.payeeId, split1.payeeId); assertEquals(a1.id, split1.fromAccountId); assertEquals(60, split1.fromAmount); assertEquals(categories.get("A1").id, split1.categoryId); Transaction split2 = splits.get(1); assertEquals(t.payeeId, split2.payeeId); assertEquals(a1.id, split2.fromAccountId); assertEquals(40, split2.fromAmount); assertEquals(categories.get("A2").id, split2.categoryId); Transaction split3 = splits.get(2); assertEquals(t.payeeId, split3.payeeId); assertEquals(a1.id, split3.fromAccountId); assertEquals(a2.id, split3.toAccountId); assertEquals(100, split3.fromAmount); assertEquals(50, split3.toAmount); } public void test_should_insert_and_update_attributes() { //given Category aa1 = categories.get("AA1"); categoryRepository.loadAttributesFor(aa1); Attribute attr1 = aa1.attributes.get(0); Attribute attr2 = aa1.attributes.get(1); //when inserted Transaction t1 = TransactionBuilder.withDb(db).account(a1).amount(1000).category(aa1) .withAttributes(attributeValue(attr1, "value1"), attributeValue(attr2, "value2")) .create(); Transaction t2 = TransactionBuilder.withDb(db).account(a2).amount(2000) .withSplit(aa1, 600, "Note1", null, attributeValue(attr1, "value11")) .withSplit(aa1, 1400, "Note2", null, attributeValue(attr2, "value21")) .create(); //then assertAttributes(t1, attributeValue(attr1, "value1"), attributeValue(attr2, "value2")); List<Transaction> splits = db.getSplitsForTransaction(t2.id); assertAttributes(splits.get(0), attributeValue(attr1, "value11")); assertAttributes(splits.get(1), attributeValue(attr2, "value21")); //when modified db.insertOrUpdate(t1, Arrays.asList(attributeValue(attr2, "value3"))); splits.get(0).categoryAttributes = asMap(attributeValue(attr1, "value111"), attributeValue(attr2, "value222")); splits.get(1).categoryAttributes = asMap(attributeValue(attr1, "value333")); t2.splits = splits; db.insertOrUpdate(t2); //then assertAttributes(t1, attributeValue(attr2, "value3")); splits = db.getSplitsForTransaction(t2.id); assertAttributes(splits.get(0), attributeValue(attr1, "value111"), attributeValue(attr2, "value222")); assertAttributes(splits.get(1), attributeValue(attr1, "value333")); } private Map<Long, String> asMap(TransactionAttribute...values) { Map<Long, String> map = new HashMap<Long, String>(); for (TransactionAttribute value : values) { map.put(value.attributeId, value.value); } return map; } private void assertAttributes(Transaction t, TransactionAttribute...values) { Map<Long, String> attributes = db.getAllAttributesForTransaction(t.id); assertEquals(values.length, attributes.size()); for (TransactionAttribute value : values) { assertEquals(value.value, attributes.get(value.attributeId)); } } public void test_should_duplicate_splits() { Transaction t = TransactionBuilder.withDb(db).account(a1).amount(-150).category(Category.splitCategory(context)) .withSplit(categories.get("A1"), -60) .withSplit(categories.get("A2"), -40) .withTransferSplit(a2, -50, 40) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(3, splits.size()); long newId = db.duplicateTransaction(t.id); assertNotSame(t.id, newId); List<Transaction> newSplits = db.getSplitsForTransaction(newId); assertEquals(3, newSplits.size()); assertEquals(-150, newSplits.get(0).fromAmount+newSplits.get(1).fromAmount+newSplits.get(2).fromAmount); } public void test_should_convert_split_into_regular_transaction() { Transaction t = TransactionBuilder.withDb(db).account(a1).amount(2000) .withSplit(categories.get("A1"), 500) .withSplit(categories.get("A2"), 1500) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(2, splits.size()); t.categoryId = categories.get("A").id; t.splits = null; db.insertOrUpdate(t); splits = db.getSplitsForTransaction(t.id); assertEquals(0, splits.size()); } public void test_should_update_splits() { Transaction t = TransactionBuilder.withDb(db).account(a1).amount(-150).category(Category.splitCategory(context)) .withSplit(categories.get("A1"), -60) .withSplit(categories.get("A2"), -40) .withTransferSplit(a2, -50, 40) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(3, splits.size()); t.fromAmount = -250; splits.get(0).fromAmount = -70; splits.get(1).fromAmount = -50; splits.get(2).fromAmount = -130; splits.get(2).toAmount = 70; t.splits = splits; db.insertOrUpdate(t); splits = db.getSplitsForTransaction(t.id); assertEquals(3, splits.size()); } public void test_should_delete_splits() { Transaction t = TransactionBuilder.withDb(db).account(a1).amount(-150).category(Category.splitCategory(context)) .withSplit(categories.get("A1"), -60) .withSplit(categories.get("A2"), -40) .withTransferSplit(a2, -50, 40) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(3, splits.size()); db.deleteTransaction(t.id); splits = db.getSplitsForTransaction(t.id); assertEquals(0, splits.size()); } public void test_should_store_transaction_in_the_database() { Transaction t = new Transaction(); t.fromAccountId = 1; t.fromAmount = 1000; t.categoryId = 5; t.isCCardPayment = 1; t.note = "My note"; t.status = TransactionStatus.RS; long id = db.saveOrUpdate(t); assertTrue(id > 0); Transaction restored = db.load(Transaction.class, id); assertEquals(t.fromAccountId, restored.fromAccountId); assertEquals(t.fromAmount, restored.fromAmount); assertEquals(t.categoryId, restored.categoryId); assertEquals(t.note, restored.note); assertEquals(t.status, restored.status); assertEquals(t.isCCardPayment, restored.isCCardPayment); } public void test_should_restore_split_from_intent() { Transaction split = new Transaction(); split.id = -2; split.fromAccountId = 3; split.toAccountId = 5; split.categoryId = 7; split.fromAmount = -10000; split.toAmount = 4000; split.unsplitAmount = 300000; split.note = "My note"; Intent intent = new Intent(); split.toIntentAsSplit(intent); Transaction restored = Transaction.fromIntentAsSplit(intent); assertEquals(split.id, restored.id); assertEquals(split.fromAccountId, restored.fromAccountId); assertEquals(split.toAccountId, restored.toAccountId); assertEquals(split.categoryId, restored.categoryId); assertEquals(split.fromAmount, restored.fromAmount); assertEquals(split.toAmount, restored.toAmount); assertEquals(split.unsplitAmount, restored.unsplitAmount); assertEquals(split.note, restored.note); } public void test_should_update_original_amount_for_splits() { Transaction t = TransactionBuilder.withDb(db).account(a1).category(Category.splitCategory(context)) .amount(120).originalAmount(a2.currency, 100) .withSplit(categories.get("A1"), 60) .withSplit(categories.get("A2"), 40) .create(); List<Transaction> splits = db.getSplitsForTransaction(t.id); assertEquals(2, splits.size()); assertSplit(splits.get(0), t.originalCurrencyId, 60, 72); assertSplit(splits.get(1), t.originalCurrencyId, 40, 48); } private void assertSplit(Transaction split, long originalCurrencyId, long originalAmount, long accountAmount) { assertEquals(originalCurrencyId, split.originalCurrencyId); assertEquals(originalAmount, split.originalFromAmount); assertEquals(accountAmount, split.fromAmount); } }