Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 6d8f9e1

Browse files
committed
Prevent filter being set twice.
Setting the Author/Assignee filter to [None] should not trigger a filter in the view model: doing this will remove the [None] entry from Authors, which will cause the selection in the view to be set to null which will reset the filter.
1 parent 5f4674e commit 6d8f9e1

File tree

5 files changed

+130
-21
lines changed

5 files changed

+130
-21
lines changed

src/GitHub.App/SampleData/PullRequestListViewModelDesigner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public PullRequestListViewModelDesigner()
4444
SelectedAuthor = Authors.ElementAt(1);
4545
}
4646

47-
public ObservableCollection<IPullRequestModel> PullRequests { get; set; }
47+
public ITrackingCollection<IPullRequestModel> PullRequests { get; set; }
4848
public IPullRequestModel SelectedPullRequest { get; set; }
4949
public ICommand OpenPullRequest { get; set; }
5050

src/GitHub.App/ViewModels/PullRequestListViewModel.cs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
using GitHub.Exports;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
6-
using System.Threading.Tasks;
7-
using GitHub.Models;
83
using System.Collections.ObjectModel;
9-
using ReactiveUI;
10-
using NullGuard;
114
using System.ComponentModel.Composition;
12-
using GitHub.Services;
5+
using System.Linq;
136
using System.Reactive.Linq;
14-
using GitHub.Extensions.Reactive;
15-
using System.Windows.Data;
16-
using GitHub.Collections;
177
using System.Windows.Input;
18-
using GitHub.UI;
198
using System.Windows.Media.Imaging;
9+
using GitHub.Collections;
10+
using GitHub.Exports;
11+
using GitHub.Models;
12+
using GitHub.Services;
13+
using GitHub.UI;
14+
using NullGuard;
15+
using ReactiveUI;
2016

2117
namespace GitHub.ViewModels
2218
{
@@ -59,11 +55,11 @@ public PullRequestListViewModel(IRepositoryHost repositoryHost, ISimpleRepositor
5955
.Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor));
6056

6157
this.WhenAny(x => x.SelectedAssignee, x => x.Value)
62-
.Where(x => PullRequests != null)
58+
.Where(x => PullRequests != null && x != EmptyUser)
6359
.Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor));
6460

6561
this.WhenAny(x => x.SelectedAuthor, x => x.Value)
66-
.Where(x => PullRequests != null)
62+
.Where(x => PullRequests != null && x != EmptyUser)
6763
.Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a));
6864

