ApiClientTests.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System.Net;
  2. using System.Text.Json;
  3. using Moq;
  4. using Moq.Protected;
  5. using XafPet.Desktop.PetEngine;
  6. using Xunit;
  7. namespace XafPet.Desktop.Tests;
  8. public class ApiClientTests
  9. {
  10. private static ApiClient CreateClientWithResponse(HttpStatusCode code, string json, string authToken = "test-token")
  11. {
  12. var handler = new Mock<HttpMessageHandler>();
  13. handler.Protected()
  14. .Setup<Task<HttpResponseMessage>>("SendAsync",
  15. ItExpr.IsAny<HttpRequestMessage>(),
  16. ItExpr.IsAny<CancellationToken>())
  17. .ReturnsAsync(new HttpResponseMessage(code)
  18. {
  19. Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json")
  20. });
  21. var http = new HttpClient(handler.Object);
  22. return new ApiClient(http, "http://localhost:9082", authToken);
  23. }
  24. [Fact]
  25. public async Task GetTodayTasks_ReturnsTaskList()
  26. {
  27. var json = """
  28. { "code": 200, "message": "ok", "data": [
  29. { "id": 1, "title": "喝水", "status": "PENDING", "dueDate": "2026-10-10" }
  30. ] }
  31. """;
  32. var client = CreateClientWithResponse(HttpStatusCode.OK, json);
  33. var tasks = await client.GetTodayTasksAsync();
  34. Assert.Single(tasks);
  35. Assert.Equal("喝水", tasks[0].Title);
  36. Assert.Equal("PENDING", tasks[0].Status);
  37. }
  38. [Fact]
  39. public async Task GetEnergyOverview_ReturnsDimensions()
  40. {
  41. var json = """
  42. { "code": 200, "message": "ok", "data": {
  43. "dimensions": [
  44. { "dimension": "身", "value": 80, "color": "#FF8C42" },
  45. { "dimension": "智", "value": 45, "color": "#6366F1" }
  46. ]
  47. } }
  48. """;
  49. var client = CreateClientWithResponse(HttpStatusCode.OK, json);
  50. var overview = await client.GetEnergyOverviewAsync();
  51. Assert.Equal(2, overview.Dimensions.Count);
  52. Assert.Equal(80, overview.Dimensions[0].Value);
  53. }
  54. [Fact]
  55. public async Task GetDailyCheckin_ReturnsStatus()
  56. {
  57. var json = """
  58. { "code": 200, "message": "ok", "data": { "checked": true, "items": ["water", "exercise"] } }
  59. """;
  60. var client = CreateClientWithResponse(HttpStatusCode.OK, json);
  61. var status = await client.GetDailyCheckinAsync();
  62. Assert.True(status.Checked);
  63. Assert.Contains("water", status.Items);
  64. }
  65. [Fact]
  66. public async Task CompleteDrinkWater_PostsCorrectEndpoint()
  67. {
  68. var json = """{ "code": 200, "message": "打卡成功", "data": null }""";
  69. var client = CreateClientWithResponse(HttpStatusCode.OK, json);
  70. var result = await client.CompleteDrinkWaterAsync();
  71. Assert.Equal("打卡成功", result.Message);
  72. }
  73. [Fact]
  74. public async Task NonSuccessCode_ThrowsApiException()
  75. {
  76. var json = """{ "code": 500, "message": "服务器错误", "data": null }""";
  77. var client = CreateClientWithResponse(HttpStatusCode.OK, json);
  78. await Assert.ThrowsAsync<ApiException>(() => client.GetTodayTasksAsync());
  79. }
  80. }