SmartOpsImprovementActionTests.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using Admin.NET.Plugin.AiDOP.Entity;
  2. using Admin.NET.Plugin.AiDOP.SmartOps;
  3. using Xunit;
  4. namespace Admin.NET.Plugin.AiDOP.Tests.SmartOps;
  5. public class SmartOpsImprovementActionTests
  6. {
  7. [Theory]
  8. [InlineData("doing", "in_progress")]
  9. [InlineData("in_progress", "in_progress")]
  10. [InlineData("done", "completed")]
  11. [InlineData("cancelled", "cancelled")]
  12. [InlineData("pending", "pending")]
  13. public void Status_NormalizesLegacyValues(string raw, string expected)
  14. {
  15. Assert.Equal(expected, SmartOpsImprovementActionStatus.Normalize(raw));
  16. }
  17. [Theory]
  18. [InlineData("pending", "in_progress", true)]
  19. [InlineData("pending", "cancelled", true)]
  20. [InlineData("in_progress", "completed", true)]
  21. [InlineData("completed", "pending", false)]
  22. [InlineData("cancelled", "completed", false)]
  23. [InlineData("cancelled", "pending", true)]
  24. public void Status_TransitionsAreGuarded(string from, string to, bool allowed)
  25. {
  26. Assert.Equal(allowed, SmartOpsImprovementActionStatus.CanTransition(from, to));
  27. }
  28. [Fact]
  29. public void Overdue_OnlyAppliesToOpenActions()
  30. {
  31. var yesterday = DateTime.Today.AddDays(-1);
  32. Assert.True(SmartOpsImprovementActionStatus.IsOverdue("pending", yesterday, DateTime.Today));
  33. Assert.False(SmartOpsImprovementActionStatus.IsOverdue("completed", yesterday, DateTime.Today));
  34. Assert.Equal("overdue", SmartOpsImprovementActionStatus.DisplayStatus("doing", yesterday, DateTime.Today));
  35. }
  36. [Fact]
  37. public void NoticeKey_IsIdempotentPerDayAndType()
  38. {
  39. var key1 = SmartOpsImprovementNoticeType.NoticeKey(1, 9, SmartOpsImprovementNoticeType.Overdue, new DateTime(2026, 8, 17));
  40. var key2 = SmartOpsImprovementNoticeType.NoticeKey(1, 9, SmartOpsImprovementNoticeType.Overdue, new DateTime(2026, 8, 17));
  41. var key3 = SmartOpsImprovementNoticeType.NoticeKey(1, 9, SmartOpsImprovementNoticeType.DueSoon, new DateTime(2026, 8, 17));
  42. Assert.Equal(key1, key2);
  43. Assert.NotEqual(key1, key3);
  44. }
  45. [Fact]
  46. public void LegacyJson_ParsesCamelAndPascal()
  47. {
  48. var camel = SmartOpsImprovementActionService.ParseDrafts(
  49. """[{"content":"核对缺料","owner":"1001","dueDate":"2026-08-18","status":"doing"}]""");
  50. var pascal = SmartOpsImprovementActionService.ParseDrafts(
  51. """[{"Content":"核对缺料","Owner":"计划员","DueDate":"2026-08-18","Status":"pending"}]""");
  52. Assert.Single(camel);
  53. Assert.Equal("核对缺料", camel[0].Content);
  54. Assert.Equal("doing", camel[0].Status);
  55. Assert.Single(pascal);
  56. Assert.Equal("计划员", pascal[0].Owner);
  57. }
  58. [Fact]
  59. public void Controller_NoLongerWritesActionJsonAsSourceOfTruth()
  60. {
  61. var source = File.ReadAllText(FindController());
  62. Assert.Contains("_actions.MutateAsync", source);
  63. Assert.Contains("_actions.ReplaceFromDraftAsync", source);
  64. Assert.DoesNotContain("ActionItemsJson = actionItemsJson", source);
  65. }
  66. private static string FindController()
  67. {
  68. var dir = new DirectoryInfo(AppContext.BaseDirectory);
  69. while (dir != null)
  70. {
  71. var candidate = Path.Combine(dir.FullName,
  72. "server", "Plugins", "Admin.NET.Plugin.AiDOP", "Controllers",
  73. "AdoSmartOpsImprovementPlanController.cs");
  74. if (File.Exists(candidate)) return candidate;
  75. dir = dir.Parent;
  76. }
  77. throw new FileNotFoundException("AdoSmartOpsImprovementPlanController.cs");
  78. }
  79. }