mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-31 13:38:14 -06:00
LRC-LIB-SMARTCOLL: a stale album rule no longer drops the filter bar from the view
From review: view_rules merged the filter bar's settings onto a smart album's rules through merge_rules, which now also checks the rules, and fell back to the bare album rules on any problem. A smart album testing an album that was later deleted therefore lost the filter bar (e.g. Rating ≥ 3) from Create Smart Album from Filter and the dialog's count, without a word. merge_filter does the merge alone; merge_rules is merge_filter plus the check, for album.createSmart / setRules. view_rules uses merge_filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3c80695e97
commit
2d29dde4d0
@@ -1278,10 +1278,16 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
}
|
||||
|
||||
/// `base` with a partial Filter (JSON) merged on top.
|
||||
fn merge_rules(base: &lightcraft_catalog::Filter, patch: &Value, c: &str, cat: &lightcraft_catalog::Catalog) -> Result<lightcraft_catalog::Filter> {
|
||||
/// `patch` merged onto `base`, unchecked (see [`merge_rules`]).
|
||||
fn merge_filter(base: &lightcraft_catalog::Filter, patch: &Value, c: &str) -> Result<lightcraft_catalog::Filter> {
|
||||
let mut v = serde_json::to_value(base).unwrap_or_default();
|
||||
lightcraft_develop::presets::deep_merge(&mut v, patch);
|
||||
let f: lightcraft_catalog::Filter = serde_json::from_value(v).map_err(|e| bad(c, e.to_string()))?;
|
||||
serde_json::from_value(v).map_err(|e| bad(c, e.to_string()))
|
||||
}
|
||||
|
||||
/// `patch` merged onto `base`, refused when its rule set has problems (`RuleSet::check`).
|
||||
fn merge_rules(base: &lightcraft_catalog::Filter, patch: &Value, c: &str, cat: &lightcraft_catalog::Catalog) -> Result<lightcraft_catalog::Filter> {
|
||||
let f = merge_filter(base, patch, c)?;
|
||||
let problems = f.rule_set.as_ref().map(|r| r.check(cat)).unwrap_or_default();
|
||||
if !problems.is_empty() {
|
||||
return Err(bad(c, problems.iter().map(ToString::to_string).collect::<Vec<_>>().join("; ")));
|
||||
@@ -1320,7 +1326,9 @@ fn view_rules(s: &Session) -> lightcraft_catalog::Filter {
|
||||
}
|
||||
}
|
||||
}
|
||||
merge_rules(&base, &Value::Object(patch), "", &s.catalog).unwrap_or(base)
|
||||
// the view as it is: a rule that no longer checks (its album was deleted) just matches
|
||||
// nothing there, and mustn't cost the filter bar's settings
|
||||
merge_filter(&base, &Value::Object(patch), "").unwrap_or(base)
|
||||
}
|
||||
None => {
|
||||
let mut f = s.source.to_filter(&s.filter, &s.catalog);
|
||||
|
||||
@@ -79,6 +79,22 @@ fn smart_album_from_smart_album_view_keeps_its_rules() {
|
||||
assert_eq!(s.source, LibrarySource::Album(lightcraft_catalog::AlbumId(id)));
|
||||
}
|
||||
|
||||
/// Saving the view of a smart album keeps the filter bar's settings even when the album holds a
|
||||
/// rule that no longer checks (it tests an album that has since been deleted).
|
||||
#[test]
|
||||
fn smart_album_view_keeps_the_filter_bar_over_a_stale_rule() {
|
||||
let mut s = Session::with_demo();
|
||||
let gone = s.execute("album.create", &json!({"name": "Gone", "addSelected": false})).unwrap()["id"].as_u64().unwrap();
|
||||
let rules = json!({"ruleSet": {"rules": [{"field": "album", "op": "isNot", "value": gone}]}});
|
||||
let id = s.execute("album.createSmart", &json!({"name": "Not in Gone", "rules": rules})).unwrap()["id"].as_u64().unwrap();
|
||||
s.execute("album.delete", &json!({"id": gone})).unwrap();
|
||||
s.execute("library.source", &json!({"kind": "album", "id": id})).unwrap();
|
||||
s.execute("library.filter", &json!({"rating": 3})).unwrap();
|
||||
let r = s.view_rules();
|
||||
assert_eq!(r.rating, 3, "the filter bar's rating survives");
|
||||
assert!(r.rule_set.is_some(), "and so do the album's own rules");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_copies_are_independent_and_persist() {
|
||||
let dir = temp_dir("vc");
|
||||
|
||||
Reference in New Issue
Block a user