web fixes

This commit is contained in:
Priec
2026-08-14 18:46:31 +02:00
parent 0e6207fb44
commit 1c3d292479
13 changed files with 1458 additions and 105 deletions

View File

@@ -77,6 +77,7 @@ mod tests {
data_type: "text".to_string(),
indexed: true,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: String::new(),
});
@@ -136,6 +137,7 @@ mod tests {
data_type: "accounting".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
@@ -172,6 +174,7 @@ mod tests {
data_type: "accounting".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
@@ -199,6 +202,7 @@ mod tests {
data_type: "accounting".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
@@ -314,6 +318,7 @@ mod tests {
data_type: "money".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
@@ -337,6 +342,7 @@ mod tests {
data_type: "accounting".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
@@ -387,6 +393,115 @@ mod tests {
assert!(html.contains("htmx:beforeSwap"));
}
/// Choosing FKlink takes the Indexing choice away and says who makes the
/// index instead. Offering the choice is what sent a definition the server
/// refuses outright — a link is indexed automatically.
#[test]
fn choosing_a_link_replaces_the_index_choice_with_who_makes_it() {
let mut state = page();
assert!(render_builder(&state).contains(r#"name="column_indexing_input""#));
state.draft.columns.type_input = "link".to_string();
let html = render_builder(&state);
assert!(!html.contains(r#"name="column_indexing_input""#), "{html}");
assert!(html.contains("Indexed automatically"));
// The rest of the link's own fields are still there.
assert!(html.contains(r#"name="link_table_input""#));
assert!(html.contains("Link alias"));
}
/// And a link already in the list is reported as indexed, without a toggle
/// that would do nothing.
#[test]
fn a_link_in_the_column_list_is_shown_as_indexed_by_the_server() {
let mut state = page();
state.draft.columns.added.push(ColumnDefinition {
name: "billing_customer".to_string(),
data_type: "link(customer)".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: String::new(),
});
let html = render_builder(&state);
assert!(html.contains("indexed automatically"), "{html}");
// `number` keeps its toggle; the link is offered none.
assert!(html.contains(r#""action": "toggle-index", "index": "0""#));
assert!(!html.contains(r#""action": "toggle-index", "index": "1""#));
}
/// A column can be made required, and the answer travels with the draft.
#[test]
fn a_column_can_be_required_and_says_so_in_the_list() {
let mut state = page();
assert!(render_builder(&state).contains(r#"name="column_required_input""#));
state.draft.columns.added[0].required = true;
let html = render_builder(&state);
assert!(html.contains(r#"name="column_required" value="yes""#));
assert!(html.contains(r#"<span class="tag">required</span>"#));
}
/// A shared table keeps no books, so the columns that post to a profile's
/// books are not on offer and the page says why.
#[test]
fn the_shared_scope_offers_no_column_that_belongs_to_one_profile() {
let mut state = page();
state.draft.global = true;
state.draft.columns.global = true;
let html = render_builder(&state);
assert!(!html.contains(r#"<option value="accounting""#), "{html}");
assert!(!html.contains(r#"<option value="accounting_transfer""#));
assert!(!html.contains(r#"name="column_quantity_ledger_input""#));
assert!(html.contains("A shared table keeps no books of its own"));
// Everything else is still offered.
assert!(html.contains(r#"<option value="money""#));
}
/// A row is identified by the columns the table will really hold, which
/// includes what a definition row generates.
#[test]
fn generated_columns_can_identify_a_row() {
let mut state = page();
state.draft.columns.added.push(ColumnDefinition {
name: "accounting".to_string(),
data_type: "accounting".to_string(),
indexed: false,
quantity_ledger: false,
required: false,
money_mode: MoneyMode::Exact,
currency: "EUR".to_string(),
});
let candidates = state
.row_display_candidates()
.into_iter()
.map(|candidate| candidate.name)
.collect::<Vec<_>>();
assert_eq!(
candidates,
[
"id",
"number",
"name",
"tax_point_date",
"debit",
"credit",
"account"
]
);
// The definition row is not one of them, having no column of its name.
assert!(!candidates.contains(&"accounting".to_string()));
}
/// A load failure has no draft to render, so the dialog is the response.
#[test]
fn a_load_failure_answers_with_the_dialog() {