This repository has been archived by the owner on Feb 8, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
33c42b2
commit 2db0989
Showing
3 changed files
with
191 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,105 @@ | ||
from gratipay.journal import Journal | ||
from __future__ import absolute_import, division, print_function, unicode_literals | ||
|
||
from decimal import Decimal as D | ||
|
||
def test_journal_can_be_instantiated(): | ||
assert Journal().__class__.__name__ == 'Journal' | ||
from gratipay.testing import Harness | ||
from gratipay.models.participant import Participant | ||
from pytest import raises | ||
from psycopg2 import IntegrityError | ||
|
||
|
||
class TestJournal(Harness): | ||
|
||
def test_journal_has_system_accounts(self): | ||
system_accounts = self.db.all('SELECT type, system FROM accounts') | ||
assert system_accounts == [ ('asset', 'cash') | ||
, ('asset', 'accounts receivable') | ||
, ('liability', 'accounts payable') | ||
, ('income', 'processing fee revenues') | ||
, ('expense', 'processing fee expenses') | ||
, ('income', 'earned interest') | ||
, ('expense', 'chargeback expenses') | ||
] | ||
|
||
def test_journal_creates_accounts_automatically_for_participants(self): | ||
self.make_participant('alice') | ||
account = self.db.one("SELECT * FROM accounts WHERE participant IS NOT NULL") | ||
assert account.participant == 'alice' | ||
assert account.type == 'liability' | ||
|
||
def test_journal_creates_accounts_automatically_for_teams(self): | ||
self.make_team() | ||
account = self.db.one("SELECT * FROM accounts WHERE team IS NOT NULL") | ||
assert account.team == 'TheATeam' | ||
assert account.type == 'liability' | ||
|
||
def test_journal_is_okay_with_teams_and_participants_with_same_name(self): | ||
self.make_participant('alice') | ||
account = self.db.one("SELECT * FROM accounts WHERE participant IS NOT NULL") | ||
assert account.participant == 'alice' | ||
|
||
self.make_team('alice') | ||
account = self.db.one("SELECT * FROM accounts WHERE team IS NOT NULL") | ||
assert account.team == 'alice' | ||
|
||
def test_journal_catches_system_account_collision(self): | ||
with raises(IntegrityError): | ||
self.db.one("INSERT INTO accounts (type, system) VALUES ('asset', 'cash')") | ||
|
||
def test_journal_catches_participant_account_collision(self): | ||
self.make_participant('alice') | ||
with raises(IntegrityError): | ||
self.db.one("INSERT INTO accounts (type, participant) VALUES ('liability', 'alice')") | ||
|
||
def test_journal_catches_team_account_collision(self): | ||
self.make_team() | ||
with raises(IntegrityError): | ||
self.db.one("INSERT INTO accounts (type, team) VALUES ('liability', 'TheATeam')") | ||
|
||
def test_journal_increments_participant_balance(self): | ||
self.make_team() | ||
alice = self.make_participant('alice') | ||
assert alice.balance == 0 | ||
|
||
self.db.run(""" | ||
INSERT INTO journal | ||
(amount, debit, credit) | ||
VALUES ( 10.77 | ||
, (SELECT id FROM accounts WHERE team='TheATeam') | ||
, (SELECT id FROM accounts WHERE participant='alice') | ||
) | ||
""") | ||
|
||
assert Participant.from_username('alice').balance == D('10.77') | ||
|
||
def test_journal_decrements_participant_balance(self): | ||
self.make_team() | ||
alice = self.make_participant('alice', balance=20) | ||
assert alice.balance == D('20.00') | ||
|
||
self.db.run(""" | ||
INSERT INTO journal | ||
(amount, debit, credit) | ||
VALUES ( 10.77 | ||
, (SELECT id FROM accounts WHERE participant='alice') | ||
, (SELECT id FROM accounts WHERE team='TheATeam') | ||
) | ||
""") | ||
|
||
assert Participant.from_username('alice').balance == D('9.23') | ||
|
||
def test_journal_allows_negative_balance(self): | ||
self.make_team() | ||
alice = self.make_participant('alice', balance=10) | ||
assert alice.balance == D('10.00') | ||
|
||
self.db.run(""" | ||
INSERT INTO journal | ||
(amount, debit, credit) | ||
VALUES ( 10.77 | ||
, (SELECT id FROM accounts WHERE participant='alice') | ||
, (SELECT id FROM accounts WHERE team='TheATeam') | ||
) | ||
""") | ||
|
||
assert Participant.from_username('alice').balance == D('-0.77') |
This is not a bug because we have accounts payable/receivable. See #3616 (comment).