6965
trackingAuthors = new TrackingCollection<IAccount>(Observable.Empty<IAccount>(),
@@ -86,7 +82,7 @@ public override void Initialize([AllowNull] ViewWithData data)
8682
{
8783
base.Initialize(data);
8884

89-
PullRequests = repositoryHost.ModelService.GetPullRequests(repository, pullRequests) as TrackingCollection<IPullRequestModel>;
85+
PullRequests = repositoryHost.ModelService.GetPullRequests(repository, pullRequests);
9086
pullRequests.Subscribe(pr =>
9187
{
9288
trackingAssignees.AddItem(pr.Assignee);
@@ -104,12 +100,12 @@ void UpdateFilter(PullRequestState state, [AllowNull]IAccount ass, [AllowNull]IA
104100
(aut == null || aut.Equals(pr.Author));
105101
}
106102

107-
TrackingCollection<IPullRequestModel> pullRequests;
108-
public ObservableCollection<IPullRequestModel> PullRequests
103+
ITrackingCollection<IPullRequestModel> pullRequests;
104+
public ITrackingCollection<IPullRequestModel> PullRequests
109105
{
110106
[return: AllowNull]
111107
get { return pullRequests; }
112-
private set { this.RaiseAndSetIfChanged(ref pullRequests, (TrackingCollection<IPullRequestModel>)value); }
108+
private set { this.RaiseAndSetIfChanged(ref pullRequests, value); }
113109
}
114110

115111
IPullRequestModel selectedPullRequest;

src/GitHub.Exports.Reactive/ViewModels/IPullRequestListViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public override string ToString()
1919

2020
public interface IPullRequestListViewModel : IViewModel
2121
{
22-
ObservableCollection<IPullRequestModel> PullRequests { get; }
22+
ITrackingCollection<IPullRequestModel> PullRequests { get; }
2323
IPullRequestModel SelectedPullRequest { get; }
2424
ICommand OpenPullRequest { get; }
2525
IReadOnlyList<PullRequestState> States { get; set; }
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reactive.Linq;
4+
using System.Windows.Media.Imaging;
5+
using GitHub.Collections;
6+
using GitHub.Models;
7+
using GitHub.Services;
8+
using GitHub.ViewModels;
9+
using NSubstitute;
10+
using Xunit;
11+
12+
namespace UnitTests.GitHub.App.ViewModels
13+
{
14+
public class PullRequestListViewModelTests : TestBaseClass
15+
{
16+
[Fact]
17+
public void SelectingAssigneeShouldTriggerFilter()
18+
{
19+
var repositoryHost = CreateRepositoryHost();
20+
var repository = Substitute.For<ISimpleRepositoryModel>();
21+
var prViewModel = new PullRequestListViewModel(repositoryHost, repository);
22+
23+
prViewModel.Initialize(null);
24+
prViewModel.PullRequests.DidNotReceive().Filter = AnyFilter;
25+
26+
prViewModel.SelectedAssignee = prViewModel.PullRequests[0].Assignee;
27+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
28+
}
29+
30+
[Fact]
31+
public void ResettingAssigneeToNoneShouldNotTriggerFilter()
32+
{
33+
var repositoryHost = CreateRepositoryHost();
34+
var repository = Substitute.For<ISimpleRepositoryModel>();
35+
var prViewModel = new PullRequestListViewModel(repositoryHost, repository);
36+
37+
prViewModel.Initialize(null);
38+
prViewModel.PullRequests.DidNotReceive().Filter = AnyFilter;
39+
40+
prViewModel.SelectedAssignee = prViewModel.PullRequests[0].Assignee;
41+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
42+
43+
// Setting the Assignee filter to [None] should not trigger a filter:
44+
// doing this will remove the [None] entry from Assignees, which will cause
45+
// the selection in the view to be set to null which will reset the filter.
46+
prViewModel.SelectedAssignee = prViewModel.EmptyUser;
47+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
48+
}
49+
50+
[Fact]
51+
public void SelectingAuthorShouldTriggerFilter()
52+
{
53+
var repositoryHost = CreateRepositoryHost();
54+
var repository = Substitute.For<ISimpleRepositoryModel>();
55+
var prViewModel = new PullRequestListViewModel(repositoryHost, repository);
56+
57+
prViewModel.Initialize(null);
58+
prViewModel.PullRequests.DidNotReceive().Filter = AnyFilter;
59+
60+
prViewModel.SelectedAuthor = prViewModel.PullRequests[0].Author;
61+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
62+
}
63+
64+
[Fact]
65+
public void ResettingAuthorToNoneShouldNotTriggerFilter()
66+
{
67+
var repositoryHost = CreateRepositoryHost();
68+
var repository = Substitute.For<ISimpleRepositoryModel>();
69+
var prViewModel = new PullRequestListViewModel(repositoryHost, repository);
70+
71+
prViewModel.Initialize(null);
72+
prViewModel.PullRequests.DidNotReceive().Filter = AnyFilter;
73+
74+
prViewModel.SelectedAuthor = prViewModel.PullRequests[0].Author;
75+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
76+
77+
// Setting the Author filter to [None] should not trigger a filter:
78+
// doing this will remove the [None] entry from Authors, which will cause
79+
// the selection in the view to be set to null which will reset the filter.
80+
prViewModel.SelectedAuthor = prViewModel.EmptyUser;
81+
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
82+
}
83+
84+
Func<IPullRequestModel, int, IList<IPullRequestModel>, bool> AnyFilter =>
85+
Arg.Any<Func<IPullRequestModel, int, IList<IPullRequestModel>, bool>>();
86+
87+
IRepositoryHost CreateRepositoryHost()
88+
{
89+
var result = Substitute.For<IRepositoryHost>();
90+
var modelService = Substitute.For<IModelService>();
91+
var bitmapSource = Observable.Empty<BitmapImage>();
92+
93+
var pullRequest = new PullRequestModel(
94+
1,
95+
"PR1",
96+
new Account("foo", true, false, 1, 0, bitmapSource),
97+
new Account("foo", true, false, 1, 0, bitmapSource),
98+
DateTimeOffset.MinValue);
99+
100+
var pullRequestCollection = Substitute.For<ITrackingCollection<IPullRequestModel>>();
101+
pullRequestCollection[0].Returns(pullRequest);
102+
103+
modelService.GetPullRequests(
104+
Arg.Any<ISimpleRepositoryModel>(),
105+
Arg.Any<ITrackingCollection<IPullRequestModel>>())
106+
.Returns(pullRequestCollection);
107+
result.ModelService.Returns(modelService);
108+
109+
return result;
110+
}
111+
}
112+
}

src/UnitTests/UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
<Compile Include="GitHub.App\ViewModels\GistCreationViewModelTests.cs" />
172172
<Compile Include="GitHub.App\ViewModels\LoginControlViewModelTests.cs" />
173173
<Compile Include="GitHub.App\ViewModels\LoginToGitHubViewModelTests.cs" />
174+
<Compile Include="GitHub.App\ViewModels\PullRequestListViewModelTests.cs" />
174175
<Compile Include="GitHub.App\ViewModels\RepositoryCloneViewModelTests.cs" />
175176
<Compile Include="GitHub.App\ViewModels\RepositoryCreationViewModelTests.cs" />
176177
<Compile Include="GitHub.App\ViewModels\RepositoryPublishViewModelTests.cs" />

0 commit comments

Comments
 (0)