diff --git a/src/Extensions/Cloudflare.Dns/DnsRecordsExtensions.cs b/src/Extensions/Cloudflare.Dns/DnsRecordsExtensions.cs index e69e799..77a8eec 100644 --- a/src/Extensions/Cloudflare.Dns/DnsRecordsExtensions.cs +++ b/src/Extensions/Cloudflare.Dns/DnsRecordsExtensions.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare.Dns.Internals; +using Newtonsoft.Json.Linq; namespace AMWD.Net.Api.Cloudflare.Dns { @@ -63,7 +64,7 @@ namespace AMWD.Net.Api.Cloudflare.Dns /// The instance. /// The request. /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task> BatchDnsRecords(this ICloudflareClient client, BatchDnsRecordsRequest request, CancellationToken cancellationToken = default) + public static async Task> BatchDnsRecords(this ICloudflareClient client, BatchDnsRecordsRequest request, CancellationToken cancellationToken = default) { request.ZoneId.ValidateCloudflareId(); @@ -121,7 +122,45 @@ namespace AMWD.Net.Api.Cloudflare.Dns if (puts.Count > 0) batchReq.Puts = puts; - return client.PostAsync($"/zones/{request.ZoneId}/dns_records/batch", batchReq, null, cancellationToken); + var res = await client.PostAsync($"/zones/{request.ZoneId}/dns_records/batch", batchReq, null, cancellationToken); + + var response = new CloudflareResponse + { + Success = res.Success, + Errors = res.Errors, + Messages = res.Messages, + ResultInfo = res.ResultInfo + }; + + if (res.Success) + { +#pragma warning disable CS8619 // There will be no null value in the final list. + response.Result = new BatchDnsRecordsResponse + { + Creates = res.Result?.Value("posts")? + .Select(ConvertToRecord) + .Where(r => r != null) + .ToList(), + + Deletes = res.Result?.Value("deletes")? + .Select(ConvertToRecord) + .Where(r => r != null) + .ToList(), + + Overwrites = res.Result?.Value("puts")? + .Select(ConvertToRecord) + .Where(r => r != null) + .ToList(), + + Updates = res.Result?.Value("patches")? + .Select(ConvertToRecord) + .Where(r => r != null) + .ToList() + }; +#pragma warning restore CS8619 + } + + return response; } /// @@ -176,14 +215,22 @@ namespace AMWD.Net.Api.Cloudflare.Dns /// The instance. /// The request. /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task> UpdateDnsRecord(this ICloudflareClient client, UpdateDnsRecordRequest request, CancellationToken cancellationToken = default) + public static async Task> UpdateDnsRecord(this ICloudflareClient client, UpdateDnsRecordRequest request, CancellationToken cancellationToken = default) { request.ZoneId.ValidateCloudflareId(); request.RecordId.ValidateCloudflareId(); var req = ValidateRequest(request); + var res = await client.PatchAsync($"/zones/{request.ZoneId}/dns_records/{request.RecordId}", req, cancellationToken); - return client.PatchAsync($"/zones/{request.ZoneId}/dns_records/{request.RecordId}", req, cancellationToken); + return new CloudflareResponse + { + Success = res.Success, + Errors = res.Errors, + Messages = res.Messages, + ResultInfo = res.ResultInfo, + Result = ConvertToRecord(res.Result) + }; } /// @@ -206,12 +253,21 @@ namespace AMWD.Net.Api.Cloudflare.Dns /// The zone identifier. /// The record identifier. /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task> DnsRecordDetails(this ICloudflareClient client, string zoneId, string recordId, CancellationToken cancellationToken = default) + public static async Task> DnsRecordDetails(this ICloudflareClient client, string zoneId, string recordId, CancellationToken cancellationToken = default) { zoneId.ValidateCloudflareId(); recordId.ValidateCloudflareId(); - return client.GetAsync($"/zones/{zoneId}/dns_records/{recordId}", null, cancellationToken); + var res = await client.GetAsync($"/zones/{zoneId}/dns_records/{recordId}", null, cancellationToken); + + return new CloudflareResponse + { + Success = res.Success, + Errors = res.Errors, + Messages = res.Messages, + ResultInfo = res.ResultInfo, + Result = ConvertToRecord(res.Result) + }; } /// @@ -252,11 +308,25 @@ namespace AMWD.Net.Api.Cloudflare.Dns /// The zone identifier. /// Filter options (optional). /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task>> ListDnsRecords(this ICloudflareClient client, string zoneId, ListDnsRecordsFilter? options = null, CancellationToken cancellationToken = default) + public static async Task>> ListDnsRecords(this ICloudflareClient client, string zoneId, ListDnsRecordsFilter? options = null, CancellationToken cancellationToken = default) { zoneId.ValidateCloudflareId(); - return client.GetAsync>($"/zones/{zoneId}/dns_records", options, cancellationToken); + var res = await client.GetAsync>($"/zones/{zoneId}/dns_records", options, cancellationToken); + +#pragma warning disable CS8619 // There will be no null value in the final list. + return new CloudflareResponse> + { + Success = res.Success, + Errors = res.Errors, + Messages = res.Messages, + ResultInfo = res.ResultInfo, + Result = res.Result? + .Select(ConvertToRecord) + .Where(r => r != null) + .ToList() + }; +#pragma warning restore CS8619 } /// @@ -287,14 +357,22 @@ namespace AMWD.Net.Api.Cloudflare.Dns /// The instance. /// The request. /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task> OverwriteDnsRecord(this ICloudflareClient client, OverwriteDnsRecordRequest request, CancellationToken cancellationToken = default) + public static async Task> OverwriteDnsRecord(this ICloudflareClient client, OverwriteDnsRecordRequest request, CancellationToken cancellationToken = default) { request.ZoneId.ValidateCloudflareId(); request.RecordId.ValidateCloudflareId(); var req = ValidateRequest(request); + var res = await client.PutAsync($"/zones/{request.ZoneId}/dns_records/{request.RecordId}", req, cancellationToken); - return client.PutAsync($"/zones/{request.ZoneId}/dns_records/{request.RecordId}", req, cancellationToken); + return new CloudflareResponse + { + Success = res.Success, + Errors = res.Errors, + Messages = res.Messages, + ResultInfo = res.ResultInfo, + Result = ConvertToRecord(res.Result) + }; } private static InternalDnsRecordRequest ValidateRequest(CreateDnsRecordRequest request) @@ -633,5 +711,59 @@ namespace AMWD.Net.Api.Cloudflare.Dns Type = req.Type }; } + + private static DnsRecord? ConvertToRecord(JToken? recordObject) + { + if (recordObject == null) + return null; + + var recordType = GetType(recordObject["type"]?.ToString()); + + return recordType switch + { + DnsRecordType.A => recordObject.ToObject(), + DnsRecordType.AAAA => recordObject.ToObject(), + DnsRecordType.CAA => recordObject.ToObject(), + DnsRecordType.CERT => recordObject.ToObject(), + DnsRecordType.CNAME => recordObject.ToObject(), + DnsRecordType.DNSKEY => recordObject.ToObject(), + DnsRecordType.DS => recordObject.ToObject(), + DnsRecordType.HTTPS => recordObject.ToObject(), + DnsRecordType.LOC => recordObject.ToObject(), + DnsRecordType.MX => recordObject.ToObject(), + DnsRecordType.NAPTR => recordObject.ToObject(), + DnsRecordType.NS => recordObject.ToObject(), + DnsRecordType.OPENPGPKEY => recordObject.ToObject(), + DnsRecordType.PTR => recordObject.ToObject(), + DnsRecordType.SMIMEA => recordObject.ToObject(), + DnsRecordType.SRV => recordObject.ToObject(), + DnsRecordType.SSHFP => recordObject.ToObject(), + DnsRecordType.SVCB => recordObject.ToObject(), + DnsRecordType.TLSA => recordObject.ToObject(), + DnsRecordType.TXT => recordObject.ToObject(), + DnsRecordType.URI => recordObject.ToObject(), + _ => null + }; + } + + private static DnsRecordType GetType(string? typeString) + { + if (string.IsNullOrWhiteSpace(typeString)) + return 0; + + return Enum.GetValues(typeof(DnsRecordType)) + .Cast() + .Select(rt => + { + return new + { + Value = rt, + Name = rt.GetEnumMemberValue() + }; + }) + .Where(v => v.Name == typeString) + .Select(v => v.Value) + .FirstOrDefault(); + } } } diff --git a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/BatchDnsRecordsTest.cs b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/BatchDnsRecordsTest.cs index fc5c5f7..5d5173c 100644 --- a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/BatchDnsRecordsTest.cs +++ b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/BatchDnsRecordsTest.cs @@ -5,6 +5,7 @@ using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Dns; using AMWD.Net.Api.Cloudflare.Dns.Internals; using Moq; +using Newtonsoft.Json.Linq; namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { @@ -20,7 +21,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions private Mock _clientMock; private List<(string RequestPath, InternalBatchRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; - private CloudflareResponse _response; + private CloudflareResponse _response; private BatchDnsRecordsRequest _request; [TestInitialize] @@ -28,7 +29,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _callbacks = []; - _response = new CloudflareResponse + _response = new CloudflareResponse { Success = true, Messages = [ @@ -37,15 +38,21 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Errors = [ new ResponseInfo(1000, "Error 1") ], - Result = new BatchDnsRecordsResponse() + Result = new JObject + { + ["deletes"] = JArray.FromObject(new[] { JObject.FromObject(new ARecord(DomainName) { Id = RecordId, Content = IpContent }) }), + ["patches"] = JArray.FromObject(new[] { JObject.FromObject(new ARecord(DomainName) { Id = RecordId, Content = IpContent }) }), + ["posts"] = JArray.FromObject(new[] { JObject.FromObject(new ARecord(DomainName) { Id = RecordId, Content = IpContent }) }), + ["puts"] = JArray.FromObject(new[] { JObject.FromObject(new ARecord(DomainName) { Id = RecordId, Content = IpContent }) }) + } }; _request = new BatchDnsRecordsRequest(ZoneId) { Deletes = [RecordId], - Updates = [new BatchDnsRecordsRequest.Patch(RecordId, DomainName) { Type = DnsRecordType.A, Content = IpContent }], - Overwrites = [new BatchDnsRecordsRequest.Put(RecordId, DomainName) { Type = DnsRecordType.A, Content = IpContent }], Creates = [new BatchDnsRecordsRequest.Post(DomainName) { Type = DnsRecordType.A, Content = IpContent }], + Updates = [new BatchDnsRecordsRequest.Patch(RecordId, DomainName) { Type = DnsRecordType.A, Content = IpContent }], + Overwrites = [new BatchDnsRecordsRequest.Put(RecordId, DomainName) { Type = DnsRecordType.A, Content = IpContent }] }; } @@ -61,7 +68,16 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + Assert.IsNotNull(response.Result); + + Assert.AreEqual(RecordId, response.Result.Deletes.Single().Id); + Assert.AreEqual(IpContent, response.Result.Deletes.Single().Content); + Assert.AreEqual(RecordId, response.Result.Creates.Single().Id); + Assert.AreEqual(IpContent, response.Result.Creates.Single().Content); + Assert.AreEqual(RecordId, response.Result.Updates.Single().Id); + Assert.AreEqual(IpContent, response.Result.Updates.Single().Content); + Assert.AreEqual(RecordId, response.Result.Overwrites.Single().Id); + Assert.AreEqual(IpContent, response.Result.Overwrites.Single().Content); Assert.AreEqual(1, _callbacks.Count); @@ -93,7 +109,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.AreEqual(DnsRecordType.A, post.Type); Assert.AreEqual(IpContent, post.Content); - _clientMock.Verify(m => m.PostAsync($"/zones/{ZoneId}/dns_records/batch", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"/zones/{ZoneId}/dns_records/batch", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -101,7 +117,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); diff --git a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/DnsRecordDetailsTest.cs b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/DnsRecordDetailsTest.cs index 541165e..b3e4d61 100644 --- a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/DnsRecordDetailsTest.cs +++ b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/DnsRecordDetailsTest.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Dns; using Moq; +using Newtonsoft.Json.Linq; namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { @@ -14,7 +15,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions private const string RecordId = "023e105f4ecef8ad9ca31a8372d0c355"; private Mock _clientMock; - private CloudflareResponse _response; + private CloudflareResponse _response; private List<(string RequestPath, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] @@ -22,7 +23,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _callbacks = []; - _response = new CloudflareResponse + _response = new CloudflareResponse { Success = true, Messages = [ @@ -30,29 +31,31 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions ], Errors = [ new ResponseInfo(1000, "Error 1") - ], - Result = new ARecord("example.com") - { - Id = RecordId, - Content = "96.7.128.175", - Proxiable = true, - Proxied = true, - TimeToLive = 1, - Settings = new(), - Comment = "Domain verification record", - Tags = [], - CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), - ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), - CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), - TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), - } + ] }; } [TestMethod] - public async Task ShouldDeleteDnsRecord() + public async Task ShouldGetARecord() { // Arrange + var result = new ARecord("example.com") + { + Id = RecordId, + Content = "96.7.128.175", + Proxiable = true, + Proxied = true, + TimeToLive = 1, + Settings = new(), + Comment = "Domain verification record", + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); var client = GetClient(); // Act @@ -61,7 +64,8 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + + AssertRecord(result, response.Result); Assert.AreEqual(1, _callbacks.Count); @@ -69,15 +73,899 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } + [TestMethod] + public async Task ShouldGetAAAARecord() + { + // Arrange + var result = new AAAARecord("example.com") + { + Id = RecordId, + Content = "::1", + Proxiable = true, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Comment = "Domain verification record", + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetCAARecord() + { + // Arrange + var result = new CAARecord("example.com") + { + Id = RecordId, + Content = "0 issue \"letsencrypt.org\"", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetCERTRecord() + { + // Arrange + var result = new CERTRecord("example.com") + { + Id = RecordId, + Content = "2 77 2 TUlJQ1l6Q0NBY3lnQXdJQkFnSUJBREFOQmdrcWh", + Proxiable = false, + Proxied = false, + TimeToLive = 120, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetCNAMERecord() + { + // Arrange + var result = new CNAMERecord("example.com") + { + Id = RecordId, + Content = "alias.example.org", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetDNSKEYRecord() + { + // Arrange + var result = new DNSKEYRecord("example.com") + { + Id = RecordId, + Content = "256 3 13 OtuN/SL9sE+SDQ0tOLeezr1KzUNi77FflTjxQylUhm3V7m13Vz9tYQuc SGK0pyxISo9CQsszubAwJSypq3li3g==", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetDSRecord() + { + // Arrange + var result = new DSRecord("example.com") + { + Id = RecordId, + Content = "370 13 2 BE74359954660069D5C63D200C39F5603827D7DD02B56F120EE9F3A8 6764247C", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetHTTPSRecord() + { + // Arrange + var result = new HTTPSRecord("example.com") + { + Id = RecordId, + Content = "1 svc.example.com. alpn=h2", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetLOCRecord() + { + // Arrange + var result = new LOCRecord("example.com") + { + Id = RecordId, + Content = "51 30 12.748 N 0 7 39.611 W 0.00m 0.00m 0.00m 0.00m", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetMXRecord() + { + // Arrange + var result = new MXRecord("example.com") + { + Id = RecordId, + Content = "10 mail.example.com.", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetNAPTRRecord() + { + // Arrange + var result = new NAPTRRecord("example.com") + { + Id = RecordId, + Content = "100 10 \"S\" \"SIP+D2T\" \"\" _sip._tcp.example.com.", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetNSRecord() + { + // Arrange + var result = new NSRecord("example.com") + { + Id = RecordId, + Content = "a.iana-servers.net.", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetOPENPGPKEYRecord() + { + // Arrange + var result = new OPENPGPKEYRecord("00d8d3f11739d2f3537099982b4674c29fc59a8fda350fca1379613a._openpgpkey.example.com") + { + Id = RecordId, + Content = "a2V5S0VZMTIzNGtleUtFWQ==", + Proxiable = false, + Proxied = false, + TimeToLive = 3600, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetPTRRecord() + { + // Arrange + var result = new PTRRecord("14.215.184.93.in-addr.arpa") + { + Id = RecordId, + Content = "example.com", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetSMIMEARecord() + { + // Arrange + var result = new SMIMEARecord("example.com") + { + Id = RecordId, + Content = "0 0 0 keyKEY1234keyKEY", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetSRVRecord() + { + // Arrange + var result = new SRVRecord("example.com") + { + Id = RecordId, + Content = "1 0 443 mail.example.com.", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetSSHFPRecord() + { + // Arrange + var result = new SSHFPRecord("example.com") + { + Id = RecordId, + Content = "2 1 123456789abcdef67890123456789abcdef67890", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetSVCBRecord() + { + // Arrange + var result = new SVCBRecord("example.com") + { + Id = RecordId, + Content = "1 . alpn=\"h2,http/1.1\"", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetTLSARecord() + { + // Arrange + var result = new TLSARecord("_443._tcp.example.com") + { + Id = RecordId, + Content = "3 0 18cb0fc6c527506a053f4f14c8464bebbd6dede2738d11468dd953d7d6a3021f1", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetTXTRecord() + { + // Arrange + var result = new TXTRecord("example.com") + { + Id = RecordId, + Content = "\"v=spf1 -all\"", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldGetURIRecord() + { + // Arrange + var result = new URIRecord("_ftp._tcp.example.com") + { + Id = RecordId, + Content = "10 1 \"ftp://ftp.example.com/public\"", + Proxiable = false, + Proxied = false, + TimeToLive = 1, + Settings = new(), + Tags = [], + CreatedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), + CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), + TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), + }; + + _response.Result = JObject.FromObject(result); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + + AssertRecord(result, response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldReturnNullForNullResponse() + { + // Arrange + _response.Result = null; + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + Assert.IsNull(response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldReturnNullForUnknownType() + { + // Arrange + var result = new ARecord("example.com"); + _response.Result = JObject.FromObject(result); + _response.Result.Remove("type"); + var client = GetClient(); + + // Act + var response = await client.DnsRecordDetails(ZoneId, RecordId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + Assert.IsNull(response.Result); + + Assert.AreEqual(1, _callbacks.Count); + + var callback = _callbacks.First(); + Assert.AreEqual($"/zones/{ZoneId}/dns_records/{RecordId}", callback.RequestPath); + Assert.IsNull(callback.QueryFilter); + + _clientMock.Verify(m => m.GetAsync($"/zones/{ZoneId}/dns_records/{RecordId}", null, It.IsAny()), Times.Once); + _clientMock.VerifyNoOtherCalls(); + } + + private static void AssertRecord(DnsRecord expected, DnsRecord actual) + { + Assert.AreEqual(expected.Id, actual.Id); + Assert.AreEqual(expected.Name, actual.Name); + Assert.AreEqual(expected.Type, actual.Type); + Assert.AreEqual(expected.Content, actual.Content); + Assert.AreEqual(expected.Proxied, actual.Proxied); + Assert.AreEqual(expected.TimeToLive, actual.TimeToLive); + Assert.AreEqual(expected.Comment, actual.Comment); + } + private ICloudflareClient GetClient() { _clientMock = new Mock(); _clientMock - .Setup(m => m.GetAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(m => m.GetAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((requestPath, queryFilter, _) => _callbacks.Add((requestPath, queryFilter))) .ReturnsAsync(() => _response); diff --git a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/ListDnsRecordsTest.cs b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/ListDnsRecordsTest.cs index 1e42810..2c382aa 100644 --- a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/ListDnsRecordsTest.cs +++ b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/ListDnsRecordsTest.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Dns; using Moq; +using Newtonsoft.Json.Linq; namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { @@ -14,7 +15,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions private Mock _clientMock; - private CloudflareResponse> _response; + private CloudflareResponse> _response; private List<(string RequestPath, IQueryParameterFilter QueryFilter)> _callbacks; @@ -23,7 +24,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _callbacks = []; - _response = new CloudflareResponse> + _response = new CloudflareResponse> { Success = true, Messages = [ @@ -41,7 +42,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions TotalPages = 100, }, Result = [ - new ARecord("example.com") + JObject.FromObject(new ARecord("example.com") { Id = "023e105f4ecef8ad9ca31a8372d0c353", Content = "96.7.128.175", @@ -55,8 +56,8 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), - }, - new AAAARecord("example.com") + }), + JObject.FromObject(new AAAARecord("example.com") { Id = "023e105f4ecef8ad9ca31a8372d0c355", Content = "2600:1408:ec00:36::1736:7f31", @@ -70,7 +71,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), - } + }) ] }; } @@ -87,7 +88,15 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + + Assert.IsNotNull(response.Result); + Assert.AreEqual(2, response.Result.Count); + + Assert.IsInstanceOfType(response.Result.First()); + Assert.AreEqual("023e105f4ecef8ad9ca31a8372d0c353", response.Result.First().Id); + + Assert.IsInstanceOfType(response.Result.Last()); + Assert.AreEqual("023e105f4ecef8ad9ca31a8372d0c355", response.Result.Last().Id); Assert.AreEqual(1, _callbacks.Count); @@ -95,7 +104,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.AreEqual($"/zones/{ZoneId}/dns_records", callback.RequestPath); Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.GetAsync>($"/zones/{ZoneId}/dns_records", null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.GetAsync>($"/zones/{ZoneId}/dns_records", null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -116,7 +125,15 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + + Assert.IsNotNull(response.Result); + Assert.AreEqual(2, response.Result.Count); + + Assert.IsInstanceOfType(response.Result.First()); + Assert.AreEqual("023e105f4ecef8ad9ca31a8372d0c353", response.Result.First().Id); + + Assert.IsInstanceOfType(response.Result.Last()); + Assert.AreEqual("023e105f4ecef8ad9ca31a8372d0c355", response.Result.Last().Id); Assert.AreEqual(1, _callbacks.Count); @@ -127,7 +144,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.IsInstanceOfType(callback.QueryFilter); Assert.AreEqual("example.com", ((ListDnsRecordsFilter)callback.QueryFilter).Name); - _clientMock.Verify(m => m.GetAsync>($"/zones/{ZoneId}/dns_records", filter, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.GetAsync>($"/zones/{ZoneId}/dns_records", filter, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -803,7 +820,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _clientMock = new Mock(); _clientMock - .Setup(m => m.GetAsync>(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(m => m.GetAsync>(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((requestPath, queryFilter, _) => _callbacks.Add((requestPath, queryFilter))) .ReturnsAsync(() => _response); diff --git a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/OverwriteDnsRecordTest.cs b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/OverwriteDnsRecordTest.cs index efe7507..690f7c9 100644 --- a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/OverwriteDnsRecordTest.cs +++ b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/OverwriteDnsRecordTest.cs @@ -5,6 +5,7 @@ using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Dns; using AMWD.Net.Api.Cloudflare.Dns.Internals; using Moq; +using Newtonsoft.Json.Linq; namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { @@ -15,7 +16,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions private const string RecordId = "023e105f4ecef8ad9ca31a8372d0c355"; private Mock _clientMock; - private CloudflareResponse _response; + private CloudflareResponse _response; private List<(string RequestPath, InternalDnsRecordRequest Request)> _callbacks; private OverwriteDnsRecordRequest _request; @@ -24,7 +25,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _callbacks = []; - _response = new CloudflareResponse + _response = new CloudflareResponse { Success = true, Messages = [ @@ -33,7 +34,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Errors = [ new ResponseInfo(1000, "Error 1") ], - Result = new ARecord("*.example.com") + Result = JObject.FromObject(new ARecord("*.example.com") { Id = RecordId, Content = "96.7.128.175", @@ -47,7 +48,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), - } + }) }; _request = new OverwriteDnsRecordRequest(ZoneId, RecordId, "example.com") @@ -69,7 +70,23 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + + Assert.IsNotNull(response.Result); + Assert.IsInstanceOfType(response.Result); + + Assert.AreEqual(RecordId, response.Result.Id); + Assert.AreEqual("*.example.com", response.Result.Name); + Assert.AreEqual("96.7.128.175", response.Result.Content); + Assert.AreEqual("Domain verification record", response.Result.Comment); + Assert.AreEqual(1, response.Result.TimeToLive); + Assert.IsTrue(response.Result.Proxied); + Assert.IsTrue(response.Result.Proxiable); + Assert.IsNotNull(response.Result.Settings); + Assert.IsNotNull(response.Result.Meta); + Assert.IsNotNull(response.Result.CreatedOn); + Assert.IsNotNull(response.Result.ModifiedOn); + Assert.IsNotNull(response.Result.CommentModifiedOn); + Assert.IsNotNull(response.Result.TagsModifiedOn); Assert.AreEqual(1, _callbacks.Count); @@ -81,7 +98,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.AreEqual(DnsRecordType.A, callback.Request.Type); Assert.AreEqual("127.0.1.22", callback.Request.Content); - _clientMock.Verify(m => m.PutAsync($"/zones/{ZoneId}/dns_records/{RecordId}", It.IsAny(), It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PutAsync($"/zones/{ZoneId}/dns_records/{RecordId}", It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -89,7 +106,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _clientMock = new Mock(); _clientMock - .Setup(m => m.PutAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(m => m.PutAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((requestPath, request, _) => _callbacks.Add((requestPath, request))) .ReturnsAsync(() => _response); diff --git a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/UpdateDnsRecordTest.cs b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/UpdateDnsRecordTest.cs index 457bc5d..789048c 100644 --- a/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/UpdateDnsRecordTest.cs +++ b/test/Extensions/Cloudflare.Dns.Tests/DnsRecordsExtensions/UpdateDnsRecordTest.cs @@ -19,7 +19,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions private const string RecordId = "023e105f4ecef8ad9ca31a8372d0c355"; private Mock _clientMock; - private CloudflareResponse _response; + private CloudflareResponse _response; private List<(string RequestPath, InternalDnsRecordRequest Request)> _callbacks; private UpdateDnsRecordRequest _request; @@ -28,7 +28,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _callbacks = []; - _response = new CloudflareResponse + _response = new CloudflareResponse { Success = true, Messages = [ @@ -37,7 +37,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Errors = [ new ResponseInfo(1000, "Error 1") ], - Result = new ARecord("example.com") + Result = JObject.FromObject(new ARecord("example.com") { Id = RecordId, Name = "*.example.com", @@ -53,7 +53,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions ModifiedOn = DateTime.Parse("2014-01-01T05:20:00.12345Z"), CommentModifiedOn = DateTime.Parse("2024-01-01T05:20:00.12345Z"), TagsModifiedOn = DateTime.Parse("2025-01-01T05:20:00.12345Z"), - } + }) }; _request = new UpdateDnsRecordRequest(ZoneId, RecordId, "example.com") @@ -75,7 +75,23 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions // Assert Assert.IsNotNull(response); Assert.IsTrue(response.Success); - Assert.AreEqual(_response.Result, response.Result); + + Assert.IsNotNull(response.Result); + Assert.IsInstanceOfType(response.Result); + + Assert.AreEqual(RecordId, response.Result.Id); + Assert.AreEqual("*.example.com", response.Result.Name); + Assert.AreEqual("96.7.128.175", response.Result.Content); + Assert.AreEqual("Domain verification record", response.Result.Comment); + Assert.AreEqual(1, response.Result.TimeToLive); + Assert.IsTrue(response.Result.Proxied); + Assert.IsTrue(response.Result.Proxiable); + Assert.IsNotNull(response.Result.Settings); + Assert.IsNotNull(response.Result.Meta); + Assert.IsNotNull(response.Result.CreatedOn); + Assert.IsNotNull(response.Result.ModifiedOn); + Assert.IsNotNull(response.Result.CommentModifiedOn); + Assert.IsNotNull(response.Result.TagsModifiedOn); Assert.AreEqual(1, _callbacks.Count); @@ -87,7 +103,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions Assert.AreEqual(DnsRecordType.A, callback.Request.Type); Assert.AreEqual("127.0.1.22", callback.Request.Content); - _clientMock.Verify(m => m.PatchAsync($"/zones/{ZoneId}/dns_records/{RecordId}", It.IsAny(), It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PatchAsync($"/zones/{ZoneId}/dns_records/{RecordId}", It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -95,7 +111,7 @@ namespace Cloudflare.Dns.Tests.DnsRecordsExtensions { _clientMock = new Mock(); _clientMock - .Setup(m => m.PatchAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(m => m.PatchAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((requestPath, request, _) => _callbacks.Add((requestPath, request))) .ReturnsAsync(() => _response);