ControllerModelTest.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6. using Microsoft.AspNetCore.Mvc.ActionConstraints;
  7. using Microsoft.AspNetCore.Mvc.Filters;
  8. using Microsoft.AspNetCore.Mvc.Routing;
  9. using Xunit;
  10. namespace Microsoft.AspNetCore.Mvc.ApplicationModels
  11. {
  12. public class ControllerModelTest
  13. {
  14. [Fact]
  15. public void CopyConstructor_DoesDeepCopyOfOtherModels()
  16. {
  17. // Arrange
  18. var controller = new ControllerModel(typeof(TestController).GetTypeInfo(),
  19. new List<object>());
  20. var action = new ActionModel(typeof(TestController).GetMethod("Edit"),
  21. new List<object>());
  22. controller.Actions.Add(action);
  23. action.Controller = controller;
  24. controller.ControllerProperties.Add(new PropertyModel(
  25. controller.ControllerType.AsType().GetProperty("TestProperty"),
  26. new List<object>() { }));
  27. var route = new AttributeRouteModel(new HttpGetAttribute("api/Products"));
  28. controller.Selectors.Add(new SelectorModel() { AttributeRouteModel = route });
  29. var apiExplorer = controller.ApiExplorer;
  30. controller.ApiExplorer.GroupName = "group";
  31. controller.ApiExplorer.IsVisible = true;
  32. // Act
  33. var controller2 = new ControllerModel(controller);
  34. // Assert
  35. Assert.NotSame(action, controller2.Actions[0]);
  36. Assert.NotNull(controller2.ControllerProperties);
  37. Assert.Single(controller2.ControllerProperties);
  38. Assert.NotNull(controller2.Selectors);
  39. Assert.Single(controller2.Selectors);
  40. Assert.NotSame(route, controller2.Selectors[0].AttributeRouteModel);
  41. Assert.NotSame(apiExplorer, controller2.ApiExplorer);
  42. Assert.NotSame(controller.Selectors[0].ActionConstraints, controller2.Selectors[0].ActionConstraints);
  43. Assert.NotSame(controller.Actions, controller2.Actions);
  44. Assert.NotSame(controller.Attributes, controller2.Attributes);
  45. Assert.NotSame(controller.Filters, controller2.Filters);
  46. Assert.NotSame(controller.RouteValues, controller2.RouteValues);
  47. Assert.NotSame(controller, controller2.Actions[0].Controller);
  48. Assert.Same(controller2, controller2.Actions[0].Controller);
  49. Assert.NotSame(controller, controller2.ControllerProperties[0].Controller);
  50. Assert.Same(controller2, controller2.ControllerProperties[0].Controller);
  51. }
  52. [Fact]
  53. public void CopyConstructor_CopiesAllProperties()
  54. {
  55. // Arrange
  56. var controller = new ControllerModel(
  57. typeof(TestController).GetTypeInfo(),
  58. new List<object>()
  59. {
  60. new HttpGetAttribute(),
  61. new MyFilterAttribute(),
  62. });
  63. var selectorModel = new SelectorModel();
  64. selectorModel.ActionConstraints.Add(new HttpMethodActionConstraint(new string[] { "GET" }));
  65. controller.Selectors.Add(selectorModel);
  66. controller.Application = new ApplicationModel();
  67. controller.ControllerName = "cool";
  68. controller.Filters.Add(new MyFilterAttribute());
  69. controller.RouteValues.Add("key", "value");
  70. controller.Properties.Add(new KeyValuePair<object, object>("test key", "test value"));
  71. controller.ControllerProperties.Add(
  72. new PropertyModel(typeof(TestController).GetProperty("TestProperty"), new List<object>()));
  73. // Act
  74. var controller2 = new ControllerModel(controller);
  75. // Assert
  76. foreach (var property in typeof(ControllerModel).GetProperties())
  77. {
  78. if (property.Name.Equals("Actions") ||
  79. property.Name.Equals("Selectors") ||
  80. property.Name.Equals("ApiExplorer") ||
  81. property.Name.Equals("ControllerProperties"))
  82. {
  83. // This test excludes other ApplicationModel objects on purpose because we deep copy them.
  84. continue;
  85. }
  86. var value1 = property.GetValue(controller);
  87. var value2 = property.GetValue(controller2);
  88. if (typeof(IEnumerable<object>).IsAssignableFrom(property.PropertyType))
  89. {
  90. Assert.Equal<object>((IEnumerable<object>)value1, (IEnumerable<object>)value2);
  91. // Ensure non-default value
  92. Assert.NotEmpty((IEnumerable<object>)value1);
  93. }
  94. else if (typeof(IDictionary<string, string>).IsAssignableFrom(property.PropertyType))
  95. {
  96. Assert.Equal(value1, value2);
  97. // Ensure non-default value
  98. Assert.NotEmpty((IDictionary<string, string>)value1);
  99. }
  100. else if (typeof(IDictionary<object, object>).IsAssignableFrom(property.PropertyType))
  101. {
  102. Assert.Equal(value1, value2);
  103. // Ensure non-default value
  104. Assert.NotEmpty((IDictionary<object, object>)value1);
  105. }
  106. else if (property.PropertyType.IsValueType ||
  107. Nullable.GetUnderlyingType(property.PropertyType) != null)
  108. {
  109. Assert.Equal(value1, value2);
  110. // Ensure non-default value
  111. Assert.NotEqual(value1, Activator.CreateInstance(property.PropertyType));
  112. }
  113. else if (property.Name.Equals(nameof(ControllerModel.DisplayName)))
  114. {
  115. // DisplayName is re-calculated, hence reference equality wouldn't work.
  116. Assert.Equal(value1, value2);
  117. }
  118. else
  119. {
  120. Assert.Same(value1, value2);
  121. // Ensure non-default value
  122. Assert.NotNull(value1);
  123. }
  124. }
  125. }
  126. private class TestController
  127. {
  128. public string TestProperty { get; set; }
  129. public void Edit()
  130. {
  131. }
  132. }
  133. private class MyFilterAttribute : Attribute, IFilterMetadata
  134. {
  135. }
  136. private class MyRouteValueAttribute : Attribute, IRouteValueProvider
  137. {
  138. public string RouteKey { get; set; }
  139. public string RouteValue { get; set; }
  140. }
  141. }
  142. }