going somewhere.
This commit is contained in:
1 parent
64e9be8b5a
commit
9ccaeaf410
5 files changed
+102
-37
No files matched your search
@@ -1,4 +1,4 @@
|
||||
use rusqlite::{params, Params, Transaction};
|
||||
use rusqlite::{ffi, params, Params, Transaction};
|
||||
|
||||
use crate::db::accounts::{Account, get_account_by_id};
|
||||
use crate::db::cheques::SecurityEmitterCheque;
|
||||
@@ -29,21 +29,29 @@ fn _add_cheque_to_cashed_cheques_log(tx: &TransactionHelper,
|
||||
)
|
||||
VALUES(?1, ?2, ?3, ?4)
|
||||
";
|
||||
tx.execute(q, params![cheque.drawer_user_id,
|
||||
let ret = tx.execute(q, params![cheque.drawer_user_id,
|
||||
cheque.cheque_number,
|
||||
cheque.amount,
|
||||
cheque.security_id])?;
|
||||
Ok(())
|
||||
cheque.security_id]);
|
||||
match ret {
|
||||
Ok(_) => Ok(()),
|
||||
Err(Error::SqlError(rusqlite::Error::SqliteFailure(ffi::Error { code: _, extended_code: 2067 }, _))) =>
|
||||
Err(Error::DoubleSpendingError(format!("Cheque number {} from user {} has already been cached.", cheque.cheque_number, cheque.drawer_user_id))),
|
||||
Err(a) => Err(a)
|
||||
}
|
||||
}
|
||||
|
||||
fn cash_cheque(tx: &Transaction,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> CustomResult<()> {
|
||||
// move money to new account
|
||||
|
||||
if !securities::is_owner(tx, &cheque.security_id, &cheque.drawer_user_id).map_err(Error::SqlError)? {
|
||||
return Err(Error::InvalidDrawer(format!("The drawer is the security owner: {:?}", cheque)));
|
||||
}
|
||||
|
||||
// todo:
|
||||
// 1. payee is owner of the account.
|
||||
|
||||
|
||||
let myx = TransactionHelper::new(tx);
|
||||
_add_securities_to_account(&myx, cheque, account_id)?;
|
||||
@@ -54,51 +62,103 @@ fn cash_cheque(tx: &Transaction,
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
mod test_caching_cheques {
|
||||
use rusqlite::{Connection, params};
|
||||
use crate::db::accounts::create_account;
|
||||
|
||||
use crate::db::test_utils;
|
||||
use crate::db::{accounts, test_utils};
|
||||
use crate::db::external_id::{Id, SecurityId, UserId};
|
||||
use crate::db::users::User;
|
||||
use crate::migration;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn setup() -> Connection {
|
||||
fn setup_conn() -> Connection {
|
||||
let mut conn = Connection::open_in_memory().unwrap();
|
||||
migration::apply_migrations(&mut conn).unwrap();
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_basic() -> Result<(), Error> {
|
||||
let mut conn = setup();
|
||||
fn setup_basic() -> (Connection, UserId, SecurityId, UserId, AccountId) {
|
||||
let mut conn = setup_conn();
|
||||
let tx = conn.transaction().unwrap();
|
||||
let (users, securities, accounts) = test_utils::setup_basic_environment(&tx).unwrap();
|
||||
let sec = securities.get(0).unwrap();
|
||||
let drawer = users.get(0).unwrap();
|
||||
let payee = users.get(1).unwrap();
|
||||
let amount: u32 = 1000;
|
||||
let payee_account = create_account(&tx, & sec.id(), & payee.id()).unwrap();
|
||||
let payee_account = create_account(&tx, &sec.id(), &payee.id()).unwrap();
|
||||
|
||||
tx.commit().unwrap();
|
||||
(conn, drawer.id(), sec.id(), payee.id(), payee_account.id())
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_basic_happy_path() -> CustomResult<()> {
|
||||
let (mut conn, drawer, sec, payee, payee_account) = setup_basic();
|
||||
let tx = conn.transaction().unwrap();
|
||||
|
||||
|
||||
// let tx = conn.transaction()?;
|
||||
// SecurityEmitterCheque::new(securities.get())
|
||||
let cheque = SecurityEmitterCheque::new(
|
||||
drawer.id(),
|
||||
sec.id(),
|
||||
payee.id(),
|
||||
amount,
|
||||
drawer,
|
||||
sec,
|
||||
payee,
|
||||
1000,
|
||||
99,
|
||||
);
|
||||
|
||||
|
||||
cash_cheque(&tx, &cheque, &payee_account.id())?;
|
||||
|
||||
cash_cheque(&tx, &cheque, &payee_account)?;
|
||||
tx.commit().unwrap();
|
||||
|
||||
let tx = conn.transaction().unwrap();
|
||||
let acc = get_account_by_id(&tx, &payee_account).unwrap();
|
||||
assert_eq!(acc.raw_amount(), 1000);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_spend() -> CustomResult<()> {
|
||||
let (mut conn, drawer, sec, payee, payee_account) = setup_basic();
|
||||
let amount: u32 = 1000;
|
||||
let tx = conn.transaction().unwrap();
|
||||
|
||||
let cheque = SecurityEmitterCheque::new(
|
||||
drawer,
|
||||
sec,
|
||||
payee,
|
||||
1000,
|
||||
99,
|
||||
);
|
||||
|
||||
cash_cheque(&tx, &cheque, &payee_account)?;
|
||||
tx.commit().unwrap();
|
||||
let tx = conn.transaction().unwrap();
|
||||
|
||||
let ret = cash_cheque(&tx, &cheque, &payee_account);
|
||||
match ret {
|
||||
Err(Error::DoubleSpendingError(_)) => Ok(()),
|
||||
_ => Err(Error::Testing("Expected double spending error here.".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_drawer() -> CustomResult<()> {
|
||||
let (mut conn, drawer, sec, payee, payee_account) = setup_basic();
|
||||
let amount: u32 = 1000;
|
||||
let tx = conn.transaction().unwrap();
|
||||
let not_currency_owner = UserId::from_id(drawer.get_id() + 72623);
|
||||
let cheque = SecurityEmitterCheque::new(
|
||||
not_currency_owner,
|
||||
sec,
|
||||
payee,
|
||||
1000,
|
||||
99,
|
||||
);
|
||||
|
||||
let ret = cash_cheque(&tx, &cheque, &payee_account);
|
||||
match ret {
|
||||
Err(Error::InvalidDrawer(_)) => Ok(()),
|
||||
_ => Err(Error::Testing("Expected invalid drawer here.".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user