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

Commit ebc0127

Browse files
committed
Don't show NoOpenItems when there's search criteria.
And add unit tests.
1 parent dd6d3f8 commit ebc0127

File tree

4 files changed

+200
-190
lines changed

4 files changed

+200
-190
lines changed

src/GitHub.App/ViewModels/GitHubPane/IssueListViewModelBase.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ public override Task Refresh()
173173
Observable.CombineLatest(
174174
itemSource.WhenAnyValue(x => x.IsLoading),
175175
view.WhenAnyValue(x => x.Count),
176-
(loading, count) => Tuple.Create(loading, count))
176+
this.WhenAnyValue(x => x.SearchQuery),
177+
this.WhenAnyValue(x => x.SelectedState),
178+
this.WhenAnyValue(x => x.AuthorFilter.Selected),
179+
(loading, count, _, __, ___) => Tuple.Create(loading, count))
177180
.Subscribe(x => UpdateState(x.Item1, x.Item2)));
178181
subscription = dispose;
179182

test/GitHub.App.UnitTests/GitHub.App.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
<Compile Include="ViewModels\Dialog\RepositoryCloneViewModelTests.cs" />
181181
<Compile Include="ViewModels\Dialog\RepositoryCreationViewModelTests.cs" />
182182
<Compile Include="ViewModels\GitHubPane\GitHubPaneViewModelTests.cs" />
183+
<Compile Include="ViewModels\GitHubPane\IssueListViewModelBaseTests.cs" />
183184
<Compile Include="ViewModels\GitHubPane\NavigationViewModelTests.cs" />
184185
<Compile Include="ViewModels\GitHubPane\PullRequestDetailViewModelTests.cs" />
185186
<Compile Include="ViewModels\GitHubPane\PullRequestFilesViewModelTests.cs" />
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reactive.Linq;
5+
using System.Threading.Tasks;
6+
using GitHub.Collections;
7+
using GitHub.Models;
8+
using GitHub.Primitives;
9+
using GitHub.Services;
10+
using GitHub.ViewModels.GitHubPane;
11+
using NSubstitute;
12+
using NUnit.Framework;
13+
14+
namespace UnitTests.GitHub.App.ViewModels.GitHubPane
15+
{
16+
public class IssueListViewModelBaseTests : TestBaseClass
17+
{
18+
[Test]
19+
public async Task First_State_Should_Be_Selected()
20+
{
21+
var target = await CreateTargetAndInitialize();
22+
23+
Assert.That(target.SelectedState, Is.EqualTo("Open"));
24+
}
25+
26+
[Test]
27+
public async Task Forks_Should_Be_Empty_If_No_Parent_Repository()
28+
{
29+
var target = await CreateTargetAndInitialize();
30+
31+
Assert.That(target.Forks, Is.Null);
32+
}
33+
34+
[Test]
35+
public async Task Forks_Should_Not_Be_Empty_If_Has_Parent_Repository()
36+
{
37+
var repositoryService = CreateRepositoryService("parent");
38+
var target = await CreateTargetAndInitialize(repositoryService: repositoryService);
39+
40+
Assert.That(target.Forks, Is.Not.Null);
41+
Assert.That(target.Forks.Count, Is.EqualTo(2));
42+
}
43+
44+
[Test]
45+
public async Task Initializing_Loads_First_Page_Of_Items()
46+
{
47+
var target = await CreateTargetAndInitialize();
48+
49+
await target.ItemSource.Received().GetPage(0);
50+
}
51+
52+
[Test]
53+
public async Task With_Items_Returns_Message_None()
54+
{
55+
var target = await CreateTargetAndInitialize();
56+
57+
Assert.That(target.Message, Is.EqualTo(IssueListMessage.None));
58+
}
59+
60+
[Test]
61+
public async Task No_Items_No_Filter_Returns_Message_NoOpenItems()
62+
{
63+
var target = await CreateTargetAndInitialize(itemCount: 0);
64+
65+
Assert.That(target.Message, Is.EqualTo(IssueListMessage.NoOpenItems));
66+
}
67+
68+
[Test]
69+
public async Task No_Items_With_SearchQuery_Returns_Message_NoOpenItems()
70+
{
71+
var target = await CreateTargetAndInitialize(itemCount: 0);
72+
target.SearchQuery = "foo";
73+
74+
Assert.That(target.Message, Is.EqualTo(IssueListMessage.NoItemsMatchCriteria));
75+
}
76+
77+
[Test]
78+
public async Task No_Items_With_Closed_State_Returns_Message_NoOpenItems()
79+
{
80+
var target = await CreateTargetAndInitialize(itemCount: 0);
81+
target.SelectedState = "Closed";
82+
83+
Assert.That(target.Message, Is.EqualTo(IssueListMessage.NoItemsMatchCriteria));
84+
}
85+
86+
[Test]
87+
public async Task No_Items_With_Author_Filter_Returns_Message_NoOpenItems()
88+
{
89+
var target = await CreateTargetAndInitialize(itemCount: 0);
90+
target.AuthorFilter.Selected = target.AuthorFilter.Users[0];
91+
92+
Assert.That(target.Message, Is.EqualTo(IssueListMessage.NoItemsMatchCriteria));
93+
}
94+
95+
protected static ILocalRepositoryModel CreateLocalRepository(
96+
string owner = "owner",
97+
string name = "name")
98+
{
99+
var result = Substitute.For<ILocalRepositoryModel>();
100+
result.CloneUrl.Returns(new UriString($"https://giuthub.com/{owner}/{name}"));
101+
result.Owner.Returns(owner);
102+
result.Name.Returns(name);
103+
return result;
104+
}
105+
106+
protected static IPullRequestSessionManager CreateSessionManager(PullRequestDetailModel pullRequest = null)
107+
{
108+
pullRequest = pullRequest ?? new PullRequestDetailModel();
109+
110+
var session = Substitute.For<IPullRequestSession>();
111+
session.PullRequest.Returns(pullRequest);
112+
113+
var result = Substitute.For<IPullRequestSessionManager>();
114+
result.CurrentSession.Returns(session);
115+
return result;
116+
}
117+
118+
protected static IPullRequestService CreatePullRequestService(int itemCount = 10)
119+
{
120+
var result = Substitute.For<IPullRequestService>();
121+
result.ReadPullRequests(null, null, null, null, null).ReturnsForAnyArgs(
122+
new Page<PullRequestListItemModel>
123+
{
124+
Items = Enumerable.Range(0, itemCount).Select(x => new PullRequestListItemModel
125+
{
126+
Id = "pr" + x,
127+
Number = x + 1,
128+
}).ToList()
129+
});
130+
return result;
131+
}
132+
133+
protected static IRepositoryService CreateRepositoryService(string parentOwnerLogin = null)
134+
{
135+
var result = Substitute.For<IRepositoryService>();
136+
result.ReadParentOwnerLogin(null, null, null).ReturnsForAnyArgs(parentOwnerLogin);
137+
return result;
138+
}
139+
140+
static Target CreateTarget(IRepositoryService repositoryService = null, int itemCount = 1000)
141+
{
142+
repositoryService = repositoryService ?? CreateRepositoryService();
143+
return new Target(repositoryService, itemCount);
144+
}
145+
146+
static async Task<Target> CreateTargetAndInitialize(
147+
IRepositoryService repositoryService = null,
148+
ILocalRepositoryModel repository = null,
149+
IConnection connection = null,
150+
int itemCount = 1000)
151+
{
152+
repository = repository ?? CreateLocalRepository();
153+
connection = connection ?? Substitute.For<IConnection>();
154+
155+
var target = CreateTarget(repositoryService, itemCount);
156+
await target.InitializeAsync(repository, connection);
157+
return target;
158+
}
159+
160+
class Target : IssueListViewModelBase
161+
{
162+
public Target(IRepositoryService repositoryService, int itemCount)
163+
: base(repositoryService)
164+
{
165+
ItemSource = Substitute.For<IVirtualizingListSource<IIssueListItemViewModelBase>>();
166+
ItemSource.GetCount().Returns(itemCount);
167+
ItemSource.PageSize.Returns(100);
168+
}
169+
170+
public IVirtualizingListSource<IIssueListItemViewModelBase> ItemSource { get; }
171+
172+
public override IReadOnlyList<string> States { get; } = new[] { "Open", "Closed" };
173+
174+
protected override IVirtualizingListSource<IIssueListItemViewModelBase> CreateItemSource() => ItemSource;
175+
176+
protected override Task DoOpenItem(IIssueListItemViewModelBase item)
177+
{
178+
throw new NotImplementedException();
179+
}
180+
181+
protected override Task<Page<ActorModel>> LoadAuthors(string after)
182+
{
183+
return Task.FromResult(new Page<ActorModel>
184+
{
185+
Items = new[]
186+
{
187+
new ActorModel { Login = "grokys" },
188+
new ActorModel { Login = "jcansdale" },
189+
},
190+
});
191+
}
192+
}
193+
}
194+
}

0 commit comments

Comments
 (0)