FileSystemXmlRepositoryTests.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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.IO;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Xml.Linq;
  8. using Microsoft.Extensions.Logging.Abstractions;
  9. using Xunit;
  10. namespace Microsoft.AspNetCore.DataProtection.Repositories
  11. {
  12. public class FileSystemXmlRepositoryTests
  13. {
  14. [Fact]
  15. public void DefaultKeyStorageDirectory_Property()
  16. {
  17. var baseDir = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
  18. ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ASP.NET")
  19. : Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".aspnet");
  20. var expectedDir = new DirectoryInfo(Path.Combine(baseDir, "DataProtection-Keys")).FullName;
  21. // Act
  22. var defaultDirInfo = FileSystemXmlRepository.DefaultKeyStorageDirectory;
  23. // Assert
  24. Assert.Equal(expectedDir, defaultDirInfo.FullName);
  25. }
  26. [Fact]
  27. public void Directory_Property()
  28. {
  29. WithUniqueTempDirectory(dirInfo =>
  30. {
  31. // Arrange
  32. var repository = new FileSystemXmlRepository(dirInfo, NullLoggerFactory.Instance);
  33. // Act
  34. var retVal = repository.Directory;
  35. // Assert
  36. Assert.Equal(dirInfo, retVal);
  37. });
  38. }
  39. [Fact]
  40. public void GetAllElements_EmptyOrNonexistentDirectory_ReturnsEmptyCollection()
  41. {
  42. WithUniqueTempDirectory(dirInfo =>
  43. {
  44. // Arrange
  45. var repository = new FileSystemXmlRepository(dirInfo, NullLoggerFactory.Instance);
  46. // Act
  47. var allElements = repository.GetAllElements();
  48. // Assert
  49. Assert.Equal(0, allElements.Count);
  50. });
  51. }
  52. [Fact]
  53. public void StoreElement_WithValidFriendlyName_UsesFriendlyName()
  54. {
  55. WithUniqueTempDirectory(dirInfo =>
  56. {
  57. // Arrange
  58. var element = XElement.Parse("<element1 />");
  59. var repository = new FileSystemXmlRepository(dirInfo, NullLoggerFactory.Instance);
  60. // Act
  61. repository.StoreElement(element, "valid-friendly-name");
  62. // Assert
  63. var fileInfos = dirInfo.GetFiles();
  64. var fileInfo = fileInfos.Single(); // only one file should've been created
  65. // filename should be "valid-friendly-name.xml"
  66. Assert.Equal("valid-friendly-name.xml", fileInfo.Name, StringComparer.OrdinalIgnoreCase);
  67. // file contents should be "<element1 />"
  68. var parsedElement = XElement.Parse(File.ReadAllText(fileInfo.FullName));
  69. XmlAssert.Equal("<element1 />", parsedElement);
  70. });
  71. }
  72. [Theory]
  73. [InlineData(null)]
  74. [InlineData("")]
  75. [InlineData(" ")]
  76. [InlineData("..")]
  77. [InlineData("not*friendly")]
  78. public void StoreElement_WithInvalidFriendlyName_CreatesNewGuidAsName(string friendlyName)
  79. {
  80. WithUniqueTempDirectory(dirInfo =>
  81. {
  82. // Arrange
  83. var element = XElement.Parse("<element1 />");
  84. var repository = new FileSystemXmlRepository(dirInfo, NullLoggerFactory.Instance);
  85. // Act
  86. repository.StoreElement(element, friendlyName);
  87. // Assert
  88. var fileInfos = dirInfo.GetFiles();
  89. var fileInfo = fileInfos.Single(); // only one file should've been created
  90. // filename should be "{GUID}.xml"
  91. var filename = fileInfo.Name;
  92. Assert.EndsWith(".xml", filename, StringComparison.OrdinalIgnoreCase);
  93. var filenameNoSuffix = filename.Substring(0, filename.Length - ".xml".Length);
  94. Guid parsedGuid = Guid.Parse(filenameNoSuffix);
  95. Assert.NotEqual(Guid.Empty, parsedGuid);
  96. // file contents should be "<element1 />"
  97. var parsedElement = XElement.Parse(File.ReadAllText(fileInfo.FullName));
  98. XmlAssert.Equal("<element1 />", parsedElement);
  99. });
  100. }
  101. [Fact]
  102. public void StoreElements_ThenRetrieve_SeesAllElements()
  103. {
  104. WithUniqueTempDirectory(dirInfo =>
  105. {
  106. // Arrange
  107. var repository = new FileSystemXmlRepository(dirInfo, NullLoggerFactory.Instance);
  108. // Act
  109. repository.StoreElement(new XElement("element1"), friendlyName: null);
  110. repository.StoreElement(new XElement("element2"), friendlyName: null);
  111. repository.StoreElement(new XElement("element3"), friendlyName: null);
  112. var allElements = repository.GetAllElements();
  113. // Assert
  114. var orderedNames = allElements.Select(el => el.Name.LocalName).OrderBy(name => name);
  115. Assert.Equal(new[] { "element1", "element2", "element3" }, orderedNames);
  116. });
  117. }
  118. /// <summary>
  119. /// Runs a test and cleans up the temp directory afterward.
  120. /// </summary>
  121. private static void WithUniqueTempDirectory(Action<DirectoryInfo> testCode)
  122. {
  123. string uniqueTempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
  124. var dirInfo = new DirectoryInfo(uniqueTempPath);
  125. try
  126. {
  127. testCode(dirInfo);
  128. }
  129. finally
  130. {
  131. // clean up when test is done
  132. if (dirInfo.Exists)
  133. {
  134. dirInfo.Delete(recursive: true);
  135. }
  136. }
  137. }
  138. }
  139. }