PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Octokit.Tests/Http/ApiConnectionTests.cs

https://gitlab.com/WoomyNightClub/GitHub-API-.NET
C# | 437 lines | 356 code | 73 blank | 8 comment | 0 complexity | 2c2f3d750504d27b5e26df854f9582ec MD5 | raw file
  1. using System;
  2. using System.Net;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using NSubstitute;
  8. using Octokit.Internal;
  9. using Xunit;
  10. namespace Octokit.Tests.Http
  11. {
  12. public class ApiConnectionTests
  13. {
  14. public class TheGetMethod
  15. {
  16. [Fact]
  17. public async Task MakesGetRequestForItem()
  18. {
  19. var getUri = new Uri("anything", UriKind.Relative);
  20. IApiResponse<object> response = new ApiResponse<object>(new Response());
  21. var connection = Substitute.For<IConnection>();
  22. connection.Get<object>(Args.Uri, null, null).Returns(Task.FromResult(response));
  23. var apiConnection = new ApiConnection(connection);
  24. var data = await apiConnection.Get<object>(getUri);
  25. Assert.Same(response.Body, data);
  26. connection.Received().GetResponse<object>(getUri);
  27. }
  28. [Fact]
  29. public async Task MakesGetRequestForItemWithAcceptsOverride()
  30. {
  31. var getUri = new Uri("anything", UriKind.Relative);
  32. const string accepts = "custom/accepts";
  33. IApiResponse<object> response = new ApiResponse<object>(new Response());
  34. var connection = Substitute.For<IConnection>();
  35. connection.Get<object>(Args.Uri, null, Args.String).Returns(Task.FromResult(response));
  36. var apiConnection = new ApiConnection(connection);
  37. var data = await apiConnection.Get<object>(getUri, null, accepts);
  38. Assert.Same(response.Body, data);
  39. connection.Received().Get<object>(getUri, null, accepts);
  40. }
  41. [Fact]
  42. public async Task EnsuresArgumentNotNull()
  43. {
  44. var getUri = new Uri("anything", UriKind.Relative);
  45. var client = new ApiConnection(Substitute.For<IConnection>());
  46. await Assert.ThrowsAsync<ArgumentNullException>(() => client.Get<object>(null));
  47. await Assert.ThrowsAsync<ArgumentNullException>(() => client.Get<object>(getUri, new Dictionary<string, string>(), null));
  48. }
  49. }
  50. public class TheGetHtmlMethod
  51. {
  52. [Fact]
  53. public async Task MakesHtmlRequest()
  54. {
  55. var getUri = new Uri("anything", UriKind.Relative);
  56. IApiResponse<string> response = new ApiResponse<string>(new Response(), "<html />");
  57. var connection = Substitute.For<IConnection>();
  58. connection.GetHtml(Args.Uri, null).Returns(Task.FromResult(response));
  59. var apiConnection = new ApiConnection(connection);
  60. var data = await apiConnection.GetHtml(getUri);
  61. Assert.Equal("<html />", data);
  62. connection.Received().GetHtml(getUri);
  63. }
  64. [Fact]
  65. public async Task EnsuresArgumentNotNull()
  66. {
  67. var client = new ApiConnection(Substitute.For<IConnection>());
  68. await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetHtml(null));
  69. }
  70. }
  71. public class TheGetAllMethod
  72. {
  73. [Fact]
  74. public async Task MakesGetRequestForAllItems()
  75. {
  76. var getAllUri = new Uri("anything", UriKind.Relative);
  77. IApiResponse<List<object>> response = new ApiResponse<List<object>>(
  78. new Response(),
  79. new List<object> { new object(), new object() });
  80. var connection = Substitute.For<IConnection>();
  81. connection.Get<List<object>>(Args.Uri, Args.EmptyDictionary, null).Returns(Task.FromResult(response));
  82. var apiConnection = new ApiConnection(connection);
  83. var data = await apiConnection.GetAll<object>(getAllUri);
  84. Assert.Equal(2, data.Count);
  85. connection.Received().Get<List<object>>(getAllUri, Args.EmptyDictionary, null);
  86. }
  87. [Fact]
  88. public async Task EnsuresArgumentNotNull()
  89. {
  90. var client = new ApiConnection(Substitute.For<IConnection>());
  91. // One argument
  92. await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll<object>(null));
  93. // Two argument
  94. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  95. await client.GetAll<object>(null, new Dictionary<string, string>()));
  96. // Three arguments
  97. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  98. await client.GetAll<object>(null, new Dictionary<string, string>(), "accepts"));
  99. }
  100. }
  101. public class ThePatchMethod
  102. {
  103. [Fact]
  104. public async Task MakesPatchRequestWithSuppliedData()
  105. {
  106. var patchUri = new Uri("anything", UriKind.Relative);
  107. var sentData = new object();
  108. IApiResponse<object> response = new ApiResponse<object>(new Response(), new object());
  109. var connection = Substitute.For<IConnection>();
  110. connection.Patch<object>(Args.Uri, Args.Object).Returns(Task.FromResult(response));
  111. var apiConnection = new ApiConnection(connection);
  112. var data = await apiConnection.Patch<object>(patchUri, sentData);
  113. Assert.Same(data, response.Body);
  114. connection.Received().Patch<object>(patchUri, sentData);
  115. }
  116. [Fact]
  117. public async Task MakesPatchRequestWithAcceptsOverride()
  118. {
  119. var patchUri = new Uri("anything", UriKind.Relative);
  120. var sentData = new object();
  121. var accepts = "custom/accepts";
  122. IApiResponse<object> response = new ApiResponse<object>(new Response());
  123. var connection = Substitute.For<IConnection>();
  124. connection.Patch<object>(Args.Uri, Args.Object, Args.String).Returns(Task.FromResult(response));
  125. var apiConnection = new ApiConnection(connection);
  126. var data = await apiConnection.Patch<object>(patchUri, sentData, accepts);
  127. Assert.Same(data, response.Body);
  128. connection.Received().Patch<object>(patchUri, sentData, accepts);
  129. }
  130. [Fact]
  131. public async Task EnsuresArgumentNotNull()
  132. {
  133. var connection = new ApiConnection(Substitute.For<IConnection>());
  134. var patchUri = new Uri("", UriKind.Relative);
  135. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Patch<object>(null, new object()));
  136. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Patch<object>(patchUri, null));
  137. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Patch<object>(patchUri, new object(), null));
  138. }
  139. }
  140. public class ThePostMethod
  141. {
  142. [Fact]
  143. public async Task MakesPostRequestWithoutData()
  144. {
  145. var postUri = new Uri("anything", UriKind.Relative);
  146. var statusCode = HttpStatusCode.Accepted;
  147. var connection = Substitute.For<IConnection>();
  148. connection.Post(Args.Uri).Returns(Task.FromResult(statusCode));
  149. var apiConnection = new ApiConnection(connection);
  150. await apiConnection.Post(postUri);
  151. connection.Received().Post(postUri);
  152. }
  153. [Fact]
  154. public async Task MakesPostRequestWithSuppliedData()
  155. {
  156. var postUri = new Uri("anything", UriKind.Relative);
  157. var sentData = new object();
  158. IApiResponse<object> response = new ApiResponse<object>(new Response(), new object());
  159. var connection = Substitute.For<IConnection>();
  160. connection.Post<object>(Args.Uri, Args.Object, null, null).Returns(Task.FromResult(response));
  161. var apiConnection = new ApiConnection(connection);
  162. var data = await apiConnection.Post<object>(postUri, sentData);
  163. Assert.Same(data, response.Body);
  164. connection.Received().Post<object>(postUri, sentData, null, null);
  165. }
  166. [Fact]
  167. public async Task MakesUploadRequest()
  168. {
  169. var uploadUrl = new Uri("anything", UriKind.Relative);
  170. IApiResponse<string> response = new ApiResponse<string>(new Response(), "the response");
  171. var connection = Substitute.For<IConnection>();
  172. connection.Post<string>(Args.Uri, Arg.Any<Stream>(), Args.String, Args.String)
  173. .Returns(Task.FromResult(response));
  174. var apiConnection = new ApiConnection(connection);
  175. var rawData = new MemoryStream();
  176. await apiConnection.Post<string>(uploadUrl, rawData, "accepts", "content-type");
  177. connection.Received().Post<string>(uploadUrl, rawData, "accepts", "content-type");
  178. }
  179. [Fact]
  180. public async Task EnsuresArgumentsNotNull()
  181. {
  182. var postUri = new Uri("", UriKind.Relative);
  183. var connection = new ApiConnection(Substitute.For<IConnection>());
  184. // 1 parameter overload
  185. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Post(null));
  186. // 2 parameter overload
  187. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Post<object>(null, new object()));
  188. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Post<object>(postUri, null));
  189. // 3 parameters
  190. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Post<object>(null, new MemoryStream(), "anAccept", "some-content-type"));
  191. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Post<object>(postUri, null, "anAccept", "some-content-type"));
  192. }
  193. }
  194. public class ThePutMethod
  195. {
  196. [Fact]
  197. public async Task MakesPutRequestWithSuppliedData()
  198. {
  199. var putUri = new Uri("anything", UriKind.Relative);
  200. var sentData = new object();
  201. IApiResponse<object> response = new ApiResponse<object>(new Response());
  202. var connection = Substitute.For<IConnection>();
  203. connection.Put<object>(Args.Uri, Args.Object).Returns(Task.FromResult(response));
  204. var apiConnection = new ApiConnection(connection);
  205. var data = await apiConnection.Put<object>(putUri, sentData);
  206. Assert.Same(data, response.Body);
  207. connection.Received().Put<object>(putUri, sentData);
  208. }
  209. [Fact]
  210. public async Task MakesPutRequestWithSuppliedDataAndTwoFactorCode()
  211. {
  212. var putUri = new Uri("anything", UriKind.Relative);
  213. var sentData = new object();
  214. IApiResponse<object> response = new ApiResponse<object>(new Response());
  215. var connection = Substitute.For<IConnection>();
  216. connection.Put<object>(Args.Uri, Args.Object, "two-factor").Returns(Task.FromResult(response));
  217. var apiConnection = new ApiConnection(connection);
  218. var data = await apiConnection.Put<object>(putUri, sentData, "two-factor");
  219. Assert.Same(data, response.Body);
  220. connection.Received().Put<object>(putUri, sentData, "two-factor");
  221. }
  222. [Fact]
  223. public async Task EnsuresArgumentsNotNull()
  224. {
  225. var putUri = new Uri("", UriKind.Relative);
  226. var connection = new ApiConnection(Substitute.For<IConnection>());
  227. // 2 parameter overload
  228. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  229. await connection.Put<object>(null, new object()));
  230. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  231. await connection.Put<object>(putUri, null));
  232. // 3 parameters
  233. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  234. await connection.Put<object>(null, new MemoryStream(), "two-factor"));
  235. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  236. await connection.Put<object>(putUri, null, "two-factor"));
  237. await Assert.ThrowsAsync<ArgumentNullException>(async () =>
  238. await connection.Put<object>(putUri, new MemoryStream(), null));
  239. await Assert.ThrowsAsync<ArgumentException>(async () =>
  240. await connection.Put<object>(putUri, new MemoryStream(), ""));
  241. }
  242. }
  243. public class TheDeleteMethod
  244. {
  245. [Fact]
  246. public async Task MakesDeleteRequest()
  247. {
  248. var deleteUri = new Uri("anything", UriKind.Relative);
  249. HttpStatusCode statusCode = HttpStatusCode.NoContent;
  250. var connection = Substitute.For<IConnection>();
  251. connection.Delete(Args.Uri).Returns(Task.FromResult(statusCode));
  252. var apiConnection = new ApiConnection(connection);
  253. await apiConnection.Delete(deleteUri);
  254. connection.Received().Delete(deleteUri);
  255. }
  256. [Fact]
  257. public async Task EnsuresArgumentNotNull()
  258. {
  259. var connection = new ApiConnection(Substitute.For<IConnection>());
  260. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.Delete(null));
  261. }
  262. }
  263. public class TheGetQueuedOperationMethod
  264. {
  265. [Fact]
  266. public async Task WhenGetReturnsNotOkOrAcceptedApiExceptionIsThrown()
  267. {
  268. var queuedOperationUrl = new Uri("anything", UriKind.Relative);
  269. const HttpStatusCode statusCode = HttpStatusCode.PartialContent;
  270. IApiResponse<object> response = new ApiResponse<object>(new Response(statusCode, null, new Dictionary<string, string>(), "application/json"), new object());
  271. var connection = Substitute.For<IConnection>();
  272. connection.GetResponse<object>(queuedOperationUrl, Args.CancellationToken).Returns(Task.FromResult(response));
  273. var apiConnection = new ApiConnection(connection);
  274. await Assert.ThrowsAsync<ApiException>(() => apiConnection.GetQueuedOperation<object>(queuedOperationUrl, Args.CancellationToken));
  275. }
  276. [Fact]
  277. public async Task WhenGetReturnsOkThenBodyAsObjectIsReturned()
  278. {
  279. var queuedOperationUrl = new Uri("anything", UriKind.Relative);
  280. var result = new[] { new object() };
  281. const HttpStatusCode statusCode = HttpStatusCode.OK;
  282. var httpResponse = new Response(statusCode, null, new Dictionary<string, string>(), "application/json");
  283. IApiResponse<IReadOnlyList<object>> response = new ApiResponse<IReadOnlyList<object>>(httpResponse, result);
  284. var connection = Substitute.For<IConnection>();
  285. connection.GetResponse<IReadOnlyList<object>>(queuedOperationUrl, Args.CancellationToken)
  286. .Returns(Task.FromResult(response));
  287. var apiConnection = new ApiConnection(connection);
  288. var actualResult = await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, Args.CancellationToken);
  289. Assert.Same(actualResult, result);
  290. }
  291. [Fact]
  292. public async Task WhenGetReturnsNoContentThenReturnsEmptyCollection()
  293. {
  294. var queuedOperationUrl = new Uri("anything", UriKind.Relative);
  295. var result = new[] { new object() };
  296. const HttpStatusCode statusCode = HttpStatusCode.NoContent;
  297. var httpResponse = new Response(statusCode, null, new Dictionary<string, string>(), "application/json");
  298. IApiResponse<IReadOnlyList<object>> response = new ApiResponse<IReadOnlyList<object>>(
  299. httpResponse, result);
  300. var connection = Substitute.For<IConnection>();
  301. connection.GetResponse<IReadOnlyList<object>>(queuedOperationUrl, Args.CancellationToken)
  302. .Returns(Task.FromResult(response));
  303. var apiConnection = new ApiConnection(connection);
  304. var actualResult = await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, Args.CancellationToken);
  305. Assert.Empty(actualResult);
  306. }
  307. [Fact]
  308. public async Task GetIsRepeatedUntilHttpStatusCodeOkIsReturned()
  309. {
  310. var queuedOperationUrl = new Uri("anything", UriKind.Relative);
  311. var result = new[] { new object() };
  312. IApiResponse<IReadOnlyList<object>> firstResponse = new ApiResponse<IReadOnlyList<object>>(
  313. new Response(HttpStatusCode.Accepted, null, new Dictionary<string, string>(), "application/json"), result);
  314. IApiResponse<IReadOnlyList<object>> completedResponse = new ApiResponse<IReadOnlyList<object>>(
  315. new Response(HttpStatusCode.OK, null, new Dictionary<string, string>(), "application/json"), result);
  316. var connection = Substitute.For<IConnection>();
  317. connection.GetResponse<IReadOnlyList<object>>(queuedOperationUrl, Args.CancellationToken)
  318. .Returns(x => Task.FromResult(firstResponse),
  319. x => Task.FromResult(firstResponse),
  320. x => Task.FromResult(completedResponse));
  321. var apiConnection = new ApiConnection(connection);
  322. await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, CancellationToken.None);
  323. connection.Received(3).GetResponse<IReadOnlyList<object>>(queuedOperationUrl, Args.CancellationToken);
  324. }
  325. public async Task CanCancelQueuedOperation()
  326. {
  327. var queuedOperationUrl = new Uri("anything", UriKind.Relative);
  328. var result = new[] { new object() };
  329. IApiResponse<IReadOnlyList<object>> accepted = new ApiResponse<IReadOnlyList<object>>(
  330. new Response(HttpStatusCode.Accepted, null, new Dictionary<string, string>(), "application/json"), result);
  331. var connection = Substitute.For<IConnection>();
  332. connection.GetResponse<IReadOnlyList<object>>(queuedOperationUrl, Args.CancellationToken)
  333. .Returns(x => Task.FromResult(accepted));
  334. var apiConnection = new ApiConnection(connection);
  335. var cancellationTokenSource = new CancellationTokenSource();
  336. cancellationTokenSource.CancelAfter(100);
  337. var canceled = false;
  338. var operationResult = await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, cancellationTokenSource.Token)
  339. .ContinueWith(task =>
  340. {
  341. canceled = task.IsCanceled;
  342. return task;
  343. }, TaskContinuationOptions.OnlyOnCanceled)
  344. .ContinueWith(task => task, TaskContinuationOptions.OnlyOnFaulted);
  345. Assert.True(canceled);
  346. Assert.Null(operationResult);
  347. }
  348. [Fact]
  349. public async Task EnsuresArgumentNotNull()
  350. {
  351. var connection = new ApiConnection(Substitute.For<IConnection>());
  352. await Assert.ThrowsAsync<ArgumentNullException>(() => connection.GetQueuedOperation<object>(null, CancellationToken.None));
  353. }
  354. }
  355. public class TheCtor
  356. {
  357. [Fact]
  358. public void EnsuresNonNullArguments()
  359. {
  360. Assert.Throws<ArgumentNullException>(() => new ApiConnection(null));
  361. }
  362. }
  363. }
  364. }