Add monzo-row parsing testcases
All checks were successful
Build and Publish Docker Container / build (push) Successful in 9m19s

This commit is contained in:
Joshua Coles 2024-06-03 17:41:43 +01:00
parent 6c5d3910dc
commit 61de38b9bf
3 changed files with 70 additions and 3 deletions

View File

@ -0,0 +1,3 @@
Transaction ID,Date,Time,Type,Name,Emoji,Category,Amount,Currency,Local amount,Local currency,Notes and #tags,Address,Receipt,Description,Category split
tx_0000AhmcbFKVlkAFbeZuAk,11/05/2024,13:41:47,Pot transfer,Savings Pot,,Savings,-1.4,GBP,-1.4,GBP,,,,Round up,
tx_0000AhmgdZ0FzkVZou77Ev,11/05/2024,14:27:01,Card payment,D,💊,C,-100.42,GBP,-100.42,GBP,,B,,A,"Groceries:15.00,Personal care:10.00"
1 Transaction ID Date Time Type Name Emoji Category Amount Currency Local amount Local currency Notes and #tags Address Receipt Description Category split
2 tx_0000AhmcbFKVlkAFbeZuAk 11/05/2024 13:41:47 Pot transfer Savings Pot Savings -1.4 GBP -1.4 GBP Round up
3 tx_0000AhmgdZ0FzkVZou77Ev 11/05/2024 14:27:01 Card payment D 💊 C -100.42 GBP -100.42 GBP B A Groceries:15.00,Personal care:10.00

View File

@ -0,0 +1,38 @@
[
[
"tx_0000AhmcbFKVlkAFbeZuAk",
"2024-05-11T00:00:00.000Z",
"1899-12-30T13:41:47.000Z",
"Pot transfer",
"Savings Pot",
"",
"Savings",
-1.4,
"GBP",
-1.4,
"GBP",
"",
"",
"",
"Round up",
""
],
[
"tx_0000AhmgdZ0FzkVZou77Ev",
"2024-05-11T00:00:00.000Z",
"1899-12-30T14:27:01.000Z",
"Card payment",
"D",
"💊",
"C",
-100.42,
"GBP",
-100.42,
"GBP",
"",
"B",
"",
"A",
"Groceries:15.00,Personal care:10.00"
]
]

View File

@ -40,7 +40,7 @@ pub struct MonzoRow {
emoji: Option<String>,
description: Option<String>,
transaction_type: String,
title: String,
title: Option<String>,
timestamp: NaiveDateTime,
transaction_id: String,
}
@ -153,7 +153,7 @@ pub fn from_json_row(row: Vec<Value>) -> anyhow::Result<MonzoRow> {
Ok(MonzoRow {
transaction_id: json_required_str(&row[headings::TRANSACTION_ID], "Transaction ID")?,
title: json_required_str(&row[headings::NAME], "Title")?,
title: json_opt(&row[headings::NAME]),
transaction_type: json_required_str(&row[headings::TYPE], "Transaction type")?,
description: json_opt(&row[headings::DESCRIPTION]),
emoji: json_opt(&row[headings::EMOJI]),
@ -166,6 +166,32 @@ pub fn from_json_row(row: Vec<Value>) -> anyhow::Result<MonzoRow> {
})
}
#[test]
fn test_json() {
let json = include_str!("../../fixtures/transactions.json");
let csv = include_str!("../../fixtures/transactions.csv");
let json: Vec<Vec<Value>> = serde_json::from_str(json).unwrap();
let mut csv_reader = csv::Reader::from_reader(csv.as_bytes());
let json_rows = json.iter()
.map(|row| from_json_row(row.clone()))
.collect::<Result<Vec<_>, anyhow::Error>>()
.unwrap();
let csv_rows = csv_reader.records()
.map(|record| from_csv_row(record.unwrap()))
.collect::<Result<Vec<_>, anyhow::Error>>()
.unwrap();
assert_eq!(csv_rows.len(), json_rows.len(), "Different number of rows");
for (i, (json_row, csv_row)) in json_rows.iter().zip(csv_rows.iter()).enumerate() {
assert_eq!(json_row, csv_row, "Row {} is different", i);
assert_eq!(json_row.compute_hash(), csv_row.compute_hash(), "Row {} hash are different", i);
}
}
fn csv_opt(s: &str) -> Option<String> {
match s {
"" => None,
@ -185,7 +211,7 @@ pub fn from_csv_row(row: StringRecord) -> anyhow::Result<MonzoRow> {
Ok(MonzoRow {
timestamp,
transaction_id: row[headings::TRANSACTION_ID].to_string(),
title: row[headings::NAME].to_string(),
title: csv_opt(&row[headings::NAME]),
transaction_type: row[headings::TYPE].to_string(),
description: csv_opt(&row[headings::DESCRIPTION]),
emoji: csv_opt(&row[headings::EMOJI]),