Skip to content

Commit e092706

Browse files
committed
test: 增加 MultiFilter 单元测试
1 parent 4e35593 commit e092706

File tree

2 files changed

+262
-37
lines changed

2 files changed

+262
-37
lines changed

src/BootstrapBlazor/Components/Filters/MultiFilter.razor.cs

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -117,43 +117,6 @@ protected override async Task InvokeInitAsync()
117117
}
118118
}
119119

120-
/// <summary>
121-
/// 重置过滤条件方法
122-
/// </summary>
123-
public override void Reset()
124-
{
125-
_searchText = null;
126-
if (_source != null)
127-
{
128-
foreach (var item in _source)
129-
{
130-
item.Active = false;
131-
}
132-
}
133-
_items = null;
134-
StateHasChanged();
135-
}
136-
137-
/// <summary>
138-
/// 生成过滤条件方法
139-
/// </summary>
140-
/// <returns></returns>
141-
public override FilterKeyValueAction GetFilterConditions()
142-
{
143-
var filter = new FilterKeyValueAction { Filters = [], FilterLogic = FilterLogic.Or };
144-
145-
foreach (var item in GetItems().Where(i => i.Active))
146-
{
147-
filter.Filters.Add(new FilterKeyValueAction
148-
{
149-
FieldKey = FieldKey,
150-
FieldValue = item.Value,
151-
FilterAction = FilterAction.Equal
152-
});
153-
}
154-
return filter;
155-
}
156-
157120
/// <summary>
158121
/// JavaScript 回调方法
159122
/// </summary>
@@ -240,4 +203,63 @@ private Task OnSearchValueChanged(string? val)
240203
}
241204

