PageRenderTime 75ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/test/System.Web.Http.Test/Metadata/Providers/CachedDataAnnotationsModelMetadataProviderTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 576 lines | 372 code | 128 blank | 76 comment | 5 complexity | 3d59596ee76eb19ca5bb40867173fe10 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.ComponentModel;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Linq;
  5. using Microsoft.TestCommon;
  6. using Xunit;
  7. using Assert = Microsoft.TestCommon.AssertEx;
  8. namespace System.Web.Http.Metadata.Providers
  9. {
  10. public class CachedDataAnnotationsModelMetadataProviderTest : MarshalByRefObject
  11. {
  12. [Fact]
  13. public void GetMetadataForPropertiesSetTypesAndPropertyNames()
  14. {
  15. // Arrange
  16. var provider = new CachedDataAnnotationsModelMetadataProvider();
  17. // Act
  18. IEnumerable<ModelMetadata> result = provider.GetMetadataForProperties("foo", typeof(string));
  19. // Assert
  20. Assert.True(result.Any(m => m.ModelType == typeof(int)
  21. && m.PropertyName == "Length"
  22. && (int)m.Model == 3));
  23. }
  24. [Fact]
  25. public void GetMetadataForPropertySetsTypeAndPropertyName()
  26. {
  27. // Arrange
  28. var provider = new CachedDataAnnotationsModelMetadataProvider();
  29. // Act
  30. ModelMetadata result = provider.GetMetadataForProperty(null, typeof(string), "Length");
  31. // Assert
  32. Assert.Equal(typeof(int), result.ModelType);
  33. Assert.Equal("Length", result.PropertyName);
  34. }
  35. [Fact]
  36. public void GetMetadataForTypeSetsTypeWithNullPropertyName()
  37. {
  38. // Arrange
  39. var provider = new CachedDataAnnotationsModelMetadataProvider();
  40. // Act
  41. ModelMetadata result = provider.GetMetadataForType(null, typeof(string));
  42. // Assert
  43. Assert.Equal(typeof(string), result.ModelType);
  44. Assert.Null(result.PropertyName);
  45. }
  46. // [UIHint] tests
  47. class UIHintModel
  48. {
  49. public int NoAttribute { get; set; }
  50. [UIHint("MyCustomTemplate")]
  51. public int DefaultUIHint { get; set; }
  52. [UIHint("MyMvcTemplate", "MVC")]
  53. public int MvcUIHint { get; set; }
  54. [UIHint("MyWebFormsTemplate", "WebForms")]
  55. public int NoMvcUIHint { get; set; }
  56. [UIHint("MyDefaultTemplate")]
  57. [UIHint("MyWebFormsTemplate", "WebForms")]
  58. [UIHint("MyMvcTemplate", "MVC")]
  59. public int MultipleUIHint { get; set; }
  60. }
  61. [Fact]
  62. public void UIHintAttributeSetsTemplateHint()
  63. {
  64. // Arrange
  65. var provider = new CachedDataAnnotationsModelMetadataProvider();
  66. // Act & Assert
  67. Assert.Null(provider.GetMetadataForProperty(null, typeof(UIHintModel), "NoAttribute").TemplateHint);
  68. Assert.Equal("MyCustomTemplate", provider.GetMetadataForProperty(null, typeof(UIHintModel), "DefaultUIHint").TemplateHint);
  69. Assert.Equal("MyMvcTemplate", provider.GetMetadataForProperty(null, typeof(UIHintModel), "MvcUIHint").TemplateHint);
  70. Assert.Null(provider.GetMetadataForProperty(null, typeof(UIHintModel), "NoMvcUIHint").TemplateHint);
  71. Assert.Equal("MyMvcTemplate", provider.GetMetadataForProperty(null, typeof(UIHintModel), "MultipleUIHint").TemplateHint);
  72. }
  73. // [DataType] tests
  74. class DataTypeModel
  75. {
  76. public int NoAttribute { get; set; }
  77. [DataType(DataType.EmailAddress)]
  78. public int EmailAddressProperty { get; set; }
  79. [DataType("CustomDataType")]
  80. public int CustomDataTypeProperty { get; set; }
  81. }
  82. [Fact]
  83. public void DataTypeAttributeSetsDataTypeName()
  84. {
  85. // Arrange
  86. var provider = new CachedDataAnnotationsModelMetadataProvider();
  87. // Act & Assert
  88. Assert.Null(provider.GetMetadataForProperty(null, typeof(DataTypeModel), "NoAttribute").DataTypeName);
  89. Assert.Equal("EmailAddress", provider.GetMetadataForProperty(null, typeof(DataTypeModel), "EmailAddressProperty").DataTypeName);
  90. Assert.Equal("CustomDataType", provider.GetMetadataForProperty(null, typeof(DataTypeModel), "CustomDataTypeProperty").DataTypeName);
  91. }
  92. // [ReadOnly] & [Editable] tests
  93. class ReadOnlyModel
  94. {
  95. public int NoAttributes { get; set; }
  96. [ReadOnly(true)]
  97. public int ReadOnlyAttribute { get; set; }
  98. [Editable(false)]
  99. public int EditableAttribute { get; set; }
  100. [ReadOnly(true)]
  101. [Editable(true)]
  102. public int BothAttributes { get; set; }
  103. // Editable trumps ReadOnly
  104. }
  105. [Fact]
  106. public void ReadOnlyTests()
  107. {
  108. // Arrange
  109. var provider = new CachedDataAnnotationsModelMetadataProvider();
  110. // Act & Assert
  111. Assert.False(provider.GetMetadataForProperty(null, typeof(ReadOnlyModel), "NoAttributes").IsReadOnly);
  112. Assert.True(provider.GetMetadataForProperty(null, typeof(ReadOnlyModel), "ReadOnlyAttribute").IsReadOnly);
  113. Assert.True(provider.GetMetadataForProperty(null, typeof(ReadOnlyModel), "EditableAttribute").IsReadOnly);
  114. Assert.False(provider.GetMetadataForProperty(null, typeof(ReadOnlyModel), "BothAttributes").IsReadOnly);
  115. }
  116. // [DisplayFormat] tests
  117. class DisplayFormatModel
  118. {
  119. public int NoAttribute { get; set; }
  120. [DisplayFormat(NullDisplayText = "(null value)")]
  121. public int NullDisplayText { get; set; }
  122. [DisplayFormat(DataFormatString = "Data {0} format")]
  123. public int DisplayFormatString { get; set; }
  124. [DisplayFormat(DataFormatString = "Data {0} format", ApplyFormatInEditMode = true)]
  125. public int DisplayAndEditFormatString { get; set; }
  126. [DisplayFormat(ConvertEmptyStringToNull = true)]
  127. public int ConvertEmptyStringToNullTrue { get; set; }
  128. [DisplayFormat(ConvertEmptyStringToNull = false)]
  129. public int ConvertEmptyStringToNullFalse { get; set; }
  130. [DataType(DataType.Currency)]
  131. public int DataTypeWithoutDisplayFormatOverride { get; set; }
  132. [DataType(DataType.Currency)]
  133. [DisplayFormat(DataFormatString = "format override")]
  134. public int DataTypeWithDisplayFormatOverride { get; set; }
  135. [DisplayFormat(HtmlEncode = true)]
  136. public int HtmlEncodeTrue { get; set; }
  137. [DisplayFormat(HtmlEncode = false)]
  138. public int HtmlEncodeFalse { get; set; }
  139. [DataType(DataType.Currency)]
  140. [DisplayFormat(HtmlEncode = false)]
  141. public int HtmlEncodeFalseWithDataType { get; set; }
  142. // DataType trumps DisplayFormat.HtmlEncode
  143. }
  144. [Fact]
  145. public void DisplayFormatAttributetSetsNullDisplayText()
  146. {
  147. // Arrange
  148. var provider = new CachedDataAnnotationsModelMetadataProvider();
  149. // Act & Assert
  150. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NoAttribute").NullDisplayText);
  151. Assert.Equal("(null value)", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NullDisplayText").NullDisplayText);
  152. }
  153. [Fact]
  154. public void DisplayFormatAttributeSetsDisplayFormatString()
  155. {
  156. // Arrange
  157. var provider = new CachedDataAnnotationsModelMetadataProvider();
  158. // Act & Assert
  159. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NoAttribute").DisplayFormatString);
  160. Assert.Equal("Data {0} format", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DisplayFormatString").DisplayFormatString);
  161. Assert.Equal("Data {0} format", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DisplayAndEditFormatString").DisplayFormatString);
  162. }
  163. [Fact]
  164. public void DisplayFormatAttributeSetEditFormatString()
  165. {
  166. // Arrange
  167. var provider = new CachedDataAnnotationsModelMetadataProvider();
  168. // Act & Assert
  169. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NoAttribute").EditFormatString);
  170. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DisplayFormatString").EditFormatString);
  171. Assert.Equal("Data {0} format", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DisplayAndEditFormatString").EditFormatString);
  172. }
  173. [Fact]
  174. public void DisplayFormatAttributeSetsConvertEmptyStringToNull()
  175. {
  176. // Arrange
  177. var provider = new CachedDataAnnotationsModelMetadataProvider();
  178. // Act & Assert
  179. Assert.True(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NoAttribute").ConvertEmptyStringToNull);
  180. Assert.True(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "ConvertEmptyStringToNullTrue").ConvertEmptyStringToNull);
  181. Assert.False(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "ConvertEmptyStringToNullFalse").ConvertEmptyStringToNull);
  182. }
  183. [Fact]
  184. public void DataTypeWithoutDisplayFormatOverrideUsesDataTypesDisplayFormat()
  185. {
  186. // Arrange
  187. var provider = new CachedDataAnnotationsModelMetadataProvider();
  188. // Act
  189. string result = provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DataTypeWithoutDisplayFormatOverride").DisplayFormatString;
  190. // Assert
  191. Assert.Equal("{0:C}", result); // Currency's default format string
  192. }
  193. [Fact]
  194. public void DataTypeWithDisplayFormatOverrideUsesDisplayFormatOverride()
  195. {
  196. // Arrange
  197. var provider = new CachedDataAnnotationsModelMetadataProvider();
  198. // Act
  199. string result = provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "DataTypeWithDisplayFormatOverride").DisplayFormatString;
  200. // Assert
  201. Assert.Equal("format override", result);
  202. }
  203. [Fact]
  204. public void DataTypeInfluencedByDisplayFormatAttributeHtmlEncode()
  205. {
  206. // Arrange
  207. var provider = new CachedDataAnnotationsModelMetadataProvider();
  208. // Act & Assert
  209. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "NoAttribute").DataTypeName);
  210. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "HtmlEncodeTrue").DataTypeName);
  211. Assert.Equal("Html", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "HtmlEncodeFalse").DataTypeName);
  212. Assert.Equal("Currency", provider.GetMetadataForProperty(null, typeof(DisplayFormatModel), "HtmlEncodeFalseWithDataType").DataTypeName);
  213. }
  214. // [ScaffoldColumn] tests
  215. class ScaffoldColumnModel
  216. {
  217. public int NoAttribute { get; set; }
  218. [ScaffoldColumn(true)]
  219. public int ScaffoldColumnTrue { get; set; }
  220. [ScaffoldColumn(false)]
  221. public int ScaffoldColumnFalse { get; set; }
  222. }
  223. [Fact]
  224. public void ScaffoldColumnAttributeSetsShowForDisplay()
  225. {
  226. // Arrange
  227. var provider = new CachedDataAnnotationsModelMetadataProvider();
  228. // Act & Assert
  229. Assert.True(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "NoAttribute").ShowForDisplay);
  230. Assert.True(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "ScaffoldColumnTrue").ShowForDisplay);
  231. Assert.False(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "ScaffoldColumnFalse").ShowForDisplay);
  232. }
  233. [Fact]
  234. public void ScaffoldColumnAttributeSetsShowForEdit()
  235. {
  236. // Arrange
  237. var provider = new CachedDataAnnotationsModelMetadataProvider();
  238. // Act & Assert
  239. Assert.True(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "NoAttribute").ShowForEdit);
  240. Assert.True(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "ScaffoldColumnTrue").ShowForEdit);
  241. Assert.False(provider.GetMetadataForProperty(null, typeof(ScaffoldColumnModel), "ScaffoldColumnFalse").ShowForEdit);
  242. }
  243. // [DisplayColumn] tests
  244. [DisplayColumn("NoPropertyWithThisName")]
  245. class UnknownDisplayColumnModel
  246. {
  247. }
  248. [Fact]
  249. public void SimpleDisplayNameWithUnknownDisplayColumnThrows()
  250. {
  251. // Arrange
  252. var provider = new CachedDataAnnotationsModelMetadataProvider();
  253. // Act & Assert
  254. Assert.Throws<InvalidOperationException>(
  255. () => provider.GetMetadataForType(() => new UnknownDisplayColumnModel(), typeof(UnknownDisplayColumnModel)).SimpleDisplayText,
  256. typeof(UnknownDisplayColumnModel).FullName + " has a DisplayColumn attribute for NoPropertyWithThisName, but property NoPropertyWithThisName does not exist.");
  257. }
  258. [DisplayColumn("WriteOnlyProperty")]
  259. class WriteOnlyDisplayColumnModel
  260. {
  261. public int WriteOnlyProperty
  262. {
  263. set { }
  264. }
  265. }
  266. [DisplayColumn("PrivateReadPublicWriteProperty")]
  267. class PrivateReadPublicWriteDisplayColumnModel
  268. {
  269. public int PrivateReadPublicWriteProperty { private get; set; }
  270. }
  271. [Fact]
  272. public void SimpleDisplayTextForTypeWithWriteOnlyDisplayColumnThrows()
  273. {
  274. // Arrange
  275. var provider = new CachedDataAnnotationsModelMetadataProvider();
  276. // Act & Assert
  277. Assert.Throws<InvalidOperationException>(
  278. () => provider.GetMetadataForType(() => new WriteOnlyDisplayColumnModel(), typeof(WriteOnlyDisplayColumnModel)).SimpleDisplayText,
  279. typeof(WriteOnlyDisplayColumnModel).FullName + " has a DisplayColumn attribute for WriteOnlyProperty, but property WriteOnlyProperty does not have a public getter.");
  280. Assert.Throws<InvalidOperationException>(
  281. () => provider.GetMetadataForType(() => new PrivateReadPublicWriteDisplayColumnModel(), typeof(PrivateReadPublicWriteDisplayColumnModel)).SimpleDisplayText,
  282. typeof(PrivateReadPublicWriteDisplayColumnModel).FullName + " has a DisplayColumn attribute for PrivateReadPublicWriteProperty, but property PrivateReadPublicWriteProperty does not have a public getter.");
  283. }
  284. [DisplayColumn("DisplayColumnProperty")]
  285. class SimpleDisplayTextAttributeModel
  286. {
  287. public int FirstProperty
  288. {
  289. get { return 42; }
  290. }
  291. [ScaffoldColumn(false)]
  292. public string DisplayColumnProperty { get; set; }
  293. }
  294. class SimpleDisplayTextAttributeModelContainer
  295. {
  296. [DisplayFormat(NullDisplayText = "This is the null display text")]
  297. public SimpleDisplayTextAttributeModel Inner { get; set; }
  298. }
  299. [Fact]
  300. public void SimpleDisplayTextForNonNullClassWithNonNullDisplayColumnValue()
  301. {
  302. // Arrange
  303. string expected = "Custom property display value";
  304. var provider = new CachedDataAnnotationsModelMetadataProvider();
  305. var model = new SimpleDisplayTextAttributeModel { DisplayColumnProperty = expected };
  306. var metadata = provider.GetMetadataForType(() => model, typeof(SimpleDisplayTextAttributeModel));
  307. // Act
  308. string result = metadata.SimpleDisplayText;
  309. // Assert
  310. Assert.Equal(expected, result);
  311. }
  312. [Fact]
  313. public void SimpleDisplayTextForNullClassRevertsToDefaultBehavior()
  314. {
  315. // Arrange
  316. var provider = new CachedDataAnnotationsModelMetadataProvider();
  317. var metadata = provider.GetMetadataForProperty(null, typeof(SimpleDisplayTextAttributeModelContainer), "Inner");
  318. // Act
  319. string result = metadata.SimpleDisplayText;
  320. // Assert
  321. Assert.Equal("This is the null display text", result);
  322. }
  323. [Fact]
  324. public void SimpleDisplayTextForNonNullClassWithNullDisplayColumnValueRevertsToDefaultBehavior()
  325. {
  326. // Arrange
  327. var provider = new CachedDataAnnotationsModelMetadataProvider();
  328. var model = new SimpleDisplayTextAttributeModel();
  329. var metadata = provider.GetMetadataForType(() => model, typeof(SimpleDisplayTextAttributeModel));
  330. // Act
  331. string result = metadata.SimpleDisplayText;
  332. // Assert
  333. Assert.Equal("42", result); // Falls back to the default logic of first property value
  334. }
  335. // [Required] tests
  336. class IsRequiredModel
  337. {
  338. public int NonNullableWithout { get; set; }
  339. public string NullableWithout { get; set; }
  340. [Required]
  341. public string NullableWith { get; set; }
  342. }
  343. [Fact]
  344. public void IsRequiredTests()
  345. {
  346. // Arrange
  347. var provider = new CachedDataAnnotationsModelMetadataProvider();
  348. // Act & Assert
  349. Assert.True(provider.GetMetadataForProperty(null, typeof(IsRequiredModel), "NonNullableWithout").IsRequired);
  350. Assert.False(provider.GetMetadataForProperty(null, typeof(IsRequiredModel), "NullableWithout").IsRequired);
  351. Assert.True(provider.GetMetadataForProperty(null, typeof(IsRequiredModel), "NullableWith").IsRequired);
  352. }
  353. // [Display] & [DisplayName] tests
  354. class DisplayModel
  355. {
  356. public int NoAttribute { get; set; }
  357. // Description
  358. [Display]
  359. public int DescriptionNotSet { get; set; }
  360. [Display(Description = "Description text")]
  361. public int DescriptionSet { get; set; }
  362. // DisplayName
  363. [DisplayName("Value from DisplayName")]
  364. public int DisplayNameAttributeNoDisplayAttribute { get; set; }
  365. [Display]
  366. public int DisplayAttributeNameNotSet { get; set; }
  367. [Display(Name = "Non empty name")]
  368. public int DisplayAttributeNonEmptyName { get; set; }
  369. [Display]
  370. [DisplayName("Value from DisplayName")]
  371. public int BothAttributesNameNotSet { get; set; }
  372. [Display(Name = "Value from Display")]
  373. [DisplayName("Value from DisplayName")]
  374. public int BothAttributes { get; set; }
  375. // Display trumps DisplayName
  376. // Order
  377. [Display]
  378. public int OrderNotSet { get; set; }
  379. [Display(Order = 2112)]
  380. public int OrderSet { get; set; }
  381. // ShortDisplayName
  382. [Display]
  383. public int ShortNameNotSet { get; set; }
  384. [Display(ShortName = "Short name")]
  385. public int ShortNameSet { get; set; }
  386. // Watermark
  387. [Display]
  388. public int PromptNotSet { get; set; }
  389. [Display(Prompt = "Enter stuff here")]
  390. public int PromptSet { get; set; }
  391. }
  392. [Fact]
  393. public void DescriptionTests()
  394. {
  395. // Arrange
  396. var provider = new CachedDataAnnotationsModelMetadataProvider();
  397. // Act & Assert
  398. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "NoAttribute").Description);
  399. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "DescriptionNotSet").Description);
  400. Assert.Equal("Description text", provider.GetMetadataForProperty(null, typeof(DisplayModel), "DescriptionSet").Description);
  401. }
  402. [Fact]
  403. public void DisplayNameTests()
  404. {
  405. // Arrange
  406. var provider = new CachedDataAnnotationsModelMetadataProvider();
  407. // Act & Assert
  408. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "NoAttribute").DisplayName);
  409. Assert.Equal("Value from DisplayName", provider.GetMetadataForProperty(null, typeof(DisplayModel), "DisplayNameAttributeNoDisplayAttribute").DisplayName);
  410. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "DisplayAttributeNameNotSet").DisplayName);
  411. Assert.Equal("Non empty name", provider.GetMetadataForProperty(null, typeof(DisplayModel), "DisplayAttributeNonEmptyName").DisplayName);
  412. Assert.Equal("Value from DisplayName", provider.GetMetadataForProperty(null, typeof(DisplayModel), "BothAttributesNameNotSet").DisplayName);
  413. Assert.Equal("Value from Display", provider.GetMetadataForProperty(null, typeof(DisplayModel), "BothAttributes").DisplayName);
  414. }
  415. [Fact]
  416. public void OrderTests()
  417. {
  418. // Arrange
  419. var provider = new CachedDataAnnotationsModelMetadataProvider();
  420. // Act & Assert
  421. Assert.Equal(10000, provider.GetMetadataForProperty(null, typeof(DisplayModel), "NoAttribute").Order);
  422. Assert.Equal(10000, provider.GetMetadataForProperty(null, typeof(DisplayModel), "OrderNotSet").Order);
  423. Assert.Equal(2112, provider.GetMetadataForProperty(null, typeof(DisplayModel), "OrderSet").Order);
  424. }
  425. [Fact]
  426. public void ShortDisplayNameTests()
  427. {
  428. // Arrange
  429. var provider = new CachedDataAnnotationsModelMetadataProvider();
  430. // Act & Assert
  431. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "NoAttribute").ShortDisplayName);
  432. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "ShortNameNotSet").ShortDisplayName);
  433. Assert.Equal("Short name", provider.GetMetadataForProperty(null, typeof(DisplayModel), "ShortNameSet").ShortDisplayName);
  434. }
  435. [Fact]
  436. public void WatermarkTests()
  437. {
  438. // Arrange
  439. var provider = new CachedDataAnnotationsModelMetadataProvider();
  440. // Act & Assert
  441. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "NoAttribute").Watermark);
  442. Assert.Null(provider.GetMetadataForProperty(null, typeof(DisplayModel), "PromptNotSet").Watermark);
  443. Assert.Equal("Enter stuff here", provider.GetMetadataForProperty(null, typeof(DisplayModel), "PromptSet").Watermark);
  444. }
  445. }
  446. [RunWith(typeof(PartialTrustRunner))]
  447. public class CachedDataAnnotationsModelMetadataProviderPartialTrustTest : CachedDataAnnotationsModelMetadataProviderTest { }
  448. }