1
use askama::Template;
2
use axum::{extract::Query, response::IntoResponse};
3
use serde::Deserialize;
4

            
5
use crate::pages::HtmlTemplate;
6

            
7
#[derive(Deserialize)]
8
pub struct SplitCreateParams {
9
    display_index: usize,
10
}
11

            
12
#[derive(Template)]
13
#[template(path = "components/transaction/split_entry.html")]
14
struct SplitEntryTemplate {
15
    display_index: usize,
16
    tags: Option<Vec<finance::tag::Tag>>,
17
}
18

            
19
pub 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)]
27
mod tests {
28
    use super::*;
29
    use askama::Template;
30

            
31
14
    fn render_split(index: usize) -> String {
32
14
        SplitEntryTemplate {
33
14
            display_index: index,
34
14
            tags: None,
35
14
        }
36
14
        .render()
37
14
        .expect("split template should render")
38
14
    }
39

            
40
    #[test]
41
2
    fn split_entry_has_amount_input() {
42
2
        let html = render_split(0);
43
2
        assert!(
44
2
            html.contains(r#"name="splits[0][amount]"#),
45
            "split entry must have amount input"
46
        );
47
2
    }
48

            
49
    #[test]
50
2
    fn split_entry_has_from_account_input() {
51
2
        let html = render_split(0);
52
2
        assert!(
53
2
            html.contains(r#"name="splits[0][from_account]"#),
54
            "split entry must have from_account hidden input"
55
        );
56
2
        assert!(
57
2
            html.contains(r#"class="account-display from-account"#),
58
            "split entry must have from-account display input"
59
        );
60
2
    }
61

            
62
    #[test]
63
2
    fn split_entry_has_to_account_input() {
64
2
        let html = render_split(0);
65
2
        assert!(
66
2
            html.contains(r#"name="splits[0][to_account]"#),
67
            "split entry must have to_account hidden input"
68
        );
69
2
        assert!(
70
2
            html.contains(r#"class="account-display to-account"#),
71
            "split entry must have to-account display input"
72
        );
73
2
    }
74

            
75
    #[test]
76
2
    fn split_entry_has_commodity_inputs() {
77
2
        let html = render_split(0);
78
2
        assert!(
79
2
            html.contains(r#"name="splits[0][from_commodity]"#),
80
            "split entry must have from_commodity hidden input"
81
        );
82
2
        assert!(
83
2
            html.contains(r#"name="splits[0][to_commodity]"#),
84
            "split entry must have to_commodity hidden input"
85
        );
86
2
    }
87

            
88
    #[test]
89
2
    fn split_entry_has_tag_editor() {
90
2
        let html = render_split(0);
91
2
        assert!(
92
2
            html.contains("split-tags-container"),
93
            "split entry must have split tags container"
94
        );
95
2
        assert!(
96
2
            html.contains("split-tag-template"),
97
            "split entry must have split tag template"
98
        );
99
2
    }
100

            
101
    #[test]
102
2
    fn split_entry_has_remove_button() {
103
2
        let html = render_split(0);
104
2
        assert!(
105
2
            html.contains("remove-split-btn"),
106
            "split entry must have remove button"
107
        );
108
2
    }
109

            
110
    #[test]
111
2
    fn split_entry_indexes_match_display_index() {
112
2
        let html = render_split(3);
113
2
        assert!(html.contains(r#"data-split-index="3"#));
114
2
        assert!(html.contains(r#"name="splits[3][amount]"#));
115
2
        assert!(html.contains(r#"name="splits[3][from_account]"#));
116
2
        assert!(html.contains(r#"name="splits[3][to_account]"#));
117
2
        assert!(html.contains("Split 4"));
118
2
    }
119
}