242205
private List<SelectedItem> GetItems() => _items ?? _source ?? [];
206+
207+
/// <summary>
208+
/// 重置过滤条件方法
209+
/// </summary>
210+
public override void Reset()
211+
{
212+
_searchText = null;
213+
if (_source != null)
214+
{
215+
foreach (var item in _source)
216+
{
217+
item.Active = false;
218+
}
219+
}
220+
_items = null;
221+
StateHasChanged();
222+
}
223+
224+
/// <summary>
225+
/// 生成过滤条件方法
226+
/// </summary>
227+
/// <returns></returns>
228+
public override FilterKeyValueAction GetFilterConditions()
229+
{
230+
var filter = new FilterKeyValueAction { FilterLogic = FilterLogic.Or };
231+
foreach (var item in GetItems().Where(i => i.Active))
232+
{
233+
filter.Filters.Add(new FilterKeyValueAction
234+
{
235+
FieldKey = FieldKey,
236+
FieldValue = item.Value,
237+
FilterAction = FilterAction.Equal
238+
});
239+
}
240+
return filter;
241+
}
242+
243+
/// <summary>
244+
/// <inheritdoc/>
245+
/// </summary>
246+
/// <param name="filter"></param>
247+
/// <returns></returns>
248+
public override async Task SetFilterConditionsAsync(FilterKeyValueAction filter)
249+
{
250+
var items = GetItems();
251+
if (items.Count > 0)
252+
{
253+
foreach (var f in filter.Filters)
254+
{
255+
var val = f.FieldValue?.ToString();
256+
var item = items.Find(i => i.Value == val);
257+
if (item != null)
258+
{
259+
item.Active = true;
260+
}
261+
}
262+
}
263+
await base.SetFilterConditionsAsync(filter);
264+
}
243265
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
namespace UnitTest.Components;
7+
8+
public class TableMultiFilterTest : BootstrapBlazorTestBase
9+
{
10+
[Fact]
11+
public void IsHeaderRow_Ok()
12+
{
13+
var cut = Context.RenderComponent<MultiFilter>(pb =>
14+
{
15+
pb.Add(a => a.IsHeaderRow, true);
16+
});
17+
Assert.Equal("", cut.Markup);
18+
}
19+
20+
[Fact]
21+
public void InvalidOperationException_Ok()
22+
{
23+
Assert.Throws<InvalidOperationException>(() =>
24+
{
25+
Context.RenderComponent<MultiFilter>(pb =>
26+
{
27+
pb.Add(a => a.Items, new List<SelectedItem>()
28+
{
29+
new("1", "Test-1"),
30+
new("2", "Test-2"),
31+
new("3", "Test-3")
32+
});
33+
pb.Add(a => a.OnGetItemsAsync, new Func<Task<List<SelectedItem>>>(() => Task.FromResult(new List<SelectedItem>())));
34+
});
35+
});
36+
}
37+
38+
[Fact]
39+
public async Task ShowSearch_Ok()
40+
{
41+
var cut = Context.RenderComponent<MultiFilter>(pb =>
42+
{
43+
pb.Add(a => a.Items, new List<SelectedItem>()
44+
{
45+
new("1", "Test-1"),
46+
new("2", "Test-2"),
47+
new("3", "Test-3")
48+
});
49+
pb.Add(a => a.StringComparison, StringComparison.OrdinalIgnoreCase);
50+
pb.Add(a => a.ShowSearch, true);
51+
});
52+
cut.Contains("bb-multi-filter-search");
53+
var input = cut.Find(".bb-multi-filter-search");
54+
await cut.InvokeAsync(() => input.Input("1"));
55+
await cut.InvokeAsync(() => input.Input(""));
56+
57+
cut.SetParametersAndRender(pb =>
58+
{
59+
pb.Add(a => a.ShowSearch, false);
60+
});
61+
cut.DoesNotContain("bb-multi-filter-search");
62+
}
63+
64+
[Fact]
65+
public async Task OnGetItemsAsync_Ok()
66+
{
67+
var cut = Context.RenderComponent<MultiFilter>(pb =>
68+
{
69+
pb.Add(a => a.OnGetItemsAsync, new Func<Task<List<SelectedItem>>>(() => Task.FromResult(new List<SelectedItem>()
70+
{
71+
new("1", "Test-1"),
72+
new("2", "Test-2"),
73+
new("3", "Test-3")
74+
})));
75+
pb.Add(a => a.StringComparison, StringComparison.OrdinalIgnoreCase);
76+
pb.Add(a => a.AlwaysTriggerGetItems, false);
77+
});
78+
79+
await cut.InvokeAsync(() => cut.Instance.TriggerGetItemsCallback());
80+
81+
// 选中第一个
82+
var checkboxs = cut.FindComponents<Checkbox<bool>>();
83+
await cut.InvokeAsync(() => checkboxs[1].Instance.SetState(CheckboxState.Checked));
84+
await cut.InvokeAsync(() => cut.Instance.TriggerGetItemsCallback());
85+
}
86+
87+
[Fact]
88+
public async Task SelectAll_Ok()
89+
{
90+
var items = new List<SelectedItem>()
91+
{
92+
new("1", "Test-1"),
93+
new("2", "Test-2"),
94+
new("3", "Test-3")
95+
};
96+
var cut = Context.RenderComponent<MultiFilter>(pb =>
97+
{
98+
pb.Add(a => a.Items, items);
99+
});
100+
var checkbox = cut.FindComponent<Checkbox<bool>>();
101+
102+
// 全选
103+
await cut.InvokeAsync(() => checkbox.Instance.SetState(CheckboxState.Checked));
104+
Assert.All(items, i => Assert.True(i.Active));
105+
106+
// 取消全选
107+
await cut.InvokeAsync(() => checkbox.Instance.SetState(CheckboxState.UnChecked));
108+
Assert.All(items, i => Assert.False(i.Active));
109+
}
110+
111+
[Fact]
112+
public void Items_Ok()
113+
{
114+
var items = new List<SelectedItem>()
115+
{
116+
new("1", "Test-1") { Active = true },
117+
new("2", "Test-2")
118+
};
119+
var cut = Context.RenderComponent<MultiFilter>(pb =>
120+
{
121+
pb.Add(a => a.Items, items);
122+
});
123+
124+
// 更新数据源保持选项选中状态
125+
items =
126+
[
127+
new("1", "Test-1") { Active = false },
128+
new("2", "Test-2") { Active = true }
129+
];
130+
cut.SetParametersAndRender(pb =>
131+
{
132+
pb.Add(a => a.Items, items);
133+
});
134+
var conditions = cut.Instance.GetFilterConditions();
135+
Assert.Equal(2, conditions.Filters.Count);
136+
}
137+
138+
[Fact]
139+
public void LoadingTemplate_Ok()
140+
{
141+
var cut = Context.RenderComponent<MultiFilter>(pb =>
142+
{
143+
pb.Add(a => a.LoadingTemplate, new RenderFragment(builder =>
144+
{
145+
builder.AddContent(0, "Loading");
146+
}));
147+
});
148+
cut.Contains("Loading");
149+
}
150+
151+
[Fact]
152+
public async Task FilterAction_Ok()
153+
{
154+
var cut = Context.RenderComponent<MultiFilter>(pb =>
155+
{
156+
pb.Add(a => a.Items, new List<SelectedItem>()
157+
{
158+
new("1", "Test-1"),
159+
new("2", "Test-2"),
160+
new("3", "Test-3")
161+
});
162+
});
163+
var filter = cut.Instance;
164+
165+
var newConditions = new FilterKeyValueAction()
166+
{
167+
Filters =
168+
[
169+
new FilterKeyValueAction() { FieldValue = "1" },
170+
new FilterKeyValueAction() { FieldValue = "2" }
171+
]
172+
};
173+
await cut.InvokeAsync(() => filter.SetFilterConditionsAsync(newConditions));
174+
var conditions = filter.GetFilterConditions();
175+
Assert.Equal(2, conditions.Filters.Count);
176+
await cut.InvokeAsync(() => filter.Reset());
177+
conditions = filter.GetFilterConditions();
178+
Assert.Empty(conditions.Filters);
179+
180+
// Improve test coverage
181+
newConditions = new FilterKeyValueAction()
182+
{
183+
Filters =
184+
[
185+
new FilterKeyValueAction() { FieldValue = null },
186+
]
187+
};
188+
await cut.InvokeAsync(() => filter.SetFilterConditionsAsync(newConditions));
189+
conditions = filter.GetFilterConditions();
190+
Assert.Empty(conditions.Filters);
191+
}
192+
193+
class MockTable : ITable
194+
{
195+
public Dictionary<string, IFilterAction> Filters { get; set; } = [];
196+
197+
public Func<Task>? OnFilterAsync { get; set; }
198+
199+
public List<ITableColumn> Columns => [];
200+
201+
public IEnumerable<ITableColumn> GetVisibleColumns() => Columns;
202+
}
203+
}

0 commit comments

Comments
 (0)