Skip to content

Commit 2f1ce40

Browse files
committed
Expanded list of users api call
When calling /users, we want to be able to provide detailed information. Therefore it's important that we can return the data dynamically, but also provide a way to get typed access to that data should it be required.
1 parent 6ab92f0 commit 2f1ce40

4 files changed

Lines changed: 164 additions & 11 deletions

File tree

csharp-github-api.IntegrationTests/UsersTest.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Configuration;
23
using FluentAssertions;
34
using LoggingExtensions.log4net;
@@ -86,6 +87,39 @@ public void then_response_data_with_model_should_contain_private_data()
8687
}
8788
}
8889

90+
public class when_getting_the_list_of_users : UsersTestsBase
91+
{
92+
public override void Because()
93+
{
94+
User = Username;
95+
}
96+
97+
public override void Context()
98+
{
99+
base.Context();
100+
Github = Github.WithAuthentication(Authenticator());
101+
}
102+
103+
[Fact]
104+
public void then_a_typed_list_should_be_able_to_be_returned()
105+
{
106+
var users = Github.GetUsers<List<Users>>();
107+
108+
users.Data.Should().BeOfType<List<Users>>();
109+
users.Data.Count.Should().BeGreaterThan(0);
110+
}
111+
112+
[Fact]
113+
public void then_dynamic_json_array_is_accessible()
114+
{
115+
var users = Github.GetUsers();
116+
117+
string url = users.Dynamic()[0].avatar_url;
118+
119+
url.Should().NotBeNullOrEmpty();
120+
}
121+
}
122+
89123
public class when_updating_a_user : UsersTestsBase
90124
{
91125
public override void Because()

csharp-github-api.Models/Users.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="Users.cs" company="TemporalCohesion.co.uk">
3+
// Copyright 2012 - Present Stuart Grassie
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
// </copyright>
17+
//----------------------------------------------------------------------
18+
19+
namespace csharp_github_api.Models
20+
{
21+
public class Users
22+
{
23+
public string AvatarUrl { get; set; }
24+
public string EventsUrl { get; set; }
25+
public string FollowersUrl { get; set; }
26+
public string FollowingUrl { get; set; }
27+
public string GistsUrl { get; set; }
28+
public string GravatarId { get; set; }
29+
public string Id { get; set; }
30+
public string Login { get; set; }
31+
public string OrganizationsUrl { get; set; }
32+
public string RecievedEventsUrl { get; set; }
33+
public string ReposUrl { get; set; }
34+
public string StarredUrl { get; set; }
35+
public string SubscriptionsUrl { get; set; }
36+
public string Type { get; set; }
37+
public string Url { get; set; }
38+
39+
/// <summary>
40+
/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
41+
/// </summary>
42+
/// <returns>
43+
/// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
44+
/// </returns>
45+
/// <param name="obj">The object to compare with the current object. </param><filterpriority>2</filterpriority>
46+
public override bool Equals(object obj)
47+
{
48+
if (ReferenceEquals(null, obj)) return false;
49+
if (ReferenceEquals(this, obj)) return true;
50+
if (obj.GetType() != this.GetType()) return false;
51+
return Equals((Users) obj);
52+
}
53+
54+
protected bool Equals(Users other)
55+
{
56+
return string.Equals(Id, other.Id) && string.Equals(Login, other.Login) && string.Equals(Url, other.Url);
57+
}
58+
59+
/// <summary>
60+
/// Serves as a hash function for a particular type.
61+
/// </summary>
62+
/// <returns>
63+
/// A hash code for the current <see cref="T:System.Object"/>.
64+
/// </returns>
65+
/// <filterpriority>2</filterpriority>
66+
public override int GetHashCode()
67+
{
68+
unchecked
69+
{
70+
int hashCode = Id.GetHashCode();
71+
hashCode = (hashCode * 397) ^ Login.GetHashCode();
72+
hashCode = (hashCode * 397) ^ Url.GetHashCode();
73+
return hashCode;
74+
}
75+
}
76+
77+
public static bool operator ==(Users left, Users right)
78+
{
79+
return Equals(left, right);
80+
}
81+
82+
public static bool operator !=(Users left, Users right)
83+
{
84+
return !Equals(left, right);
85+
}
86+
87+
/// <summary>
88+
/// Returns a string that represents the current object.
89+
/// </summary>
90+
/// <returns>
91+
/// A string that represents the current object.
92+
/// </returns>
93+
/// <filterpriority>2</filterpriority>
94+
public override string ToString()
95+
{
96+
return Login;
97+
}
98+
}
99+
}

csharp-github-api.Models/csharp-github-api.Models.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<Compile Include="Properties\AssemblyInfo.cs" />
4747
<Compile Include="UpdateableUser.cs" />
4848
<Compile Include="User.cs" />
49+
<Compile Include="Users.cs" />
4950
</ItemGroup>
5051
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
5152
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

csharp-github-api/Users.cs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ public partial class GithubRestApiClient
3838
private readonly Func<string, IRestRequest> _user = username => _restRequestFactory.CreateRequest(
3939
"/users/{username}", Method.GET, new[]{ new KeyValuePair<string, string>("username", username)});
4040

41+
private readonly Func<string, IRestRequest> _listUsers = (since) => _restRequestFactory.CreateRequest(
42+
() =>
43+
{
44+
var req = new RestRequest("/users?since={id}")
45+
{
46+
Method = Method.GET
47+
};
48+
req.AddUrlSegment("id", Convert.ToString(since,CultureInfo.InvariantCulture));
49+
return req;
50+
});
51+
4152
/// <summary>
4253
/// Get the authenticated user
4354
/// </summary>
@@ -110,24 +121,32 @@ public IRestResponse GetUser(string username)
110121
/// </remarks>
111122
/// <param name="id">The integer ID of the last User that you’ve seen.</param>
112123
/// <returns>A <see cref="IRestResponse"/> containing a chunk of users.</returns>
113-
public IRestResponse GetUsers(int id = 0)
124+
public IRestResponse GetUsers(string id = "")
114125
{
115-
var request = _restRequestFactory.CreateRequest(
116-
() =>
117-
{
118-
var req = new RestRequest("/users?since={id}")
119-
{
120-
Method = Method.GET
121-
};
122-
req.AddUrlSegment("id", Convert.ToString(id, CultureInfo.InvariantCulture));
123-
return req;
124-
});
126+
var request = _listUsers.Invoke(id);
125127
var response = _innerRestClient.Execute(request);
126128

127129
CheckRateLimit(response.Headers);
128130
return response;
129131
}
130132

133+
/// <summary>
134+
/// Get all users
135+
/// </summary>
136+
/// <remarks>
137+
/// This provides a dump of every user, in the order that they signed up for GitHub.
138+
/// </remarks>
139+
/// <param name="id">The integer ID of the last User that you’ve seen.</param>
140+
/// <returns>A <see cref="IRestResponse"/> containing a chunk of users.</returns>
141+
public IRestResponse<T> GetUsers<T>(string id = "") where T : new()
142+
{
143+
var request = _listUsers.Invoke(id);
144+
var response = _innerRestClient.Execute<T>(request);
145+
146+
CheckRateLimit(response.Headers);
147+
return response;
148+
}
149+
131150
public IRestResponse<TUser> UpdateUser<TUser>(
132151
string name = "", string email = "", string blog = null, string company = "", string location = "",
133152
string hireable = "", string bio = "") where TUser : new()

0 commit comments

Comments
 (0)