One test fails :(

This commit is contained in:
didier amyot committed 2023-04-11 16:13:38 -04:00
1 parent 0a31f89501
commit 1f05ae1957
5 files changed
+170 -12

No files matched your search

+112 -10
View File
@@ -1,4 +1,4 @@
use rusqlite::{params, Connection, Result, Row, ToSql, Transaction, OptionalExtension};
use rusqlite::{params, Connection, OptionalExtension, Result, Row, ToSql, Transaction};
use serde::Serialize;
use crate::db::_external_id::{Id, SecurityId};
@@ -89,7 +89,7 @@ impl Security {
impl Clone for Security {
fn clone(&self) -> Self {
Security{
Security {
id: self.id,
security_type: self.security_type.clone(),
symbol: self.symbol.clone(),
@@ -104,19 +104,97 @@ pub struct NewSecurity {
pub name: String,
}
struct InterestRate {
rate: f64,
start_date: i64,
end_date: Option<i64>,
}
impl InterestRate {
pub fn from_row(row: &Row) -> Result<InterestRate> {
Ok(InterestRate {
rate: row.get("rate")?,
start_date: row.get("start_date")?,
end_date: row.get("end_date")?,
})
}
}
fn set_initial_interest_rate(tx: &Connection, sec_id: &SecurityId) -> CustomResult<()> {
let q = "
INSERT INTO interest_rates(
security_id,
security_rate_id,
start_date,
end_date,
rate
)
SELECT id, 0, CURRENT_TIMESTAMP, NULL, 1.0
FROM securities
WHERE id = ?1 AND securities.security_type = ?2
";
tx.execute(q, params![sec_id, SecurityType::Currency]).map_err(Error::SqlError)?;
Ok(())
}
fn set_interest_rate(tx: &Connection, sec_id: &SecurityId, rate: f64) -> CustomResult<()> {
let q = "
INSERT INTO interest_rates(
security_id,
security_rate_id,
start_date,
end_date,
rate
)
SELECT ?1 AS security_id,
MAX(interest_rates.security_rate_id) + 1 AS security_rate_id,
CURRENT_TIMESTAMP AS start_date,
NULL AS end_date,
?2 AS rate
FROM interest_rates JOIN securities ON interest_rates.security_id = securities.id
WHERE interest_rates.security_id = ?1
AND securities.security_type = ?3
";
tx.execute(q, params![sec_id, rate, SecurityType::Currency])
.map_err(Error::SqlError)?;
Ok(())
}
fn get_rates(tx: &Connection, sec_id: &SecurityId) -> CustomResult<Vec<InterestRate>> {
let q = "
SELECT rate,
UNIXEPOCH(start_date) AS start_date,
UNIXEPOCH(end_date) AS end_date
FROM interest_rates
WHERE security_id = ?1
ORDER BY security_rate_id ASC";
let mut stmt = tx.prepare(q).map_err(Error::SqlError)?;
let ret: Vec<InterestRate> = stmt
.query_map(params![sec_id], InterestRate::from_row)
.map_err(Error::SqlError)?
.filter(Result::is_ok)
.map(Result::unwrap)
.collect();
return Ok(ret);
}
pub fn create_security(tx: &Connection, sec: &NewSecurity) -> CustomResult<Security> {
let q = "INSERT INTO
securities(name, symbol, security_type)
VALUES(?1, ?2, ?3)";
let params = (&sec.name, &sec.symbol, &sec.security_type);
tx.execute(q, params).map_err(Error::SqlError)?;
let new_sec_id:i64 = tx.last_insert_rowid();
let new_sec_id = &SecurityId::from_id(tx.last_insert_rowid());
let ret = get_security_by_id(tx, &SecurityId::from_id(new_sec_id))?;
if sec.security_type == SecurityType::Currency {
set_initial_interest_rate(tx, new_sec_id)?;
}
let ret = get_security_by_id(tx, new_sec_id)?;
Ok(ret.unwrap())
}
pub fn get_security_by_id(tx: &Connection, id: & SecurityId) -> CustomResult<Option<Security>> {
pub fn get_security_by_id(tx: &Connection, id: &SecurityId) -> CustomResult<Option<Security>> {
let q = "SELECT id AS sec_id,
security_type AS sec_security_type,
symbol AS sec_symbol,
@@ -126,7 +204,6 @@ pub fn get_security_by_id(tx: &Connection, id: & SecurityId) -> CustomResult<Opt
tx.query_row(q, params![id], Security::from_row)
.optional()
.map_err(Error::SqlError)
}
pub fn list_securities(conn: &Connection) -> CustomResult<Vec<Security>> {
@@ -184,14 +261,39 @@ mod test_securities {
}
#[test]
fn test_create_security() -> CustomResult<()> {
fn test_create_security_currency() -> CustomResult<()> {
let (mut conn, _users) = setup();
let new_sec = mock_currency_1();
let tx = conn.transaction().unwrap();
let sec = create_security(&tx, &new_sec)?;
let sec = create_security(&conn, &new_sec)?;
assert_eq!(sec.symbol, new_sec.symbol);
assert_eq!(sec.security_type, SecurityType::Currency);
tx.commit().unwrap();
let interest_rate = get_rates(&conn, &sec.id())?;
assert_eq!(interest_rate.len(), 1);
Ok(())
}
#[test]
fn test_create_security_bond() -> CustomResult<()> {
let (mut conn, _users) = setup();
let new_sec = mock_currency_2();
let sec = create_security(&conn, &new_sec)?;
assert_eq!(sec.symbol, new_sec.symbol);
assert_eq!(sec.security_type, SecurityType::Bond);
let interest_rate = get_rates(&conn, &sec.id())?;
assert_eq!(interest_rate.len(), 0);
Ok(())
}
#[test]
fn test_set_interest_rate() -> CustomResult<()> {
let (mut conn, _users) = setup();
let new_sec = mock_currency_1();
let sec = &create_security(&conn, &new_sec)?.id();
set_interest_rate(&conn, sec, 90.00)?;
let interest_rate = get_rates(&conn, sec)?;
assert_eq!(interest_rate.len(), 2);
Ok(())
}