Skip to main content

web/pages/transaction/create/
split.rs

1use askama::Template;
2use axum::{extract::Query, response::IntoResponse};
3use serde::Deserialize;
4
5use crate::pages::HtmlTemplate;
6
7#[derive(Deserialize)]
8pub struct SplitCreateParams {
9    display_index: usize,
10}
11
12#[derive(Template)]
13#[template(path = "components/transaction/split_entry.html")]
14struct SplitEntryTemplate {
15    display_index: usize,
16    tags: Option<Vec<finance::tag::Tag>>,
17}
18
19pub async fn split_create_handler(Query(params): Query<SplitCreateParams>) -> impl IntoResponse {
20    HtmlTemplate(SplitEntryTemplate {
21        display_index: params.display_index,
22        tags: None,
23    })
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use askama::Template;
30
31    fn render_split(index: usize) -> String {
32        SplitEntryTemplate {
33            display_index: index,
34            tags: None,
35        }
36        .render()
37        .expect("split template should render")
38    }
39
40    #[test]
41    fn split_entry_has_amount_input() {
42        let html = render_split(0);
43        assert!(
44            html.contains(r#"name="splits[0][amount]"#),
45            "split entry must have amount input"
46        );
47    }
48
49    #[test]
50    fn split_entry_has_from_account_input() {
51        let html = render_split(0);
52        assert!(
53            html.contains(r#"name="splits[0][from_account]"#),
54            "split entry must have from_account hidden input"
55        );
56        assert!(
57            html.contains(r#"class="account-display from-account"#),
58            "split entry must have from-account display input"
59        );
60    }
61
62    #[test]
63    fn split_entry_has_to_account_input() {
64        let html = render_split(0);
65        assert!(
66            html.contains(r#"name="splits[0][to_account]"#),
67            "split entry must have to_account hidden input"
68        );
69        assert!(
70            html.contains(r#"class="account-display to-account"#),
71            "split entry must have to-account display input"
72        );
73    }
74
75    #[test]
76    fn split_entry_has_commodity_inputs() {
77        let html = render_split(0);
78        assert!(
79            html.contains(r#"name="splits[0][from_commodity]"#),
80            "split entry must have from_commodity hidden input"
81        );
82        assert!(
83            html.contains(r#"name="splits[0][to_commodity]"#),
84            "split entry must have to_commodity hidden input"
85        );
86    }
87
88    #[test]
89    fn split_entry_has_tag_editor() {
90        let html = render_split(0);
91        assert!(
92            html.contains("split-tags-container"),
93            "split entry must have split tags container"
94        );
95        assert!(
96            html.contains("split-tag-template"),
97            "split entry must have split tag template"
98        );
99    }
100
101    #[test]
102    fn split_entry_has_remove_button() {
103        let html = render_split(0);
104        assert!(
105            html.contains("remove-split-btn"),
106            "split entry must have remove button"
107        );
108    }
109
110    #[test]
111    fn split_entry_indexes_match_display_index() {
112        let html = render_split(3);
113        assert!(html.contains(r#"data-split-index="3"#));
114        assert!(html.contains(r#"name="splits[3][amount]"#));
115        assert!(html.contains(r#"name="splits[3][from_account]"#));
116        assert!(html.contains(r#"name="splits[3][to_account]"#));
117        assert!(html.contains("Split 4"));
118    }
119}