Skip to content

Commit

Permalink
Merge branch 'release/0.87.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Jan 18, 2022
2 parents 8f6957d + cad9a3d commit 87f1138
Show file tree
Hide file tree
Showing 274 changed files with 4,831 additions and 5,168 deletions.
1 change: 1 addition & 0 deletions GitReleaseManager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ issue-labels-include:
- Bug
- New Feature
- Improvement
- Enhancement
- Documentation
- Security
issue-labels-exclude:
Expand Down
105 changes: 105 additions & 0 deletions Source/StrongGrid.Benchmark/JsonParsingBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using BenchmarkDotNet.Attributes;
using RichardSzalay.MockHttp;
using StrongGrid.Models;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace StrongGrid.Benchmark
{
[MemoryDiagnoser]
[HtmlExporter]
[MarkdownExporterAttribute.GitHub]
public class JsonParsingBenchmark
{
private const int limit = 100;
private const int offset = 0;
private const int recordsPerPage = 25;
private const int page = 1;

private static Client _client;
private static LegacyClient _legacyClient;

public JsonParsingBenchmark()
{
var mockHttp = GetMockHttpMessageHandler();
_client = new Client("my API key", mockHttp, null, null);
_legacyClient = new LegacyClient("my API key", mockHttp, null, null);
}

[Benchmark]
public async Task SystemTextJson6()
{
var whitelistedIpAddresses = await _client.AccessManagement.GetWhitelistedIpAddressesAsync(null, CancellationToken.None).ConfigureAwait(false);
var accessHistory = await _client.AccessManagement.GetAccessHistoryAsync(20, null, CancellationToken.None).ConfigureAwait(false);
var alerts = await _client.Alerts.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
var apiKeys = await _client.ApiKeys.GetAllAsync(limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var batches = await _client.Batches.GetAllAsync().ConfigureAwait(false);
var blocks = await _client.Blocks.GetAllAsync(null, null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var bounces = await _client.Bounces.GetAsync("[email protected]", null, CancellationToken.None).ConfigureAwait(false);
var legacyCampaigns = await _legacyClient.Campaigns.GetAllAsync(limit, offset, CancellationToken.None).ConfigureAwait(false);
var designs = await _client.Designs.GetAllAsync(recordsPerPage, null, CancellationToken.None).ConfigureAwait(false);
var emailActivities = await _client.EmailActivities.SearchAsync(null, limit, CancellationToken.None).ConfigureAwait(false);
var validationResult = await _client.EmailValidation.ValidateAsync("[email protected]", "Signup Form", CancellationToken.None).ConfigureAwait(false);
var globalSuppressions = await _client.GlobalSuppressions.GetAllAsync(null, null, null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var invalidEmails = await _client.InvalidEmails.GetAllAsync(null, null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var ipAddresses = await _client.IpAddresses.GetAllAsync(false, null, limit, offset, CancellationToken.None).ConfigureAwait(false);
var ipPool = await _client.IpPools.GetAsync("marketing", CancellationToken.None).ConfigureAwait(false);
var legacyCategories = await _legacyClient.Categories.GetAsync(null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var legacyContacts = await _legacyClient.Contacts.GetAsync(recordsPerPage, page, null, CancellationToken.None).ConfigureAwait(false);
var legacyCustomFields = await _legacyClient.CustomFields.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
var legacyLists = await _legacyClient.Lists.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
var legacySegments = await _legacyClient.Segments.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
var legacySenderIdentities = await _legacyClient.SenderIdentities.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
var authenticationDomains = await _client.SenderAuthentication.GetAllDomainsAsync(limit, offset, false, null, null, null, CancellationToken.None).ConfigureAwait(false);
var reverseDns = await _client.SenderAuthentication.GetAllReverseDnsAsync(null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var links = await _client.SenderAuthentication.GetAllLinksAsync(null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var spamReports = await _client.SpamReports.GetAllAsync(null, null, limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var subusers = await _client.Subusers.GetAllAsync(limit, offset, CancellationToken.None).ConfigureAwait(false);
var suppressions = await _client.Suppressions.GetAllAsync(limit, offset, null, CancellationToken.None).ConfigureAwait(false);
var accessRequests = await _client.Teammates.GetAccessRequestsAsync(limit, offset, CancellationToken.None).ConfigureAwait(false);
var invitations = await _client.Teammates.GetAllPendingInvitationsAsync(limit, offset, CancellationToken.None).ConfigureAwait(false);
var teammates = await _client.Teammates.GetAllTeammatesAsync(limit, offset, CancellationToken.None).ConfigureAwait(false);
var templates = await _client.Templates.GetAllAsync(TemplateType.Legacy, null, CancellationToken.None).ConfigureAwait(false);
var unsubscribeGroups = await _client.UnsubscribeGroups.GetAllAsync(null, CancellationToken.None).ConfigureAwait(false);
}

private static MockHttpMessageHandler GetMockHttpMessageHandler()
{
var mockHttp = new MockHttpMessageHandler();
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("access_settings/whitelist")).Respond("application/json", UnitTests.Resources.AccessManagementTests.MULTIPLE_WHITELISTED_IPS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("access_settings/activity")).Respond("application/json", UnitTests.Resources.AccessManagementTests.MULTIPLE_ACCESS_ENTRIES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("alerts")).Respond("application/json", UnitTests.Resources.AlertsTests.MULTIPLE_ALERTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("api_keys")).Respond("application/json", UnitTests.Resources.ApiKeysTests.MULTIPLE_API_KEY_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("user/scheduled_sends")).Respond("application/json", UnitTests.Resources.BatchesTests.MULTIPLE_BATCHES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("suppression/blocks") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.BlocksTests.MULTIPLE_BLOCKS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("suppression/bounces", "[email protected]")).Respond("application/json", UnitTests.Resources.BouncesTests.MULTIPLE_BOUNCES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("campaigns") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.CampaignsTests.MULTIPLE_CAMPAIGNS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("designs")).Respond("application/json", UnitTests.Resources.DesignsTests.MULTIPLE_DESIGNS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("messages") + $"?limit={limit}&query=").Respond("application/json", UnitTests.Resources.EmailActivitiesTests.MULTIPLE_MESSAGES_FOUND);
mockHttp.When(HttpMethod.Post, UnitTests.Utils.GetSendGridApiUri("validations/email")).Respond("application/json", "{\"result\":" + UnitTests.Resources.EmailValidationTests.VALID_EMAIL_JSON + "}");
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("suppression/unsubscribes")).Respond("application/json", UnitTests.Resources.GlobalSuppressionTests.GLOBALLY_UNSUBSCRIBED);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("suppression/invalid_emails") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.InvalidEmailsTests.MULTIPLE_INVALID_EMAILS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("ips")).Respond("application/json", UnitTests.Resources.IpAddressesTests.MULTIPLE_IPADDRESSES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("ips/pools", "marketing")).Respond("application/json", UnitTests.Resources.IpPoolsTests.SINGLE_IPPOOL_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("categories") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.LegacyCategoriesTests.MULTIPLE_CATEGORIES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("contactdb/recipients") + $"?page_size={recordsPerPage}&page={page}").Respond("application/json", UnitTests.Resources.LegacyContactsTests.MULTIPLE_RECIPIENTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("contactdb/custom_fields")).Respond("application/json", UnitTests.Resources.LegacyCustomFieldsTests.MULTIPLE_CUSTOM_FIELDS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("contactdb/lists")).Respond("application/json", UnitTests.Resources.LegacyListsTests.MULTIPLE_LISTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("contactdb/segments")).Respond("application/json", UnitTests.Resources.LegacySegmentsTests.MULTIPLE_SEGMENTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("senders")).Respond("application/json", UnitTests.Resources.LegacySenderIdentitiesTests.MULTIPLE_SENDER_IDENTITIES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("whitelabel/domains") + $"?exclude_subusers=false&limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.SenderAuthenticationTests.MULTIPLE_DOMAINS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("whitelabel/ips") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.SenderAuthenticationTests.MULTIPLE_IPS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("whitelabel/links") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.SenderAuthenticationTests.MULTIPLE_LINKS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("suppression/spam_reports") + $"?limit={limit}&offset={offset}").Respond("application/json", UnitTests.Resources.SpamReportsTests.MULTIPLE_SPAM_REPORTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("subusers")).Respond("application/json", UnitTests.Resources.SubusersTests.MULTIPLE_SUBUSER_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("asm", "suppressions")).Respond("application/json", UnitTests.Resources.SuppresionsTests.ALL_SUPPRESSIONS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("scopes/requests")).Respond("application/json", UnitTests.Resources.TeammatesTests.MULTIPLE_ACCESS_REQUESTS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("teammates", "pending")).Respond("application/json", UnitTests.Resources.TeammatesTests.MULTIPLE_INVITATIONS_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("teammates")).Respond("application/json", UnitTests.Resources.TeammatesTests.MULTIPLE_TEAMMATES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("templates")).Respond("application/json", UnitTests.Resources.TemplatesTests.MULTIPLE_TEMPLATES_JSON);
mockHttp.When(HttpMethod.Get, UnitTests.Utils.GetSendGridApiUri("asm/groups")).Respond("application/json", UnitTests.Resources.UnsubscribeGroupsTests.MULTIPLE_SUPPRESSION_GROUPS_JSON);
return mockHttp;
}
}
}
37 changes: 37 additions & 0 deletions Source/StrongGrid.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running;

namespace StrongGrid.Benchmark
{
class Program
{
static void Main(string[] args)
{
//var baseNamespace = "StrongGrid.Models";
//var allTypes = Assembly
// .GetAssembly(typeof(BaseClient))
// .GetTypes()
// .Where(t => t.IsClass)
// .Where(t => !string.IsNullOrEmpty(t.Namespace))
// .Where(t => t.Namespace.StartsWith(baseNamespace))
// .Where(t => !t.Namespace.StartsWith(baseNamespace + ".Webhooks.InboundEmail")); // Exclude inbound email classes which are deserialized by our WebhookParser

//var typesInBaseNamespace = allTypes
// .Where(t => t.Namespace.Equals(baseNamespace))
// .Select(t => new { Type = t, JsonSerializeAttribute = $"[JsonSerializable(typeof({t.FullName}))]" });

//var typesInSubNamespace = allTypes
// .Where(t => !t.Namespace.Equals(baseNamespace))
// .Select(t => new { Type = t, JsonSerializeAttribute = $"[JsonSerializable(typeof({t.FullName}), TypeInfoPropertyName = \"{t.FullName.Remove(0, baseNamespace.Length + 1).Replace(".", "")}\")]" });

//var result = string.Join("\r\n", typesInBaseNamespace.Union(typesInSubNamespace).OrderBy(t => t.Type.FullName).Select(t => t.JsonSerializeAttribute));

IConfig config = null;

// To debug
//config = new DebugInProcessConfig();

BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);
}
}
}
18 changes: 18 additions & 0 deletions Source/StrongGrid.Benchmark/StrongGrid.Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="RichardSzalay.MockHttp" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\StrongGrid.UnitTests\StrongGrid.UnitTests.csproj" />
<ProjectReference Include="..\StrongGrid\StrongGrid.csproj" />
</ItemGroup>

</Project>
22 changes: 0 additions & 22 deletions Source/StrongGrid.IntegrationTests/Tests/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,6 @@ public async Task RunAsync(IBaseClient client, TextWriter log, CancellationToken
await log.WriteLineAsync($" - {mailSetting.Title}: {(mailSetting.Enabled ? "Enabled" : "Not enabled")}").ConfigureAwait(false);
}

var spamCheckSettings = await client.Settings.GetSpamCheckMailSettingsAsync(null, cancellationToken).ConfigureAwait(false);
await log.WriteLineAsync("SPAM Check settings retrieved:").ConfigureAwait(false);
await log.WriteLineAsync($" - Enabled: {spamCheckSettings.Enabled}").ConfigureAwait(false);
await log.WriteLineAsync($" - Threshold: {spamCheckSettings.Threshold}").ConfigureAwait(false);
await log.WriteLineAsync($" - URL: {spamCheckSettings.Url}").ConfigureAwait(false);

var updatedSpamCheckSettings = await client.Settings.UpdateSpamCheckMailSettingsAsync(false, null, 1, null, cancellationToken).ConfigureAwait(false);
await log.WriteLineAsync("SPAM Check settings updated:").ConfigureAwait(false);
await log.WriteLineAsync($" - Enabled: {updatedSpamCheckSettings.Enabled}").ConfigureAwait(false);
await log.WriteLineAsync($" - Threshold: {updatedSpamCheckSettings.Threshold}").ConfigureAwait(false);
await log.WriteLineAsync($" - URL: {updatedSpamCheckSettings.Url}").ConfigureAwait(false);

var bccSettings = await client.Settings.GetBccMailSettingsAsync(null, cancellationToken).ConfigureAwait(false);
await log.WriteLineAsync("BCC settings retrieved:").ConfigureAwait(false);
await log.WriteLineAsync($" - Enabled: {bccSettings.Enabled}").ConfigureAwait(false);
await log.WriteLineAsync($" - Address: {bccSettings.EmailAddress}").ConfigureAwait(false);

var updatedBccSettings = await client.Settings.UpdateBccMailSettingsAsync(false, null, null, cancellationToken).ConfigureAwait(false);
await log.WriteLineAsync("BCC settings updated:").ConfigureAwait(false);
await log.WriteLineAsync($" - Enabled: {updatedBccSettings.Enabled}").ConfigureAwait(false);
await log.WriteLineAsync($" - Address: {updatedBccSettings.EmailAddress}").ConfigureAwait(false);

var clickTrackingSettings = await client.Settings.GetClickTrackingSettingsAsync(null, cancellationToken).ConfigureAwait(false);
await log.WriteLineAsync("Click tracking settings retrieved:").ConfigureAwait(false);
await log.WriteLineAsync($" - Enabled in text content: {clickTrackingSettings.EnabledInTextContent}").ConfigureAwait(false);
Expand Down
28 changes: 14 additions & 14 deletions Source/StrongGrid.UnitTests/Models/PaginationMetadataTests.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
using Newtonsoft.Json;
using Shouldly;
using StrongGrid.Models;
using System.Text.Json;
using Xunit;

namespace StrongGrid.UnitTests.Models
{
public class PaginationMetadataTests
{
private const string FIRST_PAGE_JSON = @"{
'self':'https://api.sendgrid.com/v3/designs?page_token=self_token',
'next':'https://api.sendgrid.com/v3/designs?page_token=next_token',
'count':5
""self"":""https://api.sendgrid.com/v3/designs?page_token=self_token"",
""next"":""https://api.sendgrid.com/v3/designs?page_token=next_token"",
""count"":5
}";

private const string MIDDLE_PAGE_JSON = @"{
'prev':'https://api.sendgrid.com/v3/designs?page_token=prev_token',
'self':'https://api.sendgrid.com/v3/designs?page_token=self_token',
'next':'https://api.sendgrid.com/v3/designs?page_token=next_token',
'count':5
""prev"":""https://api.sendgrid.com/v3/designs?page_token=prev_token"",
""self"":""https://api.sendgrid.com/v3/designs?page_token=self_token"",
""next"":""https://api.sendgrid.com/v3/designs?page_token=next_token"",
""count"":5
}";

private const string LAST_PAGE_JSON = @"{
'prev':'https://api.sendgrid.com/v3/designs?page_token=prev_token',
'self':'https://api.sendgrid.com/v3/designs?page_token=self_token',
'count':5
""prev"":""https://api.sendgrid.com/v3/designs?page_token=prev_token"",
""self"":""https://api.sendgrid.com/v3/designs?page_token=self_token"",
""count"":5
}";

[Fact]
Expand All @@ -32,7 +32,7 @@ public void Parse_json_first_page()
// Arrange

// Act
var result = JsonConvert.DeserializeObject<PaginationMetadata>(FIRST_PAGE_JSON);
var result = JsonSerializer.Deserialize<PaginationMetadata>(FIRST_PAGE_JSON);

// Assert
result.ShouldNotBeNull();
Expand All @@ -51,7 +51,7 @@ public void Parse_json_middle_page()
// Arrange

// Act
var result = JsonConvert.DeserializeObject<PaginationMetadata>(MIDDLE_PAGE_JSON);
var result = JsonSerializer.Deserialize<PaginationMetadata>(MIDDLE_PAGE_JSON);

// Assert
result.ShouldNotBeNull();
Expand All @@ -70,7 +70,7 @@ public void Parse_json_last_page()
// Arrange

// Act
var result = JsonConvert.DeserializeObject<PaginationMetadata>(LAST_PAGE_JSON);
var result = JsonSerializer.Deserialize<PaginationMetadata>(LAST_PAGE_JSON);

// Assert
result.ShouldNotBeNull();
Expand Down
4 changes: 4 additions & 0 deletions Source/StrongGrid.UnitTests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("StrongGrid.Benchmark")]

Loading

0 comments on commit 87f1138

Please sign in to comment.