[tests] Check transactions for errors before being added
- Added support for Exception-specific HTTP response codes for AccountinExceptions.
This commit is contained in:
		
							parent
							
								
									ef12c232ad
								
							
						
					
					
						commit
						8abbe3462f
					
				
					 5 changed files with 52 additions and 10 deletions
				
			
		|  | @ -19,7 +19,11 @@ def jsonify_exceptions(func): | |||
|         try: | ||||
|             return func(*args, **kw) | ||||
|         except AccountingException as exc: | ||||
|             return jsonify(error=exc) | ||||
|             response = jsonify(error=exc) | ||||
| 
 | ||||
|             response.status_code = exc.http_code | ||||
| 
 | ||||
|             return response | ||||
| 
 | ||||
|     return wrapper | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ class AccountingException(Exception): | |||
|     Used as a base for exceptions that are returned to the caller via the | ||||
|     jsonify_exceptions decorator | ||||
|     ''' | ||||
|     http_code = 500 | ||||
|     def __init__(self, message, **kw): | ||||
|         self.message = message | ||||
|         for key, value in kw.items(): | ||||
|  | @ -14,12 +15,12 @@ class AccountingException(Exception): | |||
| 
 | ||||
| 
 | ||||
| class TransactionNotFound(AccountingException): | ||||
|     pass | ||||
|     http_code = 404 | ||||
| 
 | ||||
| 
 | ||||
| class LedgerNotBalanced(AccountingException): | ||||
|     pass | ||||
|     http_code = 400 | ||||
| 
 | ||||
| 
 | ||||
| class TransactionIDCollision(AccountingException): | ||||
|     pass | ||||
|     http_code = 400 | ||||
|  |  | |||
|  | @ -173,6 +173,18 @@ class Ledger(Storage): | |||
|         with open(self.ledger_file, 'ab') as f: | ||||
|             f.write(output) | ||||
| 
 | ||||
|         # Check to see that no errors were introduced | ||||
|         try: | ||||
|             self.get_transactions() | ||||
|         except AccountingException as exc: | ||||
|             # TODO: Do a hard reset on the repository using Repository.reset, | ||||
|             # this is on hold because of | ||||
|             # https://github.com/libgit2/pygit2/issues/271. | ||||
|             # This solution will work in the meantime | ||||
|             self.delete_transaction(transaction.id) | ||||
|             setattr(exc, 'transaction', transaction) | ||||
|             raise exc | ||||
| 
 | ||||
|         self.commit_changes('Added transaction %s' % transaction.id) | ||||
| 
 | ||||
|         _log.info('Added transaction %s', transaction.id) | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ import copy | |||
| import uuid | ||||
| 
 | ||||
| from datetime import datetime | ||||
| from decimal import Decimal | ||||
| 
 | ||||
| from flask import json | ||||
| 
 | ||||
|  | @ -17,7 +18,7 @@ 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) | ||||
| #logging.basicConfig(level=logging.DEBUG) | ||||
| 
 | ||||
| 
 | ||||
| class TransactionTestCase(unittest.TestCase): | ||||
|  | @ -263,13 +264,36 @@ class TransactionTestCase(unittest.TestCase): | |||
|             ] | ||||
|         ) | ||||
| 
 | ||||
|         self._post_json('/transaction', transaction) | ||||
|         response = self._post_json('/transaction', transaction, expect=400) | ||||
| 
 | ||||
|         response = self._get_json('/transaction') | ||||
|         self.assertEqual(response['error']['type'], 'LedgerNotBalanced') | ||||
| 
 | ||||
|         import pdb; pdb.set_trace() | ||||
|     def test_update_transaction_amounts(self): | ||||
|         transaction = self._add_simple_transaction() | ||||
|         response = self._get_json( | ||||
|             '/transaction/' + transaction.id) | ||||
| 
 | ||||
|     def test_update_transaction_amounts(self): pass | ||||
|         transaction = response['transaction'] | ||||
| 
 | ||||
|         for posting in transaction.postings: | ||||
|             posting.amount.amount *= Decimal(1.50) | ||||
| 
 | ||||
|         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_delete_nonexistent_transaction(self): | ||||
|         response = self._open_json('DELETE', '/transaction/I-do-not-exist', | ||||
|                                    expect=404) | ||||
| 
 | ||||
|         self.assertEqual(response['error']['type'], 'TransactionNotFound') | ||||
| 
 | ||||
|     def test_post_transaction_with_metadata(self): pass | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|  |  | |||
|  | @ -44,7 +44,8 @@ class AccountingEncoder(json.JSONEncoder): | |||
|         elif isinstance(o, AccountingException): | ||||
|             return dict( | ||||
|                 type=o.__class__.__name__, | ||||
|                 message=o.message | ||||
|                 message=o.message, | ||||
|                 transaction=getattr(o, 'transaction', None) | ||||
|             ) | ||||
| 
 | ||||
|         return json.JSONEncoder.default(self, o) | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Joar Wandborg
						Joar Wandborg