diff --git a/Extensions/Cloudflare.Zones/Cache/InternalRequests/PurgeRequest.cs b/Extensions/Cloudflare.Zones/Cache/InternalRequests/PurgeRequest.cs deleted file mode 100644 index 2091f21..0000000 --- a/Extensions/Cloudflare.Zones/Cache/InternalRequests/PurgeRequest.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; - -namespace AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests -{ - internal class PurgeRequest - { - [JsonProperty("purge_everything")] - public bool? PurgeEverything { get; set; } - - [JsonProperty("tags")] - public IList Tags { get; set; } - - [JsonProperty("hosts")] - public IList Hostnames { get; set; } - - [JsonProperty("prefixes")] - public IList Prefixes { get; set; } - - [JsonProperty("files")] - public IList Urls { get; set; } - - [JsonProperty("files")] - public IList UrlsWithHeaders { get; set; } - } -} diff --git a/Extensions/Cloudflare.Zones/Enums/NameserverType.cs b/Extensions/Cloudflare.Zones/Enums/NameserverType.cs new file mode 100644 index 0000000..0ab1625 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Enums/NameserverType.cs @@ -0,0 +1,42 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// The nameserver type. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum NameserverType + { + /// + /// Cloudflare standard. + /// + [EnumMember(Value = "cloudflare.standard")] + CloudflareStandard = 1, + + /// + /// Cloudflare random. + /// + [EnumMember(Value = "cloudflare.standard.random")] + CloudflareRandom = 2, + + /// + /// Custom specified by account. + /// + [EnumMember(Value = "custom.account")] + CustomAccount = 3, + + /// + /// Custom specified by tenant. + /// + [EnumMember(Value = "custom.tenant")] + CustomTenant = 4, + + /// + /// Custom specified by zone. + /// + [EnumMember(Value = "custom.zone")] + CustomZone = 5, + } +} diff --git a/Extensions/Cloudflare.Zones/Enums/ZoneMode.cs b/Extensions/Cloudflare.Zones/Enums/ZoneMode.cs new file mode 100644 index 0000000..b7a05a6 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Enums/ZoneMode.cs @@ -0,0 +1,30 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// Zone modes. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ZoneMode + { + /// + /// Standard. + /// + [EnumMember(Value = "standard")] + Standard = 1, + + /// + /// Only as CDN. + /// + [EnumMember(Value = "cdn_only")] + CdnOnly = 2, + + /// + /// Only as DNS. + /// + [EnumMember(Value = "dns_only")] + DnsOnly = 3, + } +} diff --git a/Extensions/Cloudflare.Zones/Zone/Enums/ZoneStatus.cs b/Extensions/Cloudflare.Zones/Enums/ZoneStatus.cs similarity index 100% rename from Extensions/Cloudflare.Zones/Zone/Enums/ZoneStatus.cs rename to Extensions/Cloudflare.Zones/Enums/ZoneStatus.cs diff --git a/Extensions/Cloudflare.Zones/Zone/Enums/ZoneType.cs b/Extensions/Cloudflare.Zones/Enums/ZoneType.cs similarity index 100% rename from Extensions/Cloudflare.Zones/Zone/Enums/ZoneType.cs rename to Extensions/Cloudflare.Zones/Enums/ZoneType.cs diff --git a/Extensions/Cloudflare.Zones/Zone/Enums/ZonesOrderBy.cs b/Extensions/Cloudflare.Zones/Enums/ZonesOrderBy.cs similarity index 89% rename from Extensions/Cloudflare.Zones/Zone/Enums/ZonesOrderBy.cs rename to Extensions/Cloudflare.Zones/Enums/ZonesOrderBy.cs index 67114e0..4d3884a 100644 --- a/Extensions/Cloudflare.Zones/Zone/Enums/ZonesOrderBy.cs +++ b/Extensions/Cloudflare.Zones/Enums/ZonesOrderBy.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json.Converters; namespace AMWD.Net.Api.Cloudflare.Zones { /// - /// Field to order zones by. + /// Possible fields to order zones by. /// [JsonConverter(typeof(StringEnumConverter))] public enum ZonesOrderBy diff --git a/Extensions/Cloudflare.Zones/Zone/Filters/ListZonesFilter.cs b/Extensions/Cloudflare.Zones/Filters/ListZonesFilter.cs similarity index 80% rename from Extensions/Cloudflare.Zones/Zone/Filters/ListZonesFilter.cs rename to Extensions/Cloudflare.Zones/Filters/ListZonesFilter.cs index b239e6b..1ae7329 100644 --- a/Extensions/Cloudflare.Zones/Zone/Filters/ListZonesFilter.cs +++ b/Extensions/Cloudflare.Zones/Filters/ListZonesFilter.cs @@ -12,7 +12,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// An account ID. /// /// account.id - public string AccountId { get; set; } + public string? AccountId { get; set; } /// /// An account Name. @@ -33,19 +33,19 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// Dev Account /// contains:Test /// account.name - public string AccountName { get; set; } + public string? AccountName { get; set; } /// /// Direction to order zones. /// /// direction - public SortDirection? OrderDirection { get; set; } + public SortDirection? Direction { get; set; } /// /// Whether to match all search requirements or at least one (any). /// /// match - public FilterMatchType? MatchType { get; set; } + public FilterMatchType? Match { get; set; } /// /// A domain name. @@ -68,7 +68,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// ends_with:arpa /// starts_with:dev /// name - public string Name { get; set; } + public string? Name { get; set; } /// /// Field to order zones by. @@ -99,17 +99,19 @@ namespace AMWD.Net.Api.Cloudflare.Zones { var dict = new Dictionary(); +#pragma warning disable CS8602, CS8604 // There will be no null value below. + if (!string.IsNullOrWhiteSpace(AccountId)) - dict.Add("account.id", AccountId); + dict.Add("account.id", AccountId.Trim()); if (!string.IsNullOrWhiteSpace(AccountName)) - dict.Add("account.name", AccountName); + dict.Add("account.name", AccountName.Trim()); - if (OrderDirection.HasValue && Enum.IsDefined(typeof(SortDirection), OrderDirection.Value)) - dict.Add("direction", OrderDirection.Value.GetEnumMemberValue()); + if (Direction.HasValue && Enum.IsDefined(typeof(SortDirection), Direction.Value)) + dict.Add("direction", Direction.Value.GetEnumMemberValue()); - if (MatchType.HasValue && Enum.IsDefined(typeof(FilterMatchType), MatchType.Value)) - dict.Add("match", MatchType.Value.GetEnumMemberValue()); + if (Match.HasValue && Enum.IsDefined(typeof(FilterMatchType), Match.Value)) + dict.Add("match", Match.Value.GetEnumMemberValue()); if (!string.IsNullOrWhiteSpace(Name)) dict.Add("name", Name); @@ -126,6 +128,8 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (Status.HasValue && Enum.IsDefined(typeof(ZoneStatus), Status.Value)) dict.Add("status", Status.Value.GetEnumMemberValue()); +#pragma warning restore CS8602, CS8604 + return dict; } } diff --git a/Extensions/Cloudflare.Zones/Hold/Filters/CreateZoneHoldFilter.cs b/Extensions/Cloudflare.Zones/Internals/Filters/CreateZoneHoldFilter.cs similarity index 82% rename from Extensions/Cloudflare.Zones/Hold/Filters/CreateZoneHoldFilter.cs rename to Extensions/Cloudflare.Zones/Internals/Filters/CreateZoneHoldFilter.cs index 5a5023f..e69e2fd 100644 --- a/Extensions/Cloudflare.Zones/Hold/Filters/CreateZoneHoldFilter.cs +++ b/Extensions/Cloudflare.Zones/Internals/Filters/CreateZoneHoldFilter.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace AMWD.Net.Api.Cloudflare.Zones +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Filters { internal class CreateZoneHoldFilter : IQueryParameterFilter { diff --git a/Extensions/Cloudflare.Zones/Hold/Filters/DeleteZoneHoldFilter.cs b/Extensions/Cloudflare.Zones/Internals/Filters/DeleteZoneHoldFilter.cs similarity index 84% rename from Extensions/Cloudflare.Zones/Hold/Filters/DeleteZoneHoldFilter.cs rename to Extensions/Cloudflare.Zones/Internals/Filters/DeleteZoneHoldFilter.cs index a1204d4..134e16b 100644 --- a/Extensions/Cloudflare.Zones/Hold/Filters/DeleteZoneHoldFilter.cs +++ b/Extensions/Cloudflare.Zones/Internals/Filters/DeleteZoneHoldFilter.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace AMWD.Net.Api.Cloudflare.Zones +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Filters { internal class DeleteZoneHoldFilter : IQueryParameterFilter { diff --git a/Extensions/Cloudflare.Zones/Internals/Requests/InternalCreateZoneRequest.cs b/Extensions/Cloudflare.Zones/Internals/Requests/InternalCreateZoneRequest.cs new file mode 100644 index 0000000..f63542b --- /dev/null +++ b/Extensions/Cloudflare.Zones/Internals/Requests/InternalCreateZoneRequest.cs @@ -0,0 +1,20 @@ +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Requests +{ + internal class InternalCreateZoneRequest + { + public InternalCreateZoneRequest(AccountBase account, string name) + { + Account = account; + Name = name; + } + + [JsonProperty("account")] + public AccountBase Account { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("type")] + public ZoneType? Type { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Internals/Requests/InternalEditZoneRequest.cs b/Extensions/Cloudflare.Zones/Internals/Requests/InternalEditZoneRequest.cs new file mode 100644 index 0000000..30e1e0f --- /dev/null +++ b/Extensions/Cloudflare.Zones/Internals/Requests/InternalEditZoneRequest.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Requests +{ + internal class InternalEditZoneRequest + { + [JsonProperty("type")] + public ZoneType? Type { get; set; } + + [JsonProperty("vanity_name_servers")] + public IList? VanityNameServers { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Internals/Requests/InternalPurgeCacheRequest.cs b/Extensions/Cloudflare.Zones/Internals/Requests/InternalPurgeCacheRequest.cs new file mode 100644 index 0000000..a554106 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Internals/Requests/InternalPurgeCacheRequest.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Requests +{ + internal class InternalPurgeCacheRequest + { + [JsonProperty("purge_everything")] + public bool? PurgeEverything { get; set; } + + [JsonProperty("tags")] + public IList? Tags { get; set; } + + [JsonProperty("hosts")] + public IList? Hostnames { get; set; } + + [JsonProperty("prefixes")] + public IList? Prefixes { get; set; } + + [JsonProperty("files")] + public IList? Urls { get; set; } + + [JsonProperty("files")] + public IList? UrlsWithHeaders { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Internals/Requests/InternalUpdateDnsSettingsRequest.cs b/Extensions/Cloudflare.Zones/Internals/Requests/InternalUpdateDnsSettingsRequest.cs new file mode 100644 index 0000000..78d20fb --- /dev/null +++ b/Extensions/Cloudflare.Zones/Internals/Requests/InternalUpdateDnsSettingsRequest.cs @@ -0,0 +1,29 @@ +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Requests +{ + internal class InternalUpdateDnsSettingsRequest + { + [JsonProperty("flatten_all_cnames")] + public bool? FlattenAllCnames { get; set; } + + [JsonProperty("foundation_dns")] + public bool? FoundationDns { get; set; } + + [JsonProperty("multi_provider")] + public bool? MultiProvider { get; set; } + + [JsonProperty("nameservers")] + public Nameserver? Nameservers { get; set; } + + [JsonProperty("ns_ttl")] + public int? NameserverTtl { get; set; } + + [JsonProperty("secondary_overrides")] + public bool? SecondaryOverrides { get; set; } + + [JsonProperty("soa")] + public StartOfAuthority? Soa { get; set; } + + [JsonProperty("zone_mode")] + public ZoneMode? Mode { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Cache/InternalRequests/UrlWithHeaders.cs b/Extensions/Cloudflare.Zones/Internals/Requests/PurgeUrlWithHeaders.cs similarity index 53% rename from Extensions/Cloudflare.Zones/Cache/InternalRequests/UrlWithHeaders.cs rename to Extensions/Cloudflare.Zones/Internals/Requests/PurgeUrlWithHeaders.cs index 19e9d59..9dfbadf 100644 --- a/Extensions/Cloudflare.Zones/Cache/InternalRequests/UrlWithHeaders.cs +++ b/Extensions/Cloudflare.Zones/Internals/Requests/PurgeUrlWithHeaders.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; -namespace AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests +namespace AMWD.Net.Api.Cloudflare.Zones.Internals.Requests { - internal class UrlWithHeaders + internal class PurgeUrlWithHeaders { [JsonProperty("headers")] public Dictionary Headers { get; set; } = []; [JsonProperty("url")] - public string Url { get; set; } + public string? Url { get; set; } } } diff --git a/Extensions/Cloudflare.Zones/Models/Nameserver.cs b/Extensions/Cloudflare.Zones/Models/Nameserver.cs new file mode 100644 index 0000000..19e32f5 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Models/Nameserver.cs @@ -0,0 +1,22 @@ +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// A nameserver. + /// + public class Nameserver + { + /// + /// The nameserver type. + /// + [JsonProperty("type")] + public virtual NameserverType Type { get; set; } + + // TODO: DEPRECATED? - not available on API request. + ///// + ///// Configured nameserver set to be used for this zone. + ///// + ///// Range: 1 <= X <= 5 + //[JsonProperty("ns_set")] + //public virtual int NameserverSet { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Models/StartOfAuthority.cs b/Extensions/Cloudflare.Zones/Models/StartOfAuthority.cs new file mode 100644 index 0000000..3b6a25c --- /dev/null +++ b/Extensions/Cloudflare.Zones/Models/StartOfAuthority.cs @@ -0,0 +1,83 @@ +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// The SOA (Start of Authority) record. + /// + public class StartOfAuthority + { + /// + /// Initializes a new instance of the class. + /// + /// The primary nameserver. + /// The zone administrator. First dot will be interpreted as @-sign. + /// The time to live of the SOA record. + /// Time in seconds after which secondary servers should re-check the SOA record to see if the zone has been updated. + /// Time in seconds after which secondary servers should retry queries after the primary server was unresponsive. + /// Time in seconds of being unable to query the primary server after which secondary servers should stop serving the zone. + /// The time to live (TTL) for negative caching of records within the zone. + public StartOfAuthority(string primaryNameserver, string zoneAdministrator, int ttl, int refresh, int retry, int expire, int minimumTtl) + { + PrimaryNameserver = primaryNameserver; + ZoneAdministrator = zoneAdministrator; + Ttl = ttl; + Refresh = refresh; + Retry = retry; + Expire = expire; + MinimumTtl = minimumTtl; + } + + /// + /// Time in seconds of being unable to query the primary server after which secondary servers should stop serving the zone. + /// + /// Unit: seconds. Range: 86400 <= X <= 2419200 + [JsonProperty("expire")] + public virtual int Expire { get; set; } + + /// + /// The time to live (TTL) for negative caching of records within the zone. + /// + /// Unit: seconds. Range: 60 <= X <= 86400 + [JsonProperty("min_ttl")] + public virtual int MinimumTtl { get; set; } + + /// + /// The primary nameserver, which may be used for outbound zone transfers. + /// + [JsonProperty("mname", NullValueHandling = NullValueHandling.Include)] + public virtual string PrimaryNameserver { get; set; } + + /// + /// Time in seconds after which secondary servers should re-check the SOA record to see if the zone has been updated. + /// + /// Unit: seconds. Range: 600 <= X <= 86400 + [JsonProperty("refresh")] + public virtual int Refresh { get; set; } + + /// + /// Time in seconds after which secondary servers should retry queries after the primary server was unresponsive. + /// + /// Unit: seconds. Range: 600 <= X <= 86400 + [JsonProperty("retry")] + public virtual int Retry { get; set; } + + /// + /// The email address of the zone administrator, with the first label representing the local part of the email address. + /// + /// + /// The first dot is interpreted as @ sign. + ///
+ /// admin.example.com => admin@example.com + ///
+ /// test\.user.example.org => test.user@example.org + ///
+ [JsonProperty("rname", NullValueHandling = NullValueHandling.Include)] + public virtual string ZoneAdministrator { get; set; } + + /// + /// The time to live (TTL) of the SOA record itself. + /// + /// Unit: seconds. Range: 300 <= X <= 86400 + [JsonProperty("ttl")] + public virtual int Ttl { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Models/Zone.cs b/Extensions/Cloudflare.Zones/Models/Zone.cs index e7c2952..7178177 100644 --- a/Extensions/Cloudflare.Zones/Models/Zone.cs +++ b/Extensions/Cloudflare.Zones/Models/Zone.cs @@ -13,13 +13,13 @@ namespace AMWD.Net.Api.Cloudflare.Zones ///
// <= 32 characters [JsonProperty("id")] - public string Id { get; set; } + public string? Id { get; set; } /// /// The account the zone belongs to. /// [JsonProperty("account")] - public AccountBase Account { get; set; } + public AccountBase? Account { get; set; } /// /// The last time proof of ownership was detected and the zone was made active. @@ -45,7 +45,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// Metadata about the zone. /// [JsonProperty("meta")] - public ZoneMetaData Meta { get; set; } + public ZoneMetaData? Meta { get; set; } /// /// When the zone was last modified. @@ -58,37 +58,37 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// // <= 253 characters [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// The name servers Cloudflare assigns to a zone. /// [JsonProperty("name_servers")] - public IReadOnlyList NameServers { get; set; } + public IReadOnlyList? NameServers { get; set; } /// /// DNS host at the time of switching to Cloudflare. /// [JsonProperty("original_dnshost")] - public string OriginalDnshost { get; set; } + public string? OriginalDnshost { get; set; } /// /// Original name servers before moving to Cloudflare. /// [JsonProperty("original_name_servers")] - public IReadOnlyList OriginalNameServers { get; set; } + public IReadOnlyList? OriginalNameServers { get; set; } /// /// Registrar for the domain at the time of switching to Cloudflare. /// [JsonProperty("original_registrar")] - public string OriginalRegistrar { get; set; } + public string? OriginalRegistrar { get; set; } /// /// The owner of the zone. /// [JsonProperty("owner")] - public OwnerBase Owner { get; set; } + public OwnerBase? Owner { get; set; } /// /// Indicates whether the zone is only using Cloudflare DNS services. @@ -115,6 +115,6 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// This is only available for Business and Enterprise plans. /// [JsonProperty("vanity_name_servers")] - public IReadOnlyList VanityNameServers { get; set; } + public IReadOnlyList? VanityNameServers { get; set; } } } diff --git a/Extensions/Cloudflare.Zones/Models/ZoneDnsSetting.cs b/Extensions/Cloudflare.Zones/Models/ZoneDnsSetting.cs new file mode 100644 index 0000000..394220f --- /dev/null +++ b/Extensions/Cloudflare.Zones/Models/ZoneDnsSetting.cs @@ -0,0 +1,59 @@ +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// The DNS settings. + /// + public class ZoneDnsSetting + { + /// + /// Whether to flatten all CNAME records in the zone. Note that, due to DNS limitations, + /// a CNAME record at the zone apex will always be flattened. + /// + [JsonProperty("flatten_all_cnames")] + public bool FlattenAllCnames { get; set; } + + /// + /// Whether to enable Foundation DNS Advanced Nameservers on the zone. + /// + [JsonProperty("foundation_dns")] + public bool FoundationDns { get; set; } + + /// + /// Whether to enable multi-provider DNS, which causes Cloudflare to activate the zone even when non-Cloudflare NS records exist, + /// and to respect NS records at the zone apex during outbound zone transfers. + /// + [JsonProperty("multi_provider")] + public bool MultiProvider { get; set; } + + /// + /// Settings determining the nameservers through which the zone should be available. + /// + [JsonProperty("nameservers")] + public Nameserver? Nameservers { get; set; } + + /// + /// The time to live (TTL) of the zone's nameserver (NS) records. + /// + // 30 <= X <= 86400 + [JsonProperty("ns_ttl")] + public int NameserverTtl { get; set; } + + /// + /// Allows a Secondary DNS zone to use (proxied) override records and CNAME flattening at the zone apex. + /// + [JsonProperty("secondary_overrides")] + public bool SecondaryOverrides { get; set; } + + /// + /// Components of the zone's SOA record. + /// + [JsonProperty("soa")] + public StartOfAuthority? SOA { get; set; } + + /// + /// Whether the zone mode is a regular or CDN/DNS only zone. + /// + [JsonProperty("zone_mode")] + public ZoneMode Mode { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Models/ZoneHold.cs b/Extensions/Cloudflare.Zones/Models/ZoneHold.cs index 5b7ec12..86cef14 100644 --- a/Extensions/Cloudflare.Zones/Models/ZoneHold.cs +++ b/Extensions/Cloudflare.Zones/Models/ZoneHold.cs @@ -17,7 +17,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// Gets or sets an information whether subdomains are included in the hold. ///
[JsonProperty("include_subdomains")] - public string IncludeSubdomains { get; set; } + public string? IncludeSubdomains { get; set; } /// /// Gets or sets the time after which the zone is no longer on hold. diff --git a/Extensions/Cloudflare.Zones/Models/ZoneIdResponse.cs b/Extensions/Cloudflare.Zones/Models/ZoneIdResponse.cs index 879b548..664d265 100644 --- a/Extensions/Cloudflare.Zones/Models/ZoneIdResponse.cs +++ b/Extensions/Cloudflare.Zones/Models/ZoneIdResponse.cs @@ -10,6 +10,6 @@ /// // <= 32 characters [JsonProperty("id")] - public string Id { get; set; } + public string? Id { get; set; } } } diff --git a/Extensions/Cloudflare.Zones/Requests/CreateZoneRequest.cs b/Extensions/Cloudflare.Zones/Requests/CreateZoneRequest.cs new file mode 100644 index 0000000..c67c028 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Requests/CreateZoneRequest.cs @@ -0,0 +1,37 @@ +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// Request to create a new zone. + /// + /// + /// Request to create a new zone. + /// + /// The account identifier. + /// The domain name. + public class CreateZoneRequest(string accountId, string name) + { + /// + /// The account identifier. + /// + public string AccountId { get; set; } = accountId; + + /// + /// The domain name. + /// + public string Name { get; set; } = name; + + /// + /// The zone type. + /// + /// + /// + /// A full zone implies that DNS is hosted with Cloudflare. + /// A partial zone is typically a partner-hosted zone or a CNAME setup. + /// + /// + /// If not set, Cloudflare will use as default. + /// + /// + public ZoneType? Type { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Zone/Requests/EditZoneRequest.cs b/Extensions/Cloudflare.Zones/Requests/EditZoneRequest.cs similarity index 68% rename from Extensions/Cloudflare.Zones/Zone/Requests/EditZoneRequest.cs rename to Extensions/Cloudflare.Zones/Requests/EditZoneRequest.cs index 60abc50..370bcc3 100644 --- a/Extensions/Cloudflare.Zones/Zone/Requests/EditZoneRequest.cs +++ b/Extensions/Cloudflare.Zones/Requests/EditZoneRequest.cs @@ -5,12 +5,17 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// /// A request to edit a zone. /// - public class EditZoneRequest + /// + /// Initializes a new instance of the class. + /// + /// The zone identifier. + public class EditZoneRequest(string id) { + /// /// Identifier. /// - public string Id { get; set; } + public string Id { get; set; } = id; /// /// A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. @@ -24,6 +29,6 @@ namespace AMWD.Net.Api.Cloudflare.Zones ///
/// This is only available for Business and Enterprise plans. ///
- public IList VanityNameServers { get; set; } + public IList? VanityNameServers { get; set; } } } diff --git a/Extensions/Cloudflare.Zones/Requests/UpdateDnsSettingsRequest.cs b/Extensions/Cloudflare.Zones/Requests/UpdateDnsSettingsRequest.cs new file mode 100644 index 0000000..04b74b0 --- /dev/null +++ b/Extensions/Cloudflare.Zones/Requests/UpdateDnsSettingsRequest.cs @@ -0,0 +1,61 @@ +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// Update DNS settings request. + /// + /// + /// Initializes a new instance of the class. + /// + /// The zone identifier. + public class UpdateDnsSettingsRequest(string id) + { + + /// + /// The zone identifier. + /// + public string Id { get; set; } = id; + + /// + /// Whether to flatten all CNAME records in the zone. Note that, due to DNS limitations, + /// a CNAME record at the zone apex will always be flattened. + /// + public bool? FlattenAllCnames { get; set; } + + /// + /// Whether to enable Foundation DNS Advanced Nameservers on the zone. + /// + public bool? FoundationDns { get; set; } + + /// + /// Whether to enable multi-provider DNS, which causes Cloudflare to activate the zone even when non-Cloudflare NS records exist, + /// and to respect NS records at the zone apex during outbound zone transfers. + /// + public bool? MultiProvider { get; set; } + + /// + /// Settings determining the nameservers through which the zone should be available. + /// + public Nameserver? Nameservers { get; set; } + + /// + /// The time to live (TTL) of the zone's nameserver (NS) records. + /// + /// Unit: seconds. Range: 30 <= X <= 86400 + public int? NameserverTtl { get; set; } + + /// + /// Allows a Secondary DNS zone to use (proxied) override records and CNAME flattening at the zone apex. + /// + public bool? SecondaryOverrides { get; set; } + + /// + /// Components of the zone's SOA record. + /// + public StartOfAuthority? SOA { get; set; } + + /// + /// Whether the zone mode is a regular or CDN/DNS only zone. + /// + public ZoneMode? Mode { get; set; } + } +} diff --git a/Extensions/Cloudflare.Zones/Cache/Requests/ZonePurgeCachedUrlRequest.cs b/Extensions/Cloudflare.Zones/Requests/ZonePurgeCachedUrlRequest.cs similarity index 56% rename from Extensions/Cloudflare.Zones/Cache/Requests/ZonePurgeCachedUrlRequest.cs rename to Extensions/Cloudflare.Zones/Requests/ZonePurgeCachedUrlRequest.cs index 86bca0b..30ca0b8 100644 --- a/Extensions/Cloudflare.Zones/Cache/Requests/ZonePurgeCachedUrlRequest.cs +++ b/Extensions/Cloudflare.Zones/Requests/ZonePurgeCachedUrlRequest.cs @@ -5,7 +5,11 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// /// Url with headers to purge. /// - public class ZonePurgeCachedUrlRequest + /// + /// Initializes a new instance of the class. + /// + /// The url to purge. + public class ZonePurgeCachedUrlRequest(string url) { /// /// Defined headers to specifiy the purge request. @@ -15,6 +19,6 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// /// The file url to purge. /// - public string Url { get; set; } + public string Url { get; set; } = url; } } diff --git a/Extensions/Cloudflare.Zones/Zone/InternalRequests/CreateRequest.cs b/Extensions/Cloudflare.Zones/Zone/InternalRequests/CreateRequest.cs deleted file mode 100644 index e1b514a..0000000 --- a/Extensions/Cloudflare.Zones/Zone/InternalRequests/CreateRequest.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace AMWD.Net.Api.Cloudflare.Zones.Zones.InternalRequests -{ - internal class CreateRequest - { - [JsonProperty("account")] - public AccountBase Account { get; set; } - - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("type")] - public ZoneType Type { get; set; } - } -} diff --git a/Extensions/Cloudflare.Zones/Zone/InternalRequests/EditRequest.cs b/Extensions/Cloudflare.Zones/Zone/InternalRequests/EditRequest.cs deleted file mode 100644 index 07f9b52..0000000 --- a/Extensions/Cloudflare.Zones/Zone/InternalRequests/EditRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; - -namespace AMWD.Net.Api.Cloudflare.Zones.Zones.InternalRequests -{ - internal class EditRequest - { - [JsonProperty("type")] - public ZoneType? Type { get; set; } - - [JsonProperty("vanity_name_servers")] - public IList VanityNameServers { get; set; } - } -} diff --git a/Extensions/Cloudflare.Zones/Zone/Requests/CreateZoneRequest.cs b/Extensions/Cloudflare.Zones/Zone/Requests/CreateZoneRequest.cs deleted file mode 100644 index ee9d61f..0000000 --- a/Extensions/Cloudflare.Zones/Zone/Requests/CreateZoneRequest.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace AMWD.Net.Api.Cloudflare.Zones -{ - /// - /// Request to create a new zone. - /// - public class CreateZoneRequest - { - /// - /// The account identifier. - /// - public string AccountId { get; set; } - - /// - /// The domain name. - /// - public string Name { get; set; } - - /// - /// The zone type. - /// - /// - /// A full zone implies that DNS is hosted with Cloudflare. - /// A partial zone is typically a partner-hosted zone or a CNAME setup. - /// - public ZoneType Type { get; set; } - } -} diff --git a/Extensions/Cloudflare.Zones/Cache/ZoneCacheExtensions.cs b/Extensions/Cloudflare.Zones/ZoneCacheExtensions.cs similarity index 85% rename from Extensions/Cloudflare.Zones/Cache/ZoneCacheExtensions.cs rename to Extensions/Cloudflare.Zones/ZoneCacheExtensions.cs index d4694e1..d4232ac 100644 --- a/Extensions/Cloudflare.Zones/Cache/ZoneCacheExtensions.cs +++ b/Extensions/Cloudflare.Zones/ZoneCacheExtensions.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; namespace AMWD.Net.Api.Cloudflare.Zones { @@ -24,11 +24,11 @@ namespace AMWD.Net.Api.Cloudflare.Zones public static Task> PurgeCachedContent(this ICloudflareClient client, string zoneId, CancellationToken cancellationToken = default) { zoneId.ValidateCloudflareId(); - var req = new PurgeRequest + var req = new InternalPurgeCacheRequest { PurgeEverything = true }; - return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); + return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); } /// @@ -60,15 +60,12 @@ namespace AMWD.Net.Api.Cloudflare.Zones { zoneId.ValidateCloudflareId(); - if (urls == null) - throw new ArgumentNullException(nameof(urls)); - - var req = new PurgeRequest(); + var req = new InternalPurgeCacheRequest(); if (urls.Any(u => u.Headers.Count > 0)) { req.UrlsWithHeaders = urls.Where(u => !string.IsNullOrWhiteSpace(u.Url)) - .Select(u => new UrlWithHeaders + .Select(u => new PurgeUrlWithHeaders { Url = u.Url, Headers = u.Headers @@ -81,7 +78,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones req.Urls = urls.Where(u => !string.IsNullOrWhiteSpace(u.Url)).Select(u => u.Url).ToList(); } - return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); + return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); } /// @@ -111,11 +108,11 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (tags == null) throw new ArgumentNullException(nameof(tags)); - var req = new PurgeRequest + var req = new InternalPurgeCacheRequest { Tags = tags.Where(t => !string.IsNullOrWhiteSpace(t)).ToList() }; - return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); + return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); } /// @@ -145,11 +142,11 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (hosts == null) throw new ArgumentNullException(nameof(hosts)); - var req = new PurgeRequest + var req = new InternalPurgeCacheRequest { Hostnames = hosts.Where(h => !string.IsNullOrWhiteSpace(h)).ToList() }; - return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); + return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); } /// @@ -179,11 +176,11 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (prefixes == null) throw new ArgumentNullException(nameof(prefixes)); - var req = new PurgeRequest + var req = new InternalPurgeCacheRequest { Prefixes = prefixes.Where(h => !string.IsNullOrWhiteSpace(h)).ToList() }; - return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); + return client.PostAsync($"zones/{zoneId}/purge_cache", req, cancellationToken: cancellationToken); } } } diff --git a/Extensions/Cloudflare.Zones/ZoneDnsSettingsExtensions.cs b/Extensions/Cloudflare.Zones/ZoneDnsSettingsExtensions.cs new file mode 100644 index 0000000..1d091f4 --- /dev/null +++ b/Extensions/Cloudflare.Zones/ZoneDnsSettingsExtensions.cs @@ -0,0 +1,96 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; + +namespace AMWD.Net.Api.Cloudflare.Zones +{ + /// + /// Extends the with methods for working with zones. + /// + public static class ZoneDnsSettingsExtensions + { + /// + /// Show DNS settings for a zone. + /// + /// The . + /// The zone ID. + /// A cancellation token used to propagate notification that this operation should be canceled. + public static Task> ShowZoneDnsSettings(this ICloudflareClient client, string zoneId, CancellationToken cancellationToken = default) + { + zoneId.ValidateCloudflareId(); + return client.GetAsync($"zones/{zoneId}/dns_settings", cancellationToken: cancellationToken); + } + + /// + /// Update DNS settings for a zone. + /// + /// The . + /// The update request. + /// A cancellation token used to propagate notification that this operation should be canceled. + public static Task> UpdateZoneDnsSettings(this ICloudflareClient client, UpdateDnsSettingsRequest request, CancellationToken cancellationToken = default) + { + request.Id.ValidateCloudflareId(); + + if (request.Mode.HasValue && !Enum.IsDefined(typeof(ZoneMode), request.Mode)) + throw new ArgumentOutOfRangeException(nameof(request.Mode), request.Mode, "Value must be one of the ZoneMode enum values."); + + if (request.Nameservers != null && !Enum.IsDefined(typeof(NameserverType), request.Nameservers.Type)) + throw new ArgumentOutOfRangeException(nameof(request.Nameservers.Type), request.Nameservers.Type, "Value must be one of the NameserverType enum values."); + + if (request.NameserverTtl.HasValue && (request.NameserverTtl < 30 || 86400 < request.NameserverTtl)) + throw new ArgumentOutOfRangeException(nameof(request.NameserverTtl), request.NameserverTtl, "Value must be between 30 and 86400."); + + if (request.SOA != null) + { + if (request.SOA.Expire < 86400 || 2419200 < request.SOA.Expire) + throw new ArgumentOutOfRangeException(nameof(request.SOA.Expire), request.SOA.Expire, "Value must be between 86400 and 2419200."); + + if (request.SOA.MinimumTtl < 60 || 86400 < request.SOA.MinimumTtl) + throw new ArgumentOutOfRangeException(nameof(request.SOA.MinimumTtl), request.SOA.MinimumTtl, "Value must be between 60 and 86400."); + + if (string.IsNullOrWhiteSpace(request.SOA.PrimaryNameserver)) + throw new ArgumentNullException(nameof(request.SOA.PrimaryNameserver)); + + if (request.SOA.Refresh < 600 || 86400 < request.SOA.Refresh) + throw new ArgumentOutOfRangeException(nameof(request.SOA.Refresh), request.SOA.Refresh, "Value must be between 600 and 86400."); + + if (request.SOA.Retry < 600 || 86400 < request.SOA.Retry) + throw new ArgumentOutOfRangeException(nameof(request.SOA.Retry), request.SOA.Retry, "Value must be between 600 and 86400."); + + if (request.SOA.Ttl < 300 || 86400 < request.SOA.Ttl) + throw new ArgumentOutOfRangeException(nameof(request.SOA.Ttl), request.SOA.Ttl, "Value must be between 300 and 86400."); + + if (string.IsNullOrWhiteSpace(request.SOA.ZoneAdministrator)) + throw new ArgumentNullException(nameof(request.SOA.ZoneAdministrator)); + } + + var req = new InternalUpdateDnsSettingsRequest + { + FlattenAllCnames = request.FlattenAllCnames, + FoundationDns = request.FoundationDns, + Mode = request.Mode, + MultiProvider = request.MultiProvider, + Nameservers = request.Nameservers, + NameserverTtl = request.NameserverTtl, + SecondaryOverrides = request.SecondaryOverrides, + }; + + if (request.SOA != null) + { + req.Soa = new StartOfAuthority + ( + expire: request.SOA.Expire, + minimumTtl: request.SOA.MinimumTtl, + primaryNameserver: request.SOA.PrimaryNameserver, + refresh: request.SOA.Refresh, + retry: request.SOA.Retry, + ttl: request.SOA.Ttl, + zoneAdministrator: request.SOA.ZoneAdministrator + ); + } + + return client.PatchAsync($"zones/{request.Id}/dns_settings", req, cancellationToken); + } + } +} diff --git a/Extensions/Cloudflare.Zones/Zone/ZoneExtensions.cs b/Extensions/Cloudflare.Zones/ZoneExtensions.cs similarity index 87% rename from Extensions/Cloudflare.Zones/Zone/ZoneExtensions.cs rename to Extensions/Cloudflare.Zones/ZoneExtensions.cs index 6c459ec..03ff760 100644 --- a/Extensions/Cloudflare.Zones/Zone/ZoneExtensions.cs +++ b/Extensions/Cloudflare.Zones/ZoneExtensions.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Zones.InternalRequests; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; namespace AMWD.Net.Api.Cloudflare.Zones { @@ -18,7 +18,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones /// The . /// Filter options (optional). /// A cancellation token used to propagate notification that this operation should be canceled. - public static Task>> ListZones(this ICloudflareClient client, ListZonesFilter options = null, CancellationToken cancellationToken = default) + public static Task>> ListZones(this ICloudflareClient client, ListZonesFilter? options = null, CancellationToken cancellationToken = default) { return client.GetAsync>("zones", options, cancellationToken); } @@ -52,17 +52,15 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (!RegexPatterns.ZoneName.IsMatch(request.Name)) throw new ArgumentException("Does not match the zone name pattern", nameof(request.Name)); - if (!Enum.IsDefined(typeof(ZoneType), request.Type)) + if (request.Type.HasValue && !Enum.IsDefined(typeof(ZoneType), request.Type)) throw new ArgumentOutOfRangeException(nameof(request.Type)); - var req = new CreateRequest + var req = new InternalCreateZoneRequest(account: new AccountBase { Id = request.AccountId }, name: request.Name) { - Account = new AccountBase { Id = request.AccountId }, - Name = request.Name, Type = request.Type }; - return client.PostAsync("zones", req, cancellationToken: cancellationToken); + return client.PostAsync("zones", req, cancellationToken: cancellationToken); } /// @@ -96,7 +94,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (request.Type.HasValue && !Enum.IsDefined(typeof(ZoneType), request.Type.Value)) throw new ArgumentOutOfRangeException(nameof(request.Type)); - var req = new EditRequest(); + var req = new InternalEditZoneRequest(); if (request.Type.HasValue) req.Type = request.Type.Value; @@ -104,7 +102,7 @@ namespace AMWD.Net.Api.Cloudflare.Zones if (request.VanityNameServers != null) req.VanityNameServers = request.VanityNameServers.Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); - return client.PatchAsync($"zones/{request.Id}", req, cancellationToken); + return client.PatchAsync($"zones/{request.Id}", req, cancellationToken); } // Triggeres a new activation check for a PENDING Zone. This can be triggered every 5 min for paygo/ent customers, every hour for FREE Zones. diff --git a/Extensions/Cloudflare.Zones/Hold/ZoneHoldExtensions.cs b/Extensions/Cloudflare.Zones/ZoneHoldExtensions.cs similarity index 96% rename from Extensions/Cloudflare.Zones/Hold/ZoneHoldExtensions.cs rename to Extensions/Cloudflare.Zones/ZoneHoldExtensions.cs index 045ed00..99ad59d 100644 --- a/Extensions/Cloudflare.Zones/Hold/ZoneHoldExtensions.cs +++ b/Extensions/Cloudflare.Zones/ZoneHoldExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Filters; namespace AMWD.Net.Api.Cloudflare.Zones { diff --git a/Extensions/Directory.Build.props b/Extensions/Directory.Build.props index 63b103a..c648e7b 100644 --- a/Extensions/Directory.Build.props +++ b/Extensions/Directory.Build.props @@ -1,6 +1,7 @@ {semvertag:main}{!:-dev} + enable true false diff --git a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByHostTest.cs b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByHostTest.cs index d13e996..c9de5d8 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByHostTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByHostTest.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; -using AMWD.Net.Api.Cloudflare.Zones; -using Moq; using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; +using Moq; namespace Cloudflare.Zones.Tests.Cache { @@ -21,7 +20,7 @@ namespace Cloudflare.Zones.Tests.Cache private CloudflareResponse _response; - private List<(string RequestPath, PurgeRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; + private List<(string RequestPath, InternalPurgeCacheRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] public void Initialize() @@ -90,7 +89,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -111,8 +110,8 @@ namespace Cloudflare.Zones.Tests.Cache { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByPrefixTest.cs b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByPrefixTest.cs index cd41da1..d32b399 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByPrefixTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByPrefixTest.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; -using AMWD.Net.Api.Cloudflare.Zones; -using Moq; using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; +using Moq; namespace Cloudflare.Zones.Tests.Cache { @@ -21,7 +20,7 @@ namespace Cloudflare.Zones.Tests.Cache private CloudflareResponse _response; - private List<(string RequestPath, PurgeRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; + private List<(string RequestPath, InternalPurgeCacheRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] public void Initialize() @@ -93,7 +92,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -114,8 +113,8 @@ namespace Cloudflare.Zones.Tests.Cache { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByTagTest.cs b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByTagTest.cs index 8553221..0066041 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByTagTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByTagTest.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; -using AMWD.Net.Api.Cloudflare.Zones; -using Moq; using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; +using Moq; namespace Cloudflare.Zones.Tests.Cache { @@ -21,7 +20,7 @@ namespace Cloudflare.Zones.Tests.Cache private CloudflareResponse _response; - private List<(string RequestPath, PurgeRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; + private List<(string RequestPath, InternalPurgeCacheRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] public void Initialize() @@ -91,7 +90,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -112,8 +111,8 @@ namespace Cloudflare.Zones.Tests.Cache { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByUrlTest.cs b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByUrlTest.cs index ec37b41..2511cde 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByUrlTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentByUrlTest.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; -using AMWD.Net.Api.Cloudflare.Zones; -using Moq; using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; +using Moq; namespace Cloudflare.Zones.Tests.Cache { @@ -21,7 +20,7 @@ namespace Cloudflare.Zones.Tests.Cache private CloudflareResponse _response; - private List<(string RequestPath, PurgeRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; + private List<(string RequestPath, InternalPurgeCacheRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] public void Initialize() @@ -58,8 +57,8 @@ namespace Cloudflare.Zones.Tests.Cache // Arrange var list = new List { - new ZonePurgeCachedUrlRequest { Url = "https://example.com/foo.txt" }, - new ZonePurgeCachedUrlRequest { Url = "https://example.com/bar.baz" }, + new("https://example.com/foo.txt"), + new("https://example.com/bar.baz"), }; var client = GetClient(); @@ -90,7 +89,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -100,8 +99,8 @@ namespace Cloudflare.Zones.Tests.Cache // Arrange var list = new List { - new ZonePurgeCachedUrlRequest { Url = "https://example.com/foo.txt", Headers = new Dictionary { { "X-Test1", "Test" } } }, - new ZonePurgeCachedUrlRequest { Url = "https://example.com/bar.baz", Headers = new Dictionary { { "X-Test2", "Test" } } }, + new("https://example.com/foo.txt") { Headers = new Dictionary { { "X-Test1", "Test" } } }, + new("https://example.com/bar.baz") { Headers = new Dictionary { { "X-Test2", "Test" } } }, }; var client = GetClient(); @@ -134,7 +133,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -155,8 +154,8 @@ namespace Cloudflare.Zones.Tests.Cache { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentTest.cs b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentTest.cs index 6cc0dd1..6090570 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Cache/PurgeCachedContentTest.cs @@ -5,7 +5,7 @@ using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Zones; -using AMWD.Net.Api.Cloudflare.Zones.Cache.InternalRequests; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; using Moq; namespace Cloudflare.Zones.Tests.Cache @@ -20,7 +20,7 @@ namespace Cloudflare.Zones.Tests.Cache private CloudflareResponse _response; - private List<(string RequestPath, PurgeRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; + private List<(string RequestPath, InternalPurgeCacheRequest Request, IQueryParameterFilter QueryFilter)> _callbacks; [TestInitialize] public void Initialize() @@ -81,7 +81,7 @@ namespace Cloudflare.Zones.Tests.Cache Assert.IsNull(callback.QueryFilter); - _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync($"zones/{ZoneId}/purge_cache", It.IsAny(), null, It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -89,8 +89,8 @@ namespace Cloudflare.Zones.Tests.Cache { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, queryFilter, _) => _callbacks.Add((requestPath, request, queryFilter))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/DnsSettings/ShowDnsSettingsTest.cs b/UnitTests/Cloudflare.Zones.Tests/DnsSettings/ShowDnsSettingsTest.cs new file mode 100644 index 0000000..9e3bc7e --- /dev/null +++ b/UnitTests/Cloudflare.Zones.Tests/DnsSettings/ShowDnsSettingsTest.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using Moq; + +namespace Cloudflare.Zones.Tests.DnsSettings +{ + [TestClass] + public class ShowDnsSettingsTest + { + private const string ZoneId = "023e105f4ecef8ad9ca31a8372d0c353"; + + private Mock _clientMock; + + private CloudflareResponse _response; + + private List<(string RequestPath, IQueryParameterFilter QueryFilter)> _callbacks; + + [TestInitialize] + public void Initialize() + { + _callbacks = []; + + _response = new CloudflareResponse + { + Success = true, + Messages = [ + new ResponseInfo + { + Code = 1000, + Message = "Message 1", + } + ], + Errors = [ + new ResponseInfo + { + Code = 1000, + Message = "Error 1", + } + ], + Result = new ZoneDnsSetting + { + FlattenAllCnames = false, + FoundationDns = false, + MultiProvider = false, + Nameservers = new Nameserver + { + Type = NameserverType.CloudflareStandard, + }, + NameserverTtl = 86400, + SecondaryOverrides = false, + SOA = new StartOfAuthority + ( + expire: 604800, + minimumTtl: 1800, + primaryNameserver: "kristina.ns.cloudflare.com", + refresh: 10000, + retry: 2400, + zoneAdministrator: "admin.example.com", + ttl: 3600 + ), + Mode = ZoneMode.DnsOnly + } + }; + } + + [TestMethod] + public async Task ShouldGetDnsSetting() + { + // Arrange + var client = GetClient(); + + // Act + var response = await client.ShowZoneDnsSettings(ZoneId); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + Assert.AreEqual(_response?.Result, response.Result); + + Assert.AreEqual(1, _callbacks?.Count); + + var callback = _callbacks?.First(); + Assert.AreEqual($"zones/{ZoneId}/dns_settings", callback?.RequestPath); + + Assert.IsNull(callback?.QueryFilter); + + _clientMock?.Verify(m => m.GetAsync($"zones/{ZoneId}/dns_settings", null, It.IsAny()), Times.Once); + _clientMock?.VerifyNoOtherCalls(); + } + + private ICloudflareClient GetClient() + { + if (_response == null) throw new InvalidOperationException(); + + _clientMock = new Mock(); + _clientMock + .Setup(m => m.GetAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, queryFilter, _) => _callbacks?.Add((requestPath, queryFilter))) + .ReturnsAsync(() => _response); + + return _clientMock.Object; + } + } +} diff --git a/UnitTests/Cloudflare.Zones.Tests/DnsSettings/UpdateDnsSettingsTest.cs b/UnitTests/Cloudflare.Zones.Tests/DnsSettings/UpdateDnsSettingsTest.cs new file mode 100644 index 0000000..a98ae5e --- /dev/null +++ b/UnitTests/Cloudflare.Zones.Tests/DnsSettings/UpdateDnsSettingsTest.cs @@ -0,0 +1,355 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AMWD.Net.Api.Cloudflare; +using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; +using Moq; + +namespace Cloudflare.Zones.Tests.DnsSettings +{ + [TestClass] + public class UpdateDnsSettingsTest + { + private const string ZoneId = "023e105f4ecef8ad9ca31a8372d0c353"; + + private Mock _clientMock; + + private CloudflareResponse _response; + + private List<(string RequestPath, InternalUpdateDnsSettingsRequest Request)> _callbacks; + + private UpdateDnsSettingsRequest _request; + + [TestInitialize] + public void Initialize() + { + _callbacks = []; + + _response = new CloudflareResponse + { + Success = true, + Messages = [ + new ResponseInfo + { + Code = 1000, + Message = "Message 1", + } + ], + Errors = [ + new ResponseInfo + { + Code = 1000, + Message = "Error 1", + } + ], + Result = new ZoneDnsSetting + { + FlattenAllCnames = false, + FoundationDns = false, + MultiProvider = false, + Nameservers = new Nameserver + { + Type = NameserverType.CloudflareStandard, + }, + NameserverTtl = 86400, + SecondaryOverrides = false, + SOA = new StartOfAuthority + ( + expire: 604800, + minimumTtl: 1800, + primaryNameserver: "kristina.ns.cloudflare.com", + refresh: 10000, + retry: 2400, + zoneAdministrator: "admin.example.com", + ttl: 3600 + ), + Mode = ZoneMode.DnsOnly + } + }; + + _request = new UpdateDnsSettingsRequest(ZoneId) + { + FlattenAllCnames = true, + FoundationDns = false, + MultiProvider = false, + Nameservers = new Nameserver + { + Type = NameserverType.CloudflareRandom + }, + NameserverTtl = 86400, + SecondaryOverrides = false, + SOA = new StartOfAuthority + ( + expire: 604800, + minimumTtl: 1800, + primaryNameserver: "ns1.example.org", + refresh: 28800, + retry: 3600, + ttl: 43200, + zoneAdministrator: "admin.example.org" + ), + Mode = ZoneMode.Standard + }; + } + + [TestMethod] + public async Task ShouldUpdateDnsSettingsFull() + { + // Arrange + if (_request == null) throw new InvalidOperationException(); + var client = GetClient(); + + // Act + var response = await client.UpdateZoneDnsSettings(_request); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + Assert.AreEqual(_response?.Result, response.Result); + + Assert.AreEqual(1, _callbacks?.Count); + + var callback = _callbacks?.First(); + Assert.AreEqual($"zones/{ZoneId}/dns_settings", callback?.RequestPath); + + Assert.IsNotNull(callback?.Request); + Assert.IsTrue(callback?.Request.FlattenAllCnames); + Assert.IsFalse(callback?.Request.FoundationDns); + Assert.IsFalse(callback?.Request.MultiProvider); + Assert.IsNotNull(callback?.Request.Nameservers); + Assert.AreEqual(NameserverType.CloudflareRandom, callback?.Request.Nameservers.Type); + Assert.AreEqual(86400, callback?.Request.NameserverTtl); + Assert.IsFalse(callback?.Request.SecondaryOverrides); + Assert.IsNotNull(callback?.Request.Soa); + Assert.AreEqual(604800, callback?.Request.Soa.Expire); + Assert.AreEqual(1800, callback?.Request.Soa.MinimumTtl); + Assert.AreEqual("ns1.example.org", callback?.Request.Soa.PrimaryNameserver); + Assert.AreEqual(28800, callback?.Request.Soa.Refresh); + Assert.AreEqual(3600, callback?.Request.Soa.Retry); + Assert.AreEqual(43200, callback?.Request.Soa.Ttl); + Assert.AreEqual("admin.example.org", callback?.Request.Soa.ZoneAdministrator); + Assert.AreEqual(ZoneMode.Standard, callback?.Request.Mode); + + _clientMock?.Verify(m => m.PatchAsync($"zones/{ZoneId}/dns_settings", It.IsAny(), It.IsAny()), Times.Once); + _clientMock?.VerifyNoOtherCalls(); + } + + [TestMethod] + public async Task ShouldUpdateDnsSettingsNone() + { + // Arrange + var request = new UpdateDnsSettingsRequest(ZoneId); + var client = GetClient(); + + // Act + var response = await client.UpdateZoneDnsSettings(request); + + // Assert + Assert.IsNotNull(response); + Assert.IsTrue(response.Success); + Assert.AreEqual(_response?.Result, response.Result); + + Assert.AreEqual(1, _callbacks?.Count); + + var callback = _callbacks?.First(); + Assert.AreEqual($"zones/{ZoneId}/dns_settings", callback?.RequestPath); + + Assert.IsNotNull(callback?.Request); + Assert.IsNull(callback?.Request.FlattenAllCnames); + Assert.IsNull(callback?.Request.FoundationDns); + Assert.IsNull(callback?.Request.MultiProvider); + Assert.IsNull(callback?.Request.Nameservers); + Assert.IsNull(callback?.Request.NameserverTtl); + Assert.IsNull(callback?.Request.SecondaryOverrides); + Assert.IsNull(callback?.Request.Soa); + Assert.IsNull(callback?.Request.Mode); + + _clientMock?.Verify(m => m.PatchAsync($"zones/{ZoneId}/dns_settings", It.IsAny(), It.IsAny()), Times.Once); + _clientMock?.VerifyNoOtherCalls(); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidMode() + { + // Arrange + if (_request == null) throw new InvalidOperationException(); + _request.Mode = 0; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [TestMethod] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidNameserverType() + { + // Arrange + if (_request == null || _request.Nameservers == null) throw new InvalidOperationException(); + _request.Nameservers.Type = 0; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(29)] + [DataRow(86401)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidNameserverTtl(int ttl) + { + // Arrange + if (_request == null) throw new InvalidOperationException(); + _request.NameserverTtl = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(86399)] + [DataRow(2419201)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidSoaExpire(int ttl) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.Expire = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(59)] + [DataRow(86401)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidSoaMinimumTtl(int ttl) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.MinimumTtl = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(null)] + [DataRow("")] + [DataRow(" ")] + [ExpectedException(typeof(ArgumentNullException))] + public async Task ShouldThrowArgumentNullExceptionForMissingSoaNameserver(string nameserver) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.PrimaryNameserver = nameserver; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentNullException + } + + [DataTestMethod] + [DataRow(599)] + [DataRow(86401)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidSoaRefresh(int ttl) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.Refresh = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(599)] + [DataRow(86401)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidSoaRetry(int ttl) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.Retry = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(299)] + [DataRow(86401)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public async Task ShouldThrowArgumentOutOfRangeExceptionForInvalidSoaTtl(int ttl) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.Ttl = ttl; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentOutOfRangeException + } + + [DataTestMethod] + [DataRow(null)] + [DataRow("")] + [DataRow(" ")] + [ExpectedException(typeof(ArgumentNullException))] + public async Task ShouldThrowArgumentNullExceptionForMissingSoaAdministrator(string admin) + { + // Arrange + if (_request == null || _request.SOA == null) throw new InvalidOperationException(); + _request.SOA.ZoneAdministrator = admin; + var client = GetClient(); + + // Act + await client.UpdateZoneDnsSettings(_request); + + // Assert - ArgumentNullException + } + + private ICloudflareClient GetClient() + { + if (_response == null) throw new InvalidOperationException(); + + _clientMock = new Mock(); + _clientMock + .Setup(m => m.PatchAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, _) => _callbacks?.Add((requestPath, request))) + .ReturnsAsync(() => _response); + + return _clientMock.Object; + } + } +} diff --git a/UnitTests/Cloudflare.Zones.Tests/Hold/CreateZoneHoldTest.cs b/UnitTests/Cloudflare.Zones.Tests/Hold/CreateZoneHoldTest.cs index 9bab423..004e7de 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Hold/CreateZoneHoldTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Hold/CreateZoneHoldTest.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Filters; using Moq; namespace Cloudflare.Zones.Tests.Hold @@ -12,8 +13,8 @@ namespace Cloudflare.Zones.Tests.Hold [TestClass] public class CreateZoneHoldTest { + private readonly DateTime _date = new(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private const string ZoneId = "023e105f4ecef8ad9ca31a8372d0c353"; - private readonly DateTime DateTime = new(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private Mock _clientMock; @@ -46,7 +47,7 @@ namespace Cloudflare.Zones.Tests.Hold Result = new ZoneHold { Hold = true, - HoldAfter = DateTime, + HoldAfter = _date, IncludeSubdomains = "true" } }; diff --git a/UnitTests/Cloudflare.Zones.Tests/Hold/DeleteZoneHoldTest.cs b/UnitTests/Cloudflare.Zones.Tests/Hold/DeleteZoneHoldTest.cs index 6a9b911..cc291a2 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Hold/DeleteZoneHoldTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Hold/DeleteZoneHoldTest.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Zones; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Filters; using Moq; namespace Cloudflare.Zones.Tests.Hold @@ -12,8 +13,8 @@ namespace Cloudflare.Zones.Tests.Hold [TestClass] public class DeleteZoneHoldTest { + private readonly DateTime _date = new(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private const string ZoneId = "023e105f4ecef8ad9ca31a8372d0c353"; - private readonly DateTime Date = new(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private Mock _clientMock; @@ -46,7 +47,7 @@ namespace Cloudflare.Zones.Tests.Hold Result = new ZoneHold { Hold = true, - HoldAfter = Date, + HoldAfter = _date, IncludeSubdomains = "true" } }; @@ -86,7 +87,7 @@ namespace Cloudflare.Zones.Tests.Hold var client = GetClient(); // Act - var response = await client.DeleteZoneHold(ZoneId, holdAfter: Date); + var response = await client.DeleteZoneHold(ZoneId, holdAfter: _date); // Assert Assert.IsNotNull(response); @@ -100,7 +101,7 @@ namespace Cloudflare.Zones.Tests.Hold Assert.IsNotNull(callback.QueryFilter); Assert.IsInstanceOfType(callback.QueryFilter); - Assert.AreEqual(Date, ((DeleteZoneHoldFilter)callback.QueryFilter).HoldAfter); + Assert.AreEqual(_date, ((DeleteZoneHoldFilter)callback.QueryFilter).HoldAfter); _clientMock.Verify(m => m.DeleteAsync($"zones/{ZoneId}/hold", It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); @@ -124,7 +125,7 @@ namespace Cloudflare.Zones.Tests.Hold public void ShouldReturnQueryParameter() { // Arrange - var filter = new DeleteZoneHoldFilter { HoldAfter = Date }; + var filter = new DeleteZoneHoldFilter { HoldAfter = _date }; // Act var dict = filter.GetQueryParameters(); diff --git a/UnitTests/Cloudflare.Zones.Tests/Hold/GetZoneHoldTest.cs b/UnitTests/Cloudflare.Zones.Tests/Hold/GetZoneHoldTest.cs index 6232e21..99a1f13 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Hold/GetZoneHoldTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Hold/GetZoneHoldTest.cs @@ -12,8 +12,8 @@ namespace Cloudflare.Zones.Tests.Hold [TestClass] public class GetZoneHoldTest { + private readonly DateTime _date = new DateTime(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private const string ZoneId = "023e105f4ecef8ad9ca31a8372d0c353"; - private readonly DateTime DateTime = new DateTime(2024, 10, 10, 20, 30, 40, 0, DateTimeKind.Utc); private Mock _clientMock; @@ -46,7 +46,7 @@ namespace Cloudflare.Zones.Tests.Hold Result = new ZoneHold { Hold = true, - HoldAfter = DateTime, + HoldAfter = _date, IncludeSubdomains = "false" } }; diff --git a/UnitTests/Cloudflare.Zones.Tests/Zones/CreateZoneTest.cs b/UnitTests/Cloudflare.Zones.Tests/Zones/CreateZoneTest.cs index 6ea9077..12f0720 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Zones/CreateZoneTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Zones/CreateZoneTest.cs @@ -5,7 +5,7 @@ using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Zones; -using AMWD.Net.Api.Cloudflare.Zones.Zones.InternalRequests; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; using Moq; namespace Cloudflare.Zones.Tests.Zones @@ -19,7 +19,7 @@ namespace Cloudflare.Zones.Tests.Zones private CloudflareResponse _response; - private List<(string RequestPath, CreateRequest Request)> _callbacks; + private List<(string RequestPath, InternalCreateZoneRequest Request)> _callbacks; private CreateZoneRequest _request; @@ -47,7 +47,7 @@ namespace Cloudflare.Zones.Tests.Zones ], Result = new Zone { - Id = "023e105f4ecef8ad9ca31a8372d0c353", + Id = ZoneId, Account = new AccountBase { Id = "023e105f4ecef8ad9ca31a8372d0c353", @@ -97,18 +97,16 @@ namespace Cloudflare.Zones.Tests.Zones } }; - _request = new CreateZoneRequest - { - AccountId = "023e105f4ecef8ad9ca31a8372d0c353", - Name = "example.com", - Type = ZoneType.Full - }; + _request = new CreateZoneRequest("023e105f4ecef8ad9ca31a8372d0c353", "example.com"); } - [TestMethod] - public async Task ShouldReturnCreatedZone() + [DataTestMethod] + [DataRow(null)] + [DataRow(ZoneType.Full)] + public async Task ShouldReturnCreatedZone(ZoneType? type) { // Arrange + _request.Type = type; var client = GetClient(); // Act @@ -129,7 +127,7 @@ namespace Cloudflare.Zones.Tests.Zones Assert.AreEqual(_request.Name, callback.Request.Name); Assert.AreEqual(_request.Type, callback.Request.Type); - _clientMock.Verify(m => m.PostAsync("zones", It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PostAsync("zones", It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -182,8 +180,8 @@ namespace Cloudflare.Zones.Tests.Zones { _clientMock = new Mock(); _clientMock - .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, _, _) => _callbacks.Add((requestPath, request))) + .Setup(m => m.PostAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, _, _) => _callbacks.Add((requestPath, request))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Zones/EditZoneTest.cs b/UnitTests/Cloudflare.Zones.Tests/Zones/EditZoneTest.cs index 170237e..b06aeed 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Zones/EditZoneTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Zones/EditZoneTest.cs @@ -5,7 +5,7 @@ using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; using AMWD.Net.Api.Cloudflare.Zones; -using AMWD.Net.Api.Cloudflare.Zones.Zones.InternalRequests; +using AMWD.Net.Api.Cloudflare.Zones.Internals.Requests; using Moq; namespace Cloudflare.Zones.Tests.Zones @@ -19,7 +19,7 @@ namespace Cloudflare.Zones.Tests.Zones private CloudflareResponse _response; - private List<(string RequestPath, EditRequest Request)> _callbacks; + private List<(string RequestPath, InternalEditZoneRequest Request)> _callbacks; private EditZoneRequest _request; @@ -97,9 +97,8 @@ namespace Cloudflare.Zones.Tests.Zones } }; - _request = new EditZoneRequest + _request = new EditZoneRequest(ZoneId) { - Id = ZoneId, Type = ZoneType.Full, VanityNameServers = ["ns1.example.org", "ns2.example.org"] }; @@ -129,7 +128,7 @@ namespace Cloudflare.Zones.Tests.Zones Assert.AreEqual(_request.Type.Value, callback.Request.Type.Value); Assert.IsNull(callback.Request.VanityNameServers); - _clientMock.Verify(m => m.PatchAsync($"zones/{ZoneId}", It.IsAny(), It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PatchAsync($"zones/{ZoneId}", It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -160,7 +159,7 @@ namespace Cloudflare.Zones.Tests.Zones Assert.IsTrue(callback.Request.VanityNameServers.Contains("ns1.example.org")); Assert.IsTrue(callback.Request.VanityNameServers.Contains("ns2.example.org")); - _clientMock.Verify(m => m.PatchAsync($"zones/{ZoneId}", It.IsAny(), It.IsAny()), Times.Once); + _clientMock.Verify(m => m.PatchAsync($"zones/{ZoneId}", It.IsAny(), It.IsAny()), Times.Once); _clientMock.VerifyNoOtherCalls(); } @@ -196,8 +195,8 @@ namespace Cloudflare.Zones.Tests.Zones { _clientMock = new Mock(); _clientMock - .Setup(m => m.PatchAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((requestPath, request, _) => _callbacks.Add((requestPath, request))) + .Setup(m => m.PatchAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((requestPath, request, _) => _callbacks.Add((requestPath, request))) .ReturnsAsync(() => _response); return _clientMock.Object; diff --git a/UnitTests/Cloudflare.Zones.Tests/Zones/ListZonesTest.cs b/UnitTests/Cloudflare.Zones.Tests/Zones/ListZonesTest.cs index c433a6e..8f8ece8 100644 --- a/UnitTests/Cloudflare.Zones.Tests/Zones/ListZonesTest.cs +++ b/UnitTests/Cloudflare.Zones.Tests/Zones/ListZonesTest.cs @@ -178,12 +178,12 @@ namespace Cloudflare.Zones.Tests.Zones { AccountId = "023e105f4ecef8ad9ca31a8372d0c353", AccountName = "Example Account Name", - MatchType = FilterMatchType.Any, + Match = FilterMatchType.Any, Name = "example.com", PerPage = 13, Page = 5, OrderBy = ZonesOrderBy.AccountName, - OrderDirection = SortDirection.Descending, + Direction = SortDirection.Descending, Status = ZoneStatus.Active }; @@ -261,7 +261,7 @@ namespace Cloudflare.Zones.Tests.Zones // Arrange var filter = new ListZonesFilter { - OrderDirection = 0 + Direction = 0 }; // Act @@ -278,7 +278,7 @@ namespace Cloudflare.Zones.Tests.Zones // Arrange var filter = new ListZonesFilter { - MatchType = 0 + Match = 0 }; // Act