// Copyright (c) Umbraco. // See LICENSE for more details. using System.Text; using NUnit.Framework; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.IO.MediaPathSchemes; using Umbraco.Cms.Tests.Common.Attributes; using Umbraco.Cms.Tests.Common.Testing; using Umbraco.Cms.Tests.Integration.Testing; namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.IO; [TestFixture] [UmbracoTest] internal sealed class FileSystemsTests : UmbracoIntegrationTest { [Test] public void Can_Get_MediaFileManager() { var fileSystem = GetRequiredService(); Assert.NotNull(fileSystem); } [Test] public void MediaFileManager_Is_Singleton() { var fileManager1 = GetRequiredService(); var fileManager2 = GetRequiredService(); Assert.AreSame(fileManager1, fileManager2); } [Test] [LongRunning] public void Can_Delete_MediaFiles() { var mediaFileManager = GetRequiredService(); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("test")); var virtualPath = mediaFileManager.GetMediaPath("file.txt", Guid.NewGuid(), Guid.NewGuid()); mediaFileManager.FileSystem.AddFile(virtualPath, memoryStream); // ~/media/1234/file.txt exists var hostingEnvironment = GetRequiredService(); var physPath = hostingEnvironment.MapPathWebRoot(Path.Combine("media", virtualPath)); Assert.IsTrue(File.Exists(physPath)); // ~/media/1234/file.txt is gone mediaFileManager.DeleteMediaFiles(new[] { virtualPath }); Assert.IsFalse(File.Exists(physPath)); var scheme = GetRequiredService(); if (scheme is UniqueMediaPathScheme) { // ~/media/1234 is *not* gone physPath = Path.GetDirectoryName(physPath); Assert.IsTrue(Directory.Exists(physPath)); } else { // ~/media/1234 is gone physPath = Path.GetDirectoryName(physPath); Assert.IsFalse(Directory.Exists(physPath)); } // ~/media exists physPath = Path.GetDirectoryName(physPath); Assert.IsTrue(Directory.Exists(physPath)); } [Test] public void Can_Add_Suffix_To_Media_Files() { var mediaFileManager = GetRequiredService(); var hostingEnvironment = GetRequiredService(); CreateMediaFile(mediaFileManager, hostingEnvironment, out string virtualPath, out string physicalPath); Assert.IsTrue(File.Exists(physicalPath)); mediaFileManager.SuffixMediaFiles([virtualPath], Cms.Core.Constants.Conventions.Media.TrashedMediaSuffix); Assert.IsFalse(File.Exists(physicalPath)); var virtualPathWithSuffix = virtualPath.Replace("file.txt", $"file{Cms.Core.Constants.Conventions.Media.TrashedMediaSuffix}.txt"); physicalPath = hostingEnvironment.MapPathWebRoot(Path.Combine("media", virtualPathWithSuffix)); Assert.IsTrue(File.Exists(physicalPath)); } [Test] public void Can_Remove_Suffix_From_Media_Files() { var mediaFileManager = GetRequiredService(); var hostingEnvironment = GetRequiredService(); CreateMediaFile(mediaFileManager, hostingEnvironment, out string virtualPath, out string physicalPath); mediaFileManager.SuffixMediaFiles([virtualPath], Cms.Core.Constants.Conventions.Media.TrashedMediaSuffix); Assert.IsFalse(File.Exists(physicalPath)); mediaFileManager.RemoveSuffixFromMediaFiles([virtualPath], Cms.Core.Constants.Conventions.Media.TrashedMediaSuffix); Assert.IsFalse(File.Exists(physicalPath)); var virtualPathWithSuffix = virtualPath.Replace("file.txt", $"file{Cms.Core.Constants.Conventions.Media.TrashedMediaSuffix}.txt"); physicalPath = hostingEnvironment.MapPathWebRoot(Path.Combine("media", virtualPathWithSuffix)); Assert.IsTrue(File.Exists(physicalPath)); } private static void CreateMediaFile( MediaFileManager mediaFileManager, IHostingEnvironment hostingEnvironment, out string virtualPath, out string physicalPath) { virtualPath = mediaFileManager.GetMediaPath("file.txt", Guid.NewGuid(), Guid.NewGuid()); physicalPath = hostingEnvironment.MapPathWebRoot(Path.Combine("media", virtualPath)); var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("test")); mediaFileManager.FileSystem.AddFile(virtualPath, memoryStream); Assert.IsTrue(File.Exists(physicalPath)); } // TODO: don't make sense anymore /* [Test] public void Cannot_Get_InvalidFileSystem() { // throws because InvalidTypedFileSystem does not have the proper attribute with an alias Assert.Throws(() => FileSystems.GetFileSystem()); } [Test] public void Cannot_Get_NonConfiguredFileSystem() { // note: we need to reset the manager between tests else the Accept_Fallback test would corrupt that one // throws because NonConfiguredFileSystem has the proper attribute with an alias, // but then the container cannot find an IFileSystem implementation for that alias Assert.Throws(() => FileSystems.GetFileSystem()); // all we'd need to pass is to register something like: //_container.Register("noconfig", factory => new PhysicalFileSystem("~/foo")); } internal class InvalidFileSystem : FileSystemWrapper { public InvalidFileSystem(IFileSystem innerFileSystem) : base(innerFileSystem) { } } [InnerFileSystem("noconfig")] internal class NonConfiguredFileSystem : FileSystemWrapper { public NonConfiguredFileSystem(IFileSystem innerFileSystem) : base(innerFileSystem) { } } */ }