mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
Hosts file editor (#20462)
This commit is contained in:
committed by
GitHub
parent
ab41b61e84
commit
b2e1337d4e
83
src/modules/Hosts/Hosts.Tests/EntryTest.cs
Normal file
83
src/modules/Hosts/Hosts.Tests/EntryTest.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Hosts.Models;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Hosts.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class EntryTest
|
||||
{
|
||||
[DataTestMethod]
|
||||
[DataRow("\t\t10.1.1.1\t\thost\t\t", "10.1.1.1", "host", "", true)]
|
||||
[DataRow(" 10.1.1.1 host ", "10.1.1.1", "host", "", true)]
|
||||
[DataRow("10.1.1.1 host", "10.1.1.1", "host", "", true)]
|
||||
[DataRow("\t\t#\t\t10.1.1.1\thost\t\t", "10.1.1.1", "host", "", false)]
|
||||
[DataRow(" # 10.1.1.1 host ", "10.1.1.1", "host", "", false)]
|
||||
[DataRow("#10.1.1.1 host", "10.1.1.1", "host", "", false)]
|
||||
[DataRow("\t\t10.1.1.1\t\thost\t\t#\t\tcomment\t\t", "10.1.1.1", "host", "comment", true)]
|
||||
[DataRow(" 10.1.1.1 host # comment ", "10.1.1.1", "host", "comment", true)]
|
||||
[DataRow("10.1.1.1 host#comment", "10.1.1.1", "host", "comment", true)]
|
||||
[DataRow("\t\t#\t\t10.1.1.1\thost\t\t#\t\tcomment\t\t", "10.1.1.1", "host", "comment", false)]
|
||||
[DataRow(" # 10.1.1.1 host # comment ", "10.1.1.1", "host", "comment", false)]
|
||||
[DataRow("#10.1.1.1 host#comment", "10.1.1.1", "host", "comment", false)]
|
||||
[DataRow("# #10.1.1.1 host#comment", "10.1.1.1", "host", "comment", false)]
|
||||
[DataRow("# #\t10.1.1.1 host#comment", "10.1.1.1", "host", "comment", false)]
|
||||
[DataRow("# # \t10.1.1.1 host#comment", "10.1.1.1", "host", "comment", false)]
|
||||
public void Valid_Entry_SingleHost(string line, string address, string host, string comment, bool active)
|
||||
{
|
||||
var entry = new Entry(line);
|
||||
|
||||
Assert.AreEqual(entry.Address, address);
|
||||
Assert.AreEqual(entry.Hosts, host);
|
||||
Assert.AreEqual(entry.Comment, comment);
|
||||
Assert.AreEqual(entry.Active, active);
|
||||
Assert.IsTrue(entry.Valid);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("\t\t10.1.1.1\t\thost host.local\t\t", "10.1.1.1", "host host.local", "", true)]
|
||||
[DataRow(" 10.1.1.1 host host.local ", "10.1.1.1", "host host.local", "", true)]
|
||||
[DataRow("10.1.1.1 host host.local", "10.1.1.1", "host host.local", "", true)]
|
||||
[DataRow("\t\t#\t\t10.1.1.1\thost\t\thost.local\t\t", "10.1.1.1", "host host.local", "", false)]
|
||||
[DataRow(" # 10.1.1.1 host host.local ", "10.1.1.1", "host host.local", "", false)]
|
||||
[DataRow("#10.1.1.1 host host.local", "10.1.1.1", "host host.local", "", false)]
|
||||
[DataRow("\t\t10.1.1.1\t\thost\t\thost.local\t\t#\t\tcomment\t\t", "10.1.1.1", "host host.local", "comment", true)]
|
||||
[DataRow(" 10.1.1.1 host host.local # comment ", "10.1.1.1", "host host.local", "comment", true)]
|
||||
[DataRow("10.1.1.1 host host.local#comment", "10.1.1.1", "host host.local", "comment", true)]
|
||||
[DataRow("\t\t#\t\t10.1.1.1\thost\t\thost.local\t\t#\t\tcomment\t\t", "10.1.1.1", "host host.local", "comment", false)]
|
||||
[DataRow(" # 10.1.1.1 host host.local # comment ", "10.1.1.1", "host host.local", "comment", false)]
|
||||
[DataRow("#10.1.1.1 host host.local#comment", "10.1.1.1", "host host.local", "comment", false)]
|
||||
public void Valid_Entry_MultipleHosts(string line, string address, string host, string comment, bool active)
|
||||
{
|
||||
var entry = new Entry(line);
|
||||
|
||||
Assert.AreEqual(entry.Address, address);
|
||||
Assert.AreEqual(entry.Hosts, host);
|
||||
Assert.AreEqual(entry.Comment, comment);
|
||||
Assert.AreEqual(entry.Active, active);
|
||||
Assert.IsTrue(entry.Valid);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("\t\t10.1.1.1\t\t")]
|
||||
[DataRow(" 10.1.1.1 ")]
|
||||
[DataRow("10.1.1.1")]
|
||||
[DataRow("\t\thost\t\t")]
|
||||
[DataRow(" host ")]
|
||||
[DataRow("host")]
|
||||
[DataRow("\t\t10\t\thost")]
|
||||
[DataRow(" 10 host ")]
|
||||
[DataRow("10 host")]
|
||||
[DataRow("\t\thost\t\t10.1.1.1")]
|
||||
[DataRow(" host 10.1.1.1")]
|
||||
[DataRow("host 10.1.1.1")]
|
||||
public void Not_Valid_Entry(string line)
|
||||
{
|
||||
var entry = new Entry(line);
|
||||
Assert.IsFalse(entry.Valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj
Normal file
30
src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<IsPackable>false</IsPackable>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\Hosts\Hosts.Tests\</OutputPath>
|
||||
<IntermediateOutputPath>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\</IntermediateOutputPath>
|
||||
<RootNamespace>Hosts.Tests</RootNamespace>
|
||||
<AssemblyName>PowerToys.Hosts.Tests</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="12.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Hosts\Hosts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
255
src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs
Normal file
255
src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Hosts.Helpers;
|
||||
using Hosts.Models;
|
||||
using Hosts.Settings;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Settings.UI.Library.Enumerations;
|
||||
|
||||
namespace Hosts.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class HostsServiceTest
|
||||
{
|
||||
private static Mock<IElevationHelper> _elevationHelper;
|
||||
|
||||
[ClassInitialize]
|
||||
public static void ClassInitialize(TestContext context)
|
||||
{
|
||||
_elevationHelper = new Mock<IElevationHelper>();
|
||||
_elevationHelper.Setup(m => m.IsElevated).Returns(true);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Hosts_Exists()
|
||||
{
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(string.Empty));
|
||||
var result = service.Exists();
|
||||
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Hosts_Not_Exists()
|
||||
{
|
||||
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
|
||||
{
|
||||
})
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
var result = service.Exists();
|
||||
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Host_Added()
|
||||
{
|
||||
var content =
|
||||
@"10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var contentResult =
|
||||
@" 10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
# 10.1.1.30 host30 host30.local # new entry
|
||||
";
|
||||
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(content));
|
||||
|
||||
var (_, entries) = await service.ReadAsync();
|
||||
entries.Add(new Entry("10.1.1.30", "host30 host30.local", "new entry", false));
|
||||
await service.WriteAsync(string.Empty, entries);
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, contentResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Host_Deleted()
|
||||
{
|
||||
var content =
|
||||
@"10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var contentResult =
|
||||
@"10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(content));
|
||||
|
||||
var (_, entries) = await service.ReadAsync();
|
||||
entries.RemoveAt(0);
|
||||
await service.WriteAsync(string.Empty, entries);
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, contentResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Host_Updated()
|
||||
{
|
||||
var content =
|
||||
@"10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var contentResult =
|
||||
@"# 10.1.1.10 host host.local host1.local # updated comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(content));
|
||||
|
||||
var (_, entries) = await service.ReadAsync();
|
||||
var entry = entries[0];
|
||||
entry.Address = "10.1.1.10";
|
||||
entry.Hosts = "host host.local host1.local";
|
||||
entry.Comment = "updated comment";
|
||||
entry.Active = false;
|
||||
await service.WriteAsync(string.Empty, entries);
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, contentResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Empty_Hosts()
|
||||
{
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(string.Empty));
|
||||
|
||||
await service.WriteAsync(string.Empty, Enumerable.Empty<Entry>());
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, string.Empty);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task AdditionalLines_Top()
|
||||
{
|
||||
var content =
|
||||
@"# header
|
||||
10.1.1.1 host host.local # comment
|
||||
# comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
# footer
|
||||
";
|
||||
|
||||
var contentResult =
|
||||
@"# header
|
||||
# comment
|
||||
# footer
|
||||
10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
";
|
||||
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
userSettings.Setup(m => m.AdditionalLinesPosition).Returns(AdditionalLinesPosition.Top);
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(content));
|
||||
|
||||
var (additionalLines, entries) = await service.ReadAsync();
|
||||
await service.WriteAsync(additionalLines, entries);
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, contentResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task AdditionalLines_Bottom()
|
||||
{
|
||||
var content =
|
||||
@"# header
|
||||
10.1.1.1 host host.local # comment
|
||||
# comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
# footer
|
||||
";
|
||||
|
||||
var contentResult =
|
||||
@"10.1.1.1 host host.local # comment
|
||||
10.1.1.2 host2 host2.local # another comment
|
||||
# header
|
||||
# comment
|
||||
# footer
|
||||
";
|
||||
|
||||
var fileSystem = new MockFileSystem
|
||||
{
|
||||
FileSystemWatcher = new TestFileSystemWatcherFactory(),
|
||||
};
|
||||
|
||||
var userSettings = new Mock<IUserSettings>();
|
||||
userSettings.Setup(m => m.AdditionalLinesPosition).Returns(AdditionalLinesPosition.Bottom);
|
||||
|
||||
var service = new HostsService(fileSystem, userSettings.Object, _elevationHelper.Object);
|
||||
fileSystem.AddFile(service.HostsFilePath, new MockFileData(content));
|
||||
|
||||
var (additionalLines, entries) = await service.ReadAsync();
|
||||
await service.WriteAsync(additionalLines, entries);
|
||||
|
||||
var result = fileSystem.GetFile(service.HostsFilePath);
|
||||
Assert.AreEqual(result.TextContents, contentResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/modules/Hosts/Hosts.Tests/TestFileSystemWatcher.cs
Normal file
49
src/modules/Hosts/Hosts.Tests/TestFileSystemWatcher.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Hosts.Tests
|
||||
{
|
||||
public class TestFileSystemWatcher : FileSystemWatcherBase
|
||||
{
|
||||
public override bool IncludeSubdirectories { get; set; }
|
||||
|
||||
public override bool EnableRaisingEvents { get; set; }
|
||||
|
||||
public override string Filter { get; set; }
|
||||
|
||||
public override int InternalBufferSize { get; set; }
|
||||
|
||||
public override NotifyFilters NotifyFilter { get; set; }
|
||||
|
||||
public override string Path { get; set; }
|
||||
|
||||
public override ISite Site { get; set; }
|
||||
|
||||
public override ISynchronizeInvoke SynchronizingObject { get; set; }
|
||||
|
||||
public override WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType) => default(WaitForChangedResult);
|
||||
|
||||
public override WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int timeout) => default(WaitForChangedResult);
|
||||
|
||||
public TestFileSystemWatcher(string path) => Path = path;
|
||||
|
||||
public TestFileSystemWatcher(string path, string filter)
|
||||
{
|
||||
Path = path;
|
||||
Filter = filter;
|
||||
}
|
||||
|
||||
public override void BeginInit()
|
||||
{
|
||||
}
|
||||
|
||||
public override void EndInit()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace Hosts.Tests
|
||||
{
|
||||
public class TestFileSystemWatcherFactory : IFileSystemWatcherFactory
|
||||
{
|
||||
public IFileSystemWatcher CreateNew() => new TestFileSystemWatcher(null);
|
||||
|
||||
public IFileSystemWatcher CreateNew(string path) => new TestFileSystemWatcher(path);
|
||||
|
||||
public IFileSystemWatcher CreateNew(string path, string filter) => new TestFileSystemWatcher(path, filter);
|
||||
|
||||
public IFileSystemWatcher FromPath(string path) => new TestFileSystemWatcher(path);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user