def test_setting_explicit_timestamp_field(self): transaction = TransactionFactory() old_posted_timestamp = transaction.posted_timestamp transaction.posted_timestamp = datetime.now() transaction.save() self.assertNotEqual( old_posted_timestamp, transaction.posted_timestamp, )
def test_multiple_matches(self): """ Multiple matching transactions raises MultipleObjectsReturned. """ credit_card_transaction = CreditCardTransactionFactory() amount = Decimal('100') ledger = LedgerFactory() for _ in range(2): TransactionFactory( UserFactory(), ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=ledger), LedgerEntry(amount=credit(amount), ledger=ledger), ], evidence=[credit_card_transaction], ) self.assertEqual(Transaction.objects.count(), 2) with self.assertRaises(Transaction.MultipleObjectsReturned): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(amount)), (ledger.name, debit(amount)), ], evidence=[credit_card_transaction], )
def test_unicode_methods(self): txn = TransactionFactory() tro = txn.related_objects.last() self.assertEqual( str(tro), 'TransactionRelatedObject: CreditCardTransaction(id=%s)' % tro.related_object_id, # noqa: E501 ) entry = txn.entries.last() self.assertEqual( str(entry), "LedgerEntry: $%s in %s" % ( entry.amount, entry.ledger.name, )) ledger = LedgerFactory(name='foo') self.assertEqual(str(ledger), "Ledger foo") ledger = LedgerFactory(name='föo') if sys.version_info.major == 2: str(ledger) == b"Ledger f\xc3\xb6o" if sys.version_info.major == 3: self.assertTrue(str(ledger) == "Ledger föo") ttype = TransactionTypeFactory(name='foo') self.assertEqual(str(ttype), "Transaction Type foo") balance = LedgerBalance.objects.last() self.assertEqual( str(balance), "LedgerBalance: %s for %s in %s" % ( balance.balance, balance.related_object, balance.ledger, ))
def test_transaction_fields(self): """ Test filtering by `posted_timestamp`, `notes`, `type`, and `user`. """ time = datetime.now() wrong_time = datetime.now() - timedelta(days=1) user1 = UserFactory() user2 = UserFactory() credit_card_transaction = CreditCardTransactionFactory() ttype1 = TransactionTypeFactory(name='1') ttype2 = TransactionTypeFactory(name='2') FIELDS_TO_VALUES = [ ('posted_timestamp', time, wrong_time), ('notes', 'foo', 'bar'), ('type', ttype1, ttype2), ('user', user1, user2), ] for field_name, right_value, wrong_value in FIELDS_TO_VALUES: TransactionFactory( evidence=[credit_card_transaction], **{field_name: right_value}) ledger = Ledger.objects.last() assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(Decimal('100'))), (ledger.name, debit(Decimal('100'))), ], evidence=[credit_card_transaction], **{field_name: right_value} )
def test_mismatch_on_evidence(self): """ An otherwise matching Trans. will fail if its evidence is different. """ credit_card_transaction = CreditCardTransactionFactory() amount = Decimal('100') ledger = LedgerFactory() TransactionFactory( UserFactory(), ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=ledger), LedgerEntry(amount=credit(amount), ledger=ledger), ], evidence=[credit_card_transaction], ) ledger_amount_pairs = [ (ledger.name, credit(amount)), (ledger.name, debit(amount)), ] with self.assertRaises(Transaction.DoesNotExist): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=ledger_amount_pairs, evidence=[ credit_card_transaction, CreditCardTransactionFactory()], ) with self.assertRaises(Transaction.DoesNotExist): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=ledger_amount_pairs, evidence=[], )
def test_mismatch_on_ledger_entries(self): """ An otherwise matching Trans. will fail if its LedgerEntries mismatch. """ credit_card_transaction = CreditCardTransactionFactory() amount = Decimal('100') ledger = LedgerFactory() evidence = [credit_card_transaction] TransactionFactory( UserFactory(), ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=ledger), LedgerEntry(amount=credit(amount), ledger=ledger), ], evidence=evidence, ) with self.assertRaises(Transaction.DoesNotExist): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name + 'foo', credit(amount)), (ledger.name + 'foo', debit(amount)), ], evidence=evidence, ) with self.assertRaises(AssertionError): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(amount + Decimal('1'))), (ledger.name, debit(amount + Decimal('1'))), ], evidence=evidence, )
def test_transaction_summary(self): ledger = LedgerFactory() amount = Decimal('500') ccx = CreditCardTransactionFactory() le1 = LedgerEntry(ledger=ledger, amount=credit(amount)) le2 = LedgerEntry(ledger=ledger, amount=debit(amount)) txn = TransactionFactory(evidence=[ccx], ledger_entries=[le1, le2]) self.assertEqual( txn.summary(), { 'entries': [str(entry) for entry in txn.entries.all()], 'related_objects': [ 'TransactionRelatedObject: CreditCardTransaction(id=%s)' % ccx.id, ], }, )
def test_no_args(self): TransactionFactory(evidence=[self.credit_card_transaction]) ledger = Ledger.objects.last() assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(Decimal('100'))), (ledger.name, debit(Decimal('100'))), ], evidence=[self.credit_card_transaction], )
def test_custom_evidence(self): ccx = CreditCardTransactionFactory() TransactionFactory(evidence=[ccx]) ledger = Ledger.objects.last() assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(Decimal('100'))), (ledger.name, debit(Decimal('100'))), ], evidence=[ccx], )
def test_editing_transactions(self): transaction = TransactionFactory() transaction.notes = 'foo' transaction.save() entry = transaction.entries.last() entry.amount += Decimal('1') entry.save() with self.assertRaises(TransactionBalanceException): transaction.save()
def test_auto_timestamp(self): """ If a posted_timestamp isn't specified we assume the posted_timestamp is the same as the transaction we're voiding. """ amount = D(100) charge_txn = TransactionFactory(self.creation_user, ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=self.ar_ledger), LedgerEntry(amount=credit(amount), ledger=self.rev_ledger), ]) void_txn = void_transaction(charge_txn, self.creation_user) self.assertEqual( charge_txn.posted_timestamp, void_txn.posted_timestamp)
def test_cant_void_twice(self): """ Voiding a `Transaction` more than once is not permitted. """ amount = D(100) txn = TransactionFactory(self.creation_user, ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=self.ar_ledger), LedgerEntry(amount=credit(amount), ledger=self.rev_ledger), ]) void_transaction(txn, self.creation_user) self.assertRaises( UnvoidableTransactionException, void_transaction, txn, self.creation_user)
def test_given_timestamp(self): """ If a posted_timestamp is given for the void, then use it """ amount = D(100) charge_txn = TransactionFactory(self.creation_user, ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=self.ar_ledger), LedgerEntry(amount=credit(amount), ledger=self.rev_ledger), ]) now = datetime.now() void_txn = void_transaction( charge_txn, self.creation_user, posted_timestamp=now) self.assertEqual(now, void_txn.posted_timestamp)
def test_custom_ledger_entries(self): ledger = LedgerFactory() amount = Decimal('500') TransactionFactory(evidence=[self.credit_card_transaction], ledger_entries=[ LedgerEntry(ledger=ledger, amount=credit(amount)), LedgerEntry(ledger=ledger, amount=debit(amount)), ]) assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(amount)), (ledger.name, debit(amount)), ], evidence=[self.credit_card_transaction], )
def test_no_matches(self): """ No matching transaction raises DoesNotExist. """ TransactionFactory() credit_card_transaction = CreditCardTransactionFactory() ledger = Ledger.objects.last() self.assertTrue(Transaction.objects.exists()) with self.assertRaises(Transaction.DoesNotExist): assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(Decimal('100'))), (ledger.name, debit(Decimal('100'))), ], evidence=[credit_card_transaction], )
def test_can_void_void(self): """ A void can be voided, thus restoring the original transaction. """ amount = D(100) txn = TransactionFactory(self.creation_user, ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=self.ar_ledger), LedgerEntry(amount=credit(amount), ledger=self.rev_ledger), ]) void_txn = void_transaction(txn, self.creation_user) self.assertEqual(void_txn.voids, txn) void_void_txn = (void_transaction(void_txn, self.creation_user)) self.assertEqual(void_void_txn.voids, void_txn) self.assertEqual(self.ar_ledger.get_balance(), amount) self.assertEqual(self.rev_ledger.get_balance(), -amount)
def test_void_with_non_default_type(self): """ Test voiding a `Transaction` with a non-default `type`. """ amount = D(100) txn = TransactionFactory(self.creation_user, ledger_entries=[ LedgerEntry(amount=debit(amount), ledger=self.ar_ledger), LedgerEntry(amount=credit(amount), ledger=self.rev_ledger), ]) new_ttype = TransactionTypeFactory() void_txn = void_transaction(txn, self.creation_user, type=new_ttype) self.assertEqual(void_txn.voids, txn) self.assertEqual(self.ar_ledger.get_balance(), D(0)) self.assertEqual(self.rev_ledger.get_balance(), D(0)) self.assertEqual(void_txn.type, new_ttype) self.assertNotEqual(void_txn.type, txn.type)
def test_custom_fields(self): """ Test setting fields `posted_timestamp`, `notes`, `type`, and `user`. """ time = datetime.now() FIELDS_TO_VALUES = [ ('posted_timestamp', time), ('notes', 'booga'), ('type', TransactionTypeFactory()), ('user', UserFactory()), ] for field_name, value in FIELDS_TO_VALUES: TransactionFactory(evidence=[self.credit_card_transaction], **{field_name: value}) ledger = Ledger.objects.last() assert_transaction_in_ledgers_for_amounts_with_evidence( ledger_amount_pairs=[ (ledger.name, credit(Decimal('100'))), (ledger.name, debit(Decimal('100'))), ], evidence=[self.credit_card_transaction], **{field_name: value})