/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see .
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using DnsClient;
using DnsClient.Protocol;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
using ProtonVPN.Core.OS.Net.Dns;
namespace ProtonVPN.Core.Tests.OS.Net.Dns
{
[TestClass]
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
[SuppressMessage("ReSharper", "UseObjectOrCollectionInitializer")]
public class FixedDnsClientTest
{
private ILookupClient _lookupClient;
[TestInitialize]
public void TestInitialize()
{
_lookupClient = Substitute.For();
}
[TestMethod]
public void FixedDnsClient_ShouldThrow_WhenLookupClient_IsNull()
{
// Act
Action action = () => new FixedDnsClient(null);
// Assert
action.Should().Throw();
}
[TestMethod]
public async Task Resolve_ShouldResolve_IPAddress()
{
// Arrange
const string ip = "134.27.41.216";
FixedDnsClient client = new(_lookupClient);
// Act
string result = await client.Resolve(ip, CancellationToken.None);
// Assert
result.Should().Be(ip);
}
[TestMethod]
public async Task Resolve_ShouldResolve_HostName()
{
// Arrange
const string host = "some.host.com";
const string ip = "134.27.41.216";
CancellationToken token = new();
_lookupClient.QueryAsync(host, QueryType.A, cancellationToken: token)
.Returns(new DnsQueryResponse
{
HasError = false,
Answers = new DnsResourceRecord[]
{
new ARecord(
new ResourceRecordInfo(host, ResourceRecordType.A, QueryClass.IN, 5, 5),
IPAddress.Parse(ip))
}
});
FixedDnsClient client = new FixedDnsClient(_lookupClient);
// Act
string result = await client.Resolve(ip, token);
// Assert
result.Should().Be(ip);
}
[TestMethod]
public void NameServers_ShouldBe_LookupClientNameServers()
{
// Arrange
IPEndPoint[] nameServers = new []
{
new IPEndPoint(IPAddress.Parse("15.46.251.79"), 53),
new IPEndPoint(IPAddress.Parse("8.8.8.8"), 53),
new IPEndPoint(IPAddress.Parse("10.3.15.47"), 66)
};
_lookupClient.NameServers.Returns(nameServers.Select(s => new NameServer(s)).ToList());
FixedDnsClient client = new FixedDnsClient(_lookupClient);
// Act
IReadOnlyCollection result = client.NameServers;
// Assert
result.Should().BeEquivalentTo(nameServers);
}
[TestCleanup]
public void Cleanup()
{
_lookupClient = null;
}
#region Helpers
private class DnsQueryResponse : IDnsQueryResponse
{
public IReadOnlyList Questions { get; set; }
public IReadOnlyList Additionals { get; set; }
public IEnumerable AllRecords { get; set; }
public IReadOnlyList Answers { get; set; }
public IReadOnlyList Authorities { get; set; }
public string AuditTrail { get; set; }
public string ErrorMessage { get; set; }
public bool HasError { get; set; }
public DnsResponseHeader Header { get; set; }
public int MessageSize { get; set; }
public NameServer NameServer { get; set; }
public DnsQuerySettings Settings { get; set; }
}
#endregion
}
}