예제 #1
0
        public async Task ValidateReverseDnsAsync()
        {
            // Arrange
            var id = 1L;

            var apiResponse = @"{
				""id"": 1,
				""valid"": true,
				""validation_results"": {
					""a_record"": {
						""valid"": true,
						""reason"": null
					}
				}
			}"            ;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, "ips", id, "validate")).Respond("application/json", apiResponse);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.ValidateReverseDnsAsync(id).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
            result.IpId.ShouldBe(1);
            result.IsValid.ShouldBe(true);
            result.ValidationResults.ARecord.IsValid.ShouldBe(true);
            result.ValidationResults.ARecord.Reason.ShouldBeNull();
        }
예제 #2
0
파일: Client.cs 프로젝트: xhanix/StrongGrid
        private Client(string apiKey, string username, string password, HttpClient httpClient, bool disposeClient, StrongGridClientOptions options)
        {
            _mustDisposeHttpClient = disposeClient;
            _httpClient            = httpClient;
            _options = options ?? GetDefaultOptions();

            _fluentClient = new FluentClient(new Uri(SENDGRID_V3_BASE_URI), httpClient)
                            .SetUserAgent(Client.UserAgent)
                            .SetRequestCoordinator(new SendGridRetryStrategy());

            _fluentClient.Filters.Remove <DefaultErrorFilter>();

            // Order is important: DiagnosticHandler must be first.
            // Also, the list of filters must be kept in sync with the filters in Utils.GetFluentClient in the unit testing project.
            _fluentClient.Filters.Add(new DiagnosticHandler(_options.LogLevelSuccessfulCalls, _options.LogLevelFailedCalls));
            _fluentClient.Filters.Add(new SendGridErrorHandler());

            if (!string.IsNullOrEmpty(apiKey))
            {
                _fluentClient.SetBearerAuthentication(apiKey);
            }
            if (!string.IsNullOrEmpty(username))
            {
                _fluentClient.SetBasicAuthentication(username, password);
            }

            AccessManagement   = new AccessManagement(_fluentClient);
            Alerts             = new Alerts(_fluentClient);
            ApiKeys            = new ApiKeys(_fluentClient);
            Batches            = new Batches(_fluentClient);
            Blocks             = new Blocks(_fluentClient);
            Bounces            = new Bounces(_fluentClient);
            Campaigns          = new Campaigns(_fluentClient);
            Categories         = new Categories(_fluentClient);
            Contacts           = new Contacts(_fluentClient);
            CustomFields       = new CustomFields(_fluentClient);
            Designs            = new Designs(_fluentClient);
            EmailActivities    = new EmailActivities(_fluentClient);
            EmailValidation    = new EmailValidation(_fluentClient);
            GlobalSuppressions = new GlobalSuppressions(_fluentClient);
            InvalidEmails      = new InvalidEmails(_fluentClient);
            IpAddresses        = new IpAddresses(_fluentClient);
            IpPools            = new IpPools(_fluentClient);
            Lists                = new Lists(_fluentClient);
            Mail                 = new Mail(_fluentClient);
            Segments             = new Segments(_fluentClient);
            SenderIdentities     = new SenderIdentities(_fluentClient);
            Settings             = new Settings(_fluentClient);
            SpamReports          = new SpamReports(_fluentClient);
            Statistics           = new Statistics(_fluentClient);
            Subusers             = new Subusers(_fluentClient);
            Suppressions         = new Suppressions(_fluentClient);
            Teammates            = new Teammates(_fluentClient);
            Templates            = new Templates(_fluentClient);
            UnsubscribeGroups    = new UnsubscribeGroups(_fluentClient);
            User                 = new User(_fluentClient);
            WebhookSettings      = new WebhookSettings(_fluentClient);
            WebhookStats         = new WebhookStats(_fluentClient);
            SenderAuthentication = new SenderAuthentication(_fluentClient);
        }
예제 #3
0
        public async Task CreateDomainAsync()
        {
            // Arrange
            var domain             = "";
            var subdomain          = "";
            var username           = "";
            var ips                = Array.Empty <string>();
            var automaticSecurity  = true;
            var customSpf          = false;
            var isDefault          = true;
            var customDkimSelector = "";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, "domains")).Respond("application/json", SINGLE_DOMAIN_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.CreateDomainAsync(domain, subdomain, username, ips, automaticSecurity, customSpf, isDefault, customDkimSelector, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #4
0
        private Client(string apiKey, string username, string password, string baseUri, string apiVersion, HttpClient httpClient)
        {
            _mustDisposeHttpClient = httpClient == null;
            _httpClient            = httpClient;

            Version = typeof(Client).GetTypeInfo().Assembly.GetName().Version.ToString(3);
#if DEBUG
            Version = "DEBUG";
#endif

            _fluentClient = new FluentClient(new Uri($"{baseUri.TrimEnd('/')}/{apiVersion.TrimStart('/')}"), httpClient)
                            .SetUserAgent($"StrongGrid/{Version} (+https://github.com/Jericho/StrongGrid)")
                            .SetRequestCoordinator(new SendGridRetryStrategy());

            _fluentClient.Filters.Remove <DefaultErrorFilter>();
            _fluentClient.Filters.Add(new DiagnosticHandler());
            _fluentClient.Filters.Add(new SendGridErrorHandler());

            if (!string.IsNullOrEmpty(apiKey))
            {
                _fluentClient.SetBearerAuthentication(apiKey);
            }
            if (!string.IsNullOrEmpty(username))
            {
                _fluentClient.SetBasicAuthentication(username, password);
            }

            AccessManagement   = new AccessManagement(_fluentClient);
            Alerts             = new Alerts(_fluentClient);
            ApiKeys            = new ApiKeys(_fluentClient);
            Batches            = new Batches(_fluentClient);
            Blocks             = new Blocks(_fluentClient);
            Bounces            = new Bounces(_fluentClient);
            Campaigns          = new Campaigns(_fluentClient);
            Categories         = new Categories(_fluentClient);
            Contacts           = new Contacts(_fluentClient);
            CustomFields       = new CustomFields(_fluentClient);
            EmailActivities    = new EmailActivities(_fluentClient);
            GlobalSuppressions = new GlobalSuppressions(_fluentClient);
            InvalidEmails      = new InvalidEmails(_fluentClient);
            IpAddresses        = new IpAddresses(_fluentClient);
            IpPools            = new IpPools(_fluentClient);
            Lists                = new Lists(_fluentClient);
            Mail                 = new Mail(_fluentClient);
            Segments             = new Segments(_fluentClient);
            SenderIdentities     = new SenderIdentities(_fluentClient);
            Settings             = new Settings(_fluentClient);
            SpamReports          = new SpamReports(_fluentClient);
            Statistics           = new Statistics(_fluentClient);
            Subusers             = new Subusers(_fluentClient);
            Suppressions         = new Suppressions(_fluentClient);
            Teammates            = new Teammates(_fluentClient);
            Templates            = new Templates(_fluentClient);
            UnsubscribeGroups    = new UnsubscribeGroups(_fluentClient);
            User                 = new User(_fluentClient);
            WebhookSettings      = new WebhookSettings(_fluentClient);
            WebhookStats         = new WebhookStats(_fluentClient);
            SenderAuthentication = new SenderAuthentication(_fluentClient);
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseClient" /> class.
        /// </summary>
        /// <param name="apiKey">Your api key.</param>
        /// <param name="httpClient">Allows you to inject your own HttpClient. This is useful, for example, to setup the HtppClient with a proxy.</param>
        /// <param name="disposeClient">Indicates if the http client should be dispose when this instance of BaseClient is disposed.</param>
        /// <param name="options">Options for the SendGrid client.</param>
        /// <param name="logger">Logger.</param>
        public BaseClient(string apiKey, HttpClient httpClient, bool disposeClient, StrongGridClientOptions options, ILogger logger = null)
        {
            _mustDisposeHttpClient = disposeClient;
            _httpClient            = httpClient;
            _options = options;
            _logger  = logger ?? NullLogger.Instance;

            _fluentClient = new FluentClient(new Uri(SENDGRID_V3_BASE_URI), httpClient)
                            .SetUserAgent($"StrongGrid/{Version} (+https://github.com/Jericho/StrongGrid)")
                            .SetRequestCoordinator(new SendGridRetryStrategy());

            _fluentClient.Filters.Remove <DefaultErrorFilter>();

            // Remove all the built-in formatters and replace them with our custom JSON formatter
            _fluentClient.Formatters.Clear();
            _fluentClient.Formatters.Add(new JsonFormatter());

            // Order is important: DiagnosticHandler must be first.
            // Also, the list of filters must be kept in sync with the filters in Utils.GetFluentClient in the unit testing project.
            _fluentClient.Filters.Add(new DiagnosticHandler(_options.LogLevelSuccessfulCalls, _options.LogLevelFailedCalls, _logger));
            _fluentClient.Filters.Add(new SendGridErrorHandler());

            if (string.IsNullOrEmpty(apiKey))
            {
                throw new ArgumentNullException(apiKey);
            }
            _fluentClient.SetBearerAuthentication(apiKey);

            AccessManagement   = new AccessManagement(FluentClient);
            Alerts             = new Alerts(FluentClient);
            ApiKeys            = new ApiKeys(FluentClient);
            Batches            = new Batches(FluentClient);
            Blocks             = new Blocks(FluentClient);
            Bounces            = new Bounces(FluentClient);
            Designs            = new Designs(FluentClient);
            EmailActivities    = new EmailActivities(FluentClient);
            EmailValidation    = new EmailValidation(FluentClient);
            GlobalSuppressions = new GlobalSuppressions(FluentClient);
            InvalidEmails      = new InvalidEmails(FluentClient);
            IpAddresses        = new IpAddresses(FluentClient);
            IpPools            = new IpPools(FluentClient);
            Mail                 = new Mail(FluentClient);
            Settings             = new Settings(FluentClient);
            SpamReports          = new SpamReports(FluentClient);
            Statistics           = new Statistics(FluentClient);
            Subusers             = new Subusers(FluentClient);
            Suppressions         = new Suppressions(FluentClient);
            Teammates            = new Teammates(FluentClient);
            Templates            = new Templates(FluentClient);
            UnsubscribeGroups    = new UnsubscribeGroups(FluentClient);
            User                 = new User(FluentClient);
            WebhookSettings      = new WebhookSettings(FluentClient);
            WebhookStats         = new WebhookStats(FluentClient);
            SenderAuthentication = new SenderAuthentication(FluentClient);
        }
예제 #6
0
        public async Task ValidateDomainAsync()
        {
            // Arrange
            var domainId = 1L;

            var apiResponse = @"{
				""id"": 1,
				""valid"": true,
				""validation_results"": {
					""mail_cname"": {
						""valid"": false,
						""reason"": ""Expected your MX record to be \""mx.sendgrid.net\"" but found \""example.com\"".""
					},
					""dkim1"": {
						""valid"": true,
						""reason"": null
					},
					""dkim2"": {
						""valid"": true,
						""reason"": null
					},
					""spf"": {
						""valid"": true,
						""reason"": null
					}
				}
			}"            ;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, $"domains/{domainId}/validate")).Respond("application/json", apiResponse);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.ValidateDomainAsync(domainId).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
            result.DomainId.ShouldBe(1);
            result.IsValid.ShouldBe(true);
            result.ValidationResults.Dkim1.IsValid.ShouldBe(true);
            result.ValidationResults.Dkim1.Reason.ShouldBeNull();
            result.ValidationResults.Dkim2.IsValid.ShouldBe(true);
            result.ValidationResults.Dkim2.Reason.ShouldBeNull();
            result.ValidationResults.Mail.IsValid.ShouldBe(false);
            result.ValidationResults.Mail.Reason.ShouldBe("Expected your MX record to be \"mx.sendgrid.net\" but found \"example.com\".");
            result.ValidationResults.Spf.IsValid.ShouldBe(true);
            result.ValidationResults.Spf.Reason.ShouldBeNull();
        }
예제 #7
0
        public async Task DisassociateLinkAsync()
        {
            // Arrange
            var username = "******";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Delete, Utils.GetSendGridApiUri(ENDPOINT, $"links/subuser?username={username}")).Respond(HttpStatusCode.OK);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            await senderAuthentication.DisassociateLinkAsync(username, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
        }
예제 #8
0
        public async Task DeleteLinkAsync()
        {
            // Arrange
            var linkId = 48L;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Delete, Utils.GetSendGridApiUri(ENDPOINT, "links", linkId)).Respond(HttpStatusCode.OK);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            await senderAuthentication.DeleteLinkAsync(linkId, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
        }
        public async Task GetAllDomainsAsync_exclude_subusers()
        {
            // Arrange
            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Get, Utils.GetSendGridApiUri(ENDPOINT, "domains?exclude_subusers=true&limit=50&offset=0&username=&domain=")).Respond("application/json", MULTIPLE_DOMAINS_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.GetAllDomainsAsync(excludeSubusers : true).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
            result.Length.ShouldBe(2);
        }
예제 #10
0
        public async Task GetAllLinksAsync()
        {
            // Arrange
            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Get, Utils.GetSendGridApiUri(ENDPOINT, "links?limit=50&offset=0")).Respond("application/json", MULTIPLE_LINKS_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.GetAllLinksAsync().ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
            result.Length.ShouldBe(2);
        }
예제 #11
0
        public async Task GetAssociatedLinkAsync()
        {
            // Arrange
            var username = "******";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Get, Utils.GetSendGridApiUri(ENDPOINT, $"links/subuser?username={username}")).Respond("application/json", SINGLE_LINK_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.GetAssociatedLinkAsync(username, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #12
0
        public async Task GetDefaultLinkAsync()
        {
            // Arrange
            var domain = "example.com";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Get, Utils.GetSendGridApiUri(ENDPOINT, $"links/default?domain={domain}")).Respond("application/json", SINGLE_LINK_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.GetDefaultLinkAsync(domain).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #13
0
        public async Task GetReverseDnsAsync()
        {
            // Arrange
            var id = 123L;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Get, Utils.GetSendGridApiUri(ENDPOINT, $"ips/{id}")).Respond("application/json", SINGLE_IP_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.GetReverseDnsAsync(id).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #14
0
        public async Task ValidateLinkAsync()
        {
            // Arrange
            var linkId = 1L;

            var apiResponse = @"{
				""id"": 1,
				""valid"": true,
				""validation_results"": {
					""domain_cname"": {
						""valid"": false,
						""reason"": ""Expected CNAME to match \""sendgrid.net.\"" but found \""example.com.\"".""
					},
					""owner_cname"": {
						""valid"": true,
						""reason"": null
					}
				}
			}"            ;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, "links", linkId, "validate")).Respond("application/json", apiResponse);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.ValidateLinkAsync(linkId).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
            result.LinkId.ShouldBe(1);
            result.IsValid.ShouldBe(true);
            result.ValidationResults.Domain.IsValid.ShouldBe(false);
            result.ValidationResults.Domain.Reason.ShouldBe("Expected CNAME to match \"sendgrid.net.\" but found \"example.com.\".");
            result.ValidationResults.Owner.IsValid.ShouldBe(true);
            result.ValidationResults.Owner.Reason.ShouldBeNull();
        }
예제 #15
0
        public async Task UpdateLinkAsync()
        {
            // Arrange
            var linkId    = 123L;
            var isDefault = true;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(new HttpMethod("PATCH"), Utils.GetSendGridApiUri(ENDPOINT, "links", linkId)).Respond("application/json", SINGLE_LINK_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.UpdateLinkAsync(linkId, isDefault).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #16
0
        public async Task AssociateDomainAsync()
        {
            // Arrange
            var domainId  = 123L;
            var ipAddress = "192.168.77.1";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, $"domains/{domainId}/subuser")).Respond("application/json", SINGLE_DOMAIN_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.AssociateDomainAsync(domainId, ipAddress, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #17
0
        public async Task SetupReverseDnsAsync()
        {
            // Arrange
            var ipAddress = "192.168.77.1";
            var domain    = "example.com";
            var subdomain = "mail";

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, "ips")).Respond("application/json", SINGLE_IP_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.SetupReverseDnsAsync(ipAddress, domain, subdomain, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #18
0
        public async Task UpdateDomainAsync()
        {
            // Arrange
            var domainId  = 123L;
            var customSpf = true;
            var isDefault = false;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(new HttpMethod("PATCH"), Utils.GetSendGridApiUri(ENDPOINT, $"domains/{domainId}")).Respond("application/json", SINGLE_DOMAIN_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.UpdateDomainAsync(domainId, isDefault, customSpf, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #19
0
        public async Task CreateLinkAsync()
        {
            // Arrange
            var domain    = "example.com";
            var subdomain = "mail";
            var isDefault = false;

            var mockHttp = new MockHttpMessageHandler();

            mockHttp.Expect(HttpMethod.Post, Utils.GetSendGridApiUri(ENDPOINT, "links")).Respond("application/json", SINGLE_LINK_JSON);

            var client = Utils.GetFluentClient(mockHttp);
            var senderAuthentication = new SenderAuthentication(client);

            // Act
            var result = await senderAuthentication.CreateLinkAsync(domain, subdomain, isDefault, null, CancellationToken.None).ConfigureAwait(false);

            // Assert
            mockHttp.VerifyNoOutstandingExpectation();
            mockHttp.VerifyNoOutstandingRequest();
            result.ShouldNotBeNull();
        }
예제 #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseClient" /> class.
        /// </summary>
        /// <param name="apiKey">Your api key.</param>
        /// <param name="username">Your username. Ignored if the api key is specified.</param>
        /// <param name="password">Your password. Ignored if the api key is specified.</param>
        /// <param name="httpClient">Allows you to inject your own HttpClient. This is useful, for example, to setup the HtppClient with a proxy.</param>
        /// <param name="disposeClient">Indicates if the http client should be dispose when this instance of BaseClient is disposed.</param>
        /// <param name="options">Options for the SendGrid client.</param>
        /// <param name="logger">Logger.</param>
        public BaseClient(Parameter <string> apiKey, Parameter <string> username, Parameter <string> password, HttpClient httpClient, bool disposeClient, StrongGridClientOptions options, ILogger logger = null)
        {
            _mustDisposeHttpClient = disposeClient;
            _httpClient            = httpClient;
            _options = options ?? GetDefaultOptions();
            _logger  = logger ?? NullLogger.Instance;

            _fluentClient = new FluentClient(new Uri(SENDGRID_V3_BASE_URI), httpClient)
                            .SetUserAgent($"StrongGrid/{Version} (+https://github.com/Jericho/StrongGrid)")
                            .SetRequestCoordinator(new SendGridRetryStrategy());

            _fluentClient.Filters.Remove <DefaultErrorFilter>();

            // Order is important: DiagnosticHandler must be first.
            // Also, the list of filters must be kept in sync with the filters in Utils.GetFluentClient in the unit testing project.
            _fluentClient.Filters.Add(new DiagnosticHandler(_options.LogLevelSuccessfulCalls, _options.LogLevelFailedCalls, _logger));
            _fluentClient.Filters.Add(new SendGridErrorHandler());

            if (apiKey.HasValue)
            {
                if (string.IsNullOrEmpty(apiKey))
                {
                    throw new ArgumentNullException(apiKey);
                }
                else
                {
                    _fluentClient.SetBearerAuthentication(apiKey);
                }
            }
            else if (username.HasValue)
            {
                if (string.IsNullOrEmpty(username))
                {
                    throw new ArgumentNullException(username);
                }
                else
                {
                    _fluentClient.SetBasicAuthentication(username, password);
                }
            }
            else
            {
                throw new ArgumentException("You must provide either an API key or a username and a password.");
            }

            AccessManagement   = new AccessManagement(FluentClient);
            Alerts             = new Alerts(FluentClient);
            ApiKeys            = new ApiKeys(FluentClient);
            Batches            = new Batches(FluentClient);
            Blocks             = new Blocks(FluentClient);
            Bounces            = new Bounces(FluentClient);
            Designs            = new Designs(FluentClient);
            EmailActivities    = new EmailActivities(FluentClient);
            EmailValidation    = new EmailValidation(FluentClient);
            GlobalSuppressions = new GlobalSuppressions(FluentClient);
            InvalidEmails      = new InvalidEmails(FluentClient);
            IpAddresses        = new IpAddresses(FluentClient);
            IpPools            = new IpPools(FluentClient);
            Mail                 = new Mail(FluentClient);
            Settings             = new Settings(FluentClient);
            SpamReports          = new SpamReports(FluentClient);
            Statistics           = new Statistics(FluentClient);
            Subusers             = new Subusers(FluentClient);
            Suppressions         = new Suppressions(FluentClient);
            Teammates            = new Teammates(FluentClient);
            Templates            = new Templates(FluentClient);
            UnsubscribeGroups    = new UnsubscribeGroups(FluentClient);
            User                 = new User(FluentClient);
            WebhookSettings      = new WebhookSettings(FluentClient);
            WebhookStats         = new WebhookStats(FluentClient);
            SenderAuthentication = new SenderAuthentication(FluentClient);
        }