[tests] Added tests and updated storage.ledgercli
- [ledgercli] Log info messages for operations such as add, delete, update transactions
This commit is contained in:
		
							parent
							
								
									0108548b4b
								
							
						
					
					
						commit
						3620d97f9d
					
				
					 3 changed files with 284 additions and 0 deletions
				
			
		|  | @ -211,6 +211,8 @@ class Ledger(Storage): | |||
|         with open(self.ledger_file, 'ab') as f: | ||||
|             f.write(output) | ||||
| 
 | ||||
|         _log.info('Added transaction %s', transaction.id) | ||||
| 
 | ||||
|         _log.debug('written to file: %s', output) | ||||
| 
 | ||||
|         return transaction.id | ||||
|  | @ -419,6 +421,11 @@ class Ledger(Storage): | |||
|             # Delete the preceding line to make the file | ||||
|             del_start -= 1 | ||||
| 
 | ||||
|         _log.info('Removing transaction with ID: %s (lines %d-%d)', | ||||
|                    transaction_id, | ||||
|                    del_start, | ||||
|                    semantic_lines['next_transaction_or_eof']) | ||||
| 
 | ||||
|         del lines[del_start:semantic_lines['next_transaction_or_eof']] | ||||
| 
 | ||||
|         with open(self.ledger_file, 'w') as f: | ||||
|  | @ -444,6 +451,7 @@ class Ledger(Storage): | |||
| 
 | ||||
|         self.add_transaction(transaction) | ||||
| 
 | ||||
|         _log.info('Updated transaction %s', transaction.id) | ||||
|         _log.debug('Updated transaction from: %s to: %s', old_transaction, | ||||
|                    transaction) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										0
									
								
								accounting/tests/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								accounting/tests/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										276
									
								
								accounting/tests/test_transactions.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								accounting/tests/test_transactions.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,276 @@ | |||
| ''' | ||||
| Tests for accounting-api | ||||
| ''' | ||||
| import os | ||||
| import unittest | ||||
| import tempfile | ||||
| import logging | ||||
| import copy | ||||
| import uuid | ||||
| 
 | ||||
| from datetime import datetime | ||||
| 
 | ||||
| from flask import json | ||||
| 
 | ||||
| from accounting.web import app, init_ledger | ||||
| 
 | ||||
| from accounting.transport import AccountingEncoder, AccountingDecoder | ||||
| from accounting.models import Transaction, Posting, Amount | ||||
| 
 | ||||
| logging.basicConfig(level=logging.DEBUG) | ||||
| 
 | ||||
| 
 | ||||
| class TransactionTestCase(unittest.TestCase): | ||||
|     def setUp(self): | ||||
|         self.app = app.test_client() | ||||
|         self.fd, app.config['LEDGER_FILE'] = tempfile.mkstemp() | ||||
|         init_ledger() | ||||
|         self.simple_transaction = Transaction( | ||||
|             date=datetime.today(), | ||||
|             payee='Joar', | ||||
|             postings=[ | ||||
|                 Posting('Assets:Checking', Amount('-133.7', 'USD')), | ||||
|                 Posting('Expenses:Foo', Amount('133.7', 'USD')) | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         os.close(self.fd) | ||||
|         os.unlink(app.config['LEDGER_FILE']) | ||||
| 
 | ||||
|     def test_get_transactions(self): | ||||
|         open(app.config['LEDGER_FILE'], 'w').write( | ||||
|             '1400-12-21 Old stuff\n' | ||||
|             '  ;Id: foo\n' | ||||
|             '  Assets:Checking  -100 USD\n' | ||||
|             '  Expenses:Tax  100 USD\n') | ||||
|         rv = self.app.get('/transaction') | ||||
| 
 | ||||
|         json_transaction = ( | ||||
|             b'{\n' | ||||
|             b'  "transactions": [\n' | ||||
|             b'    {\n' | ||||
|             b'      "__type__": "Transaction", \n' | ||||
|             b'      "date": "1400-12-21", \n' | ||||
|             b'      "id": "foo", \n' | ||||
|             b'      "metadata": {}, \n' | ||||
|             b'      "payee": "Old stuff", \n' | ||||
|             b'      "postings": [\n' | ||||
|             b'        {\n' | ||||
|             b'          "__type__": "Posting", \n' | ||||
|             b'          "account": "Assets:Checking", \n' | ||||
|             b'          "amount": {\n' | ||||
|             b'            "__type__": "Amount", \n' | ||||
|             b'            "amount": "-100", \n' | ||||
|             b'            "symbol": "USD"\n' | ||||
|             b'          }, \n' | ||||
|             b'          "metadata": {}\n' | ||||
|             b'        }, \n' | ||||
|             b'        {\n' | ||||
|             b'          "__type__": "Posting", \n' | ||||
|             b'          "account": "Expenses:Tax", \n' | ||||
|             b'          "amount": {\n' | ||||
|             b'            "__type__": "Amount", \n' | ||||
|             b'            "amount": "100", \n' | ||||
|             b'            "symbol": "USD"\n' | ||||
|             b'          }, \n' | ||||
|             b'          "metadata": {}\n' | ||||
|             b'        }\n' | ||||
|             b'      ]\n' | ||||
|             b'    }\n' | ||||
|             b'  ]\n' | ||||
|             b'}') | ||||
| 
 | ||||
|         self.assertEqual(rv.get_data(), json_transaction) | ||||
| 
 | ||||
|     def _post_json(self, path, data, expect=200, **kw): | ||||
|         response = self.app.post( | ||||
|             path, | ||||
|             content_type='application/json', | ||||
|             data=json.dumps(data, cls=AccountingEncoder), | ||||
|             **kw | ||||
|         ) | ||||
| 
 | ||||
|         self.assertEqual(response.status_code, expect) | ||||
| 
 | ||||
|         return self._decode_response(response) | ||||
| 
 | ||||
|     def _decode_response(self, response): | ||||
|         return json.loads(response.data, cls=AccountingDecoder) | ||||
| 
 | ||||
|     def _get_json(self, path, expect=200, **kw): | ||||
|         response = self.app.get(path, **kw) | ||||
| 
 | ||||
|         self.assertEqual(response.status_code, expect) | ||||
| 
 | ||||
|         return self._decode_response(response) | ||||
| 
 | ||||
|     def _open_json(self, method, path, expect=200, **kw): | ||||
|         response = self.app.open( | ||||
|             path, | ||||
|             method=method.upper(), | ||||
|             **kw | ||||
|         ) | ||||
| 
 | ||||
|         self.assertEqual(response.status_code, expect) | ||||
| 
 | ||||
|         return self._decode_response(response) | ||||
| 
 | ||||
|     def _add_simple_transaction(self, transaction_id=None): | ||||
|         if transaction_id is None: | ||||
|             transaction_id = str(uuid.uuid4()) | ||||
| 
 | ||||
|         transaction = copy.deepcopy(self.simple_transaction) | ||||
|         transaction.id = transaction_id | ||||
| 
 | ||||
|         response = self._post_json('/transaction', transaction) | ||||
| 
 | ||||
|         self.assertEqual(len(response['transaction_ids']), 1) | ||||
|         self.assertEqual(response['status'], 'OK') | ||||
| 
 | ||||
|         response = self._get_json('/transaction/' + transaction.id) | ||||
| 
 | ||||
|         self.assertEqual(transaction_id, response['transaction'].id) | ||||
| 
 | ||||
|         self.assertEqual(response['transaction'], transaction) | ||||
| 
 | ||||
|         return transaction | ||||
| 
 | ||||
|     def test_post_transaction_without_id(self): | ||||
|         transaction = copy.deepcopy(self.simple_transaction) | ||||
| 
 | ||||
|         response = self._post_json('/transaction', transaction) | ||||
| 
 | ||||
|         self.assertEqual(len(response['transaction_ids']), 1) | ||||
|         self.assertEqual(response['status'], 'OK') | ||||
| 
 | ||||
|         transaction.id = response['transaction_ids'][0] | ||||
| 
 | ||||
|         response = self._get_json('/transaction/' + transaction.id) | ||||
| 
 | ||||
|         self.assertEqual(response['transaction'], transaction) | ||||
| 
 | ||||
|     def test_delete_transaction(self): | ||||
|         transaction = copy.deepcopy(self.simple_transaction) | ||||
| 
 | ||||
|         response = self._post_json('/transaction', transaction) | ||||
| 
 | ||||
|         transaction_id = response['transaction_ids'][0] | ||||
| 
 | ||||
|         self.assertIsNotNone(transaction_id) | ||||
| 
 | ||||
|         response = self._open_json('DELETE', | ||||
|                                   '/transaction/' + transaction_id) | ||||
| 
 | ||||
|         self.assertEqual(response['status'], 'OK') | ||||
| 
 | ||||
|         with self.assertRaises(ValueError): | ||||
|             # ValueError thrown because the response does not contain any JSON | ||||
|             response = self._get_json('/transaction/' + transaction_id, 404) | ||||
| 
 | ||||
|     def test_post_multiple_transactions(self): | ||||
|         transactions = [ | ||||
|             Transaction( | ||||
|                 date=datetime.today(), | ||||
|                 payee='Rent', | ||||
|                 postings=[ | ||||
|                     Posting( | ||||
|                         account='Assets:Checking', | ||||
|                         amount=Amount(amount='-4600.00', symbol='SEK') | ||||
|                     ), | ||||
|                     Posting( | ||||
|                         account='Expenses:Rent', | ||||
|                         amount=Amount(amount='4600.00', symbol='SEK') | ||||
|                     ) | ||||
|                 ] | ||||
|             ), | ||||
|             Transaction( | ||||
|                 date=datetime.today(), | ||||
|                 payee='Hosting', | ||||
|                 postings=[ | ||||
|                     Posting( | ||||
|                         account='Assets:Checking', | ||||
|                         amount=Amount(amount='-700.00', symbol='SEK') | ||||
|                     ), | ||||
|                     Posting( | ||||
|                         account='Expenses:Hosting', | ||||
|                         amount=Amount(amount='700.00', symbol='SEK') | ||||
|                     ) | ||||
|                 ] | ||||
|             ) | ||||
|         ] | ||||
| 
 | ||||
|         response = self._post_json('/transaction', | ||||
|                                   {'transactions': transactions}) | ||||
| 
 | ||||
|         self.assertEqual(len(response['transaction_ids']), 2) | ||||
| 
 | ||||
|         transactions[0].id = response['transaction_ids'][0] | ||||
|         transactions[1].id = response['transaction_ids'][1] | ||||
| 
 | ||||
|         response = self._get_json('/transaction/' + transactions[0].id) | ||||
| 
 | ||||
|         self.assertEqual(transactions[0], response['transaction']) | ||||
| 
 | ||||
|         response = self._get_json('/transaction/' + transactions[1].id) | ||||
| 
 | ||||
|         self.assertEqual(transactions[1], response['transaction']) | ||||
| 
 | ||||
|     def test_update_transaction_payee(self): | ||||
|         transaction = self._add_simple_transaction() | ||||
| 
 | ||||
|         transaction.payee = 'not Joar' | ||||
| 
 | ||||
|         response = self._post_json('/transaction/' + transaction.id, | ||||
|                                    {'transaction': transaction}) | ||||
| 
 | ||||
|         self.assertEqual(response['status'], 'OK') | ||||
| 
 | ||||
|         response = self._get_json('/transaction/'+ transaction.id) | ||||
| 
 | ||||
|         self.assertEqual(response['transaction'], transaction) | ||||
| 
 | ||||
|     def test_update_transaction_postings(self): | ||||
|         transaction = self._add_simple_transaction() | ||||
| 
 | ||||
|         postings = [ | ||||
|             Posting(account='Assets:Checking', | ||||
|                     amount=Amount(amount='-733.10', symbol='SEK')), | ||||
|             Posting(account='Expenses:Bar', | ||||
|                     amount=Amount(amount='733.10', symbol='SEK')) | ||||
|         ] | ||||
| 
 | ||||
|         transaction.postings = postings | ||||
| 
 | ||||
|         response = self._post_json('/transaction/' + transaction.id, | ||||
|                                    {'transaction': transaction}) | ||||
| 
 | ||||
|         self.assertEqual(response['status'], 'OK') | ||||
| 
 | ||||
|         response = self._get_json('/transaction/' + transaction.id) | ||||
| 
 | ||||
|         self.assertEqual(response['transaction'], transaction) | ||||
| 
 | ||||
|     def test_post_unbalanced_transaction(self): | ||||
|         transaction = Transaction( | ||||
|             date=datetime.today(), | ||||
|             payee='Unbalanced Transaction', | ||||
|             postings=[ | ||||
|                 Posting(account='Assets:Checking', | ||||
|                         amount=Amount(amount='100.00', symbol='USD')), | ||||
|                 Posting(account='Income:Foo', | ||||
|                         amount=Amount(amount='-100.01', symbol='USD')) | ||||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|         self._post_json('/transaction', transaction) | ||||
| 
 | ||||
|         response = self._get_json('/transaction') | ||||
| 
 | ||||
|         import pdb; pdb.set_trace() | ||||
| 
 | ||||
|     def test_update_transaction_amounts(self): pass | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Joar Wandborg
						Joar Wandborg