Skip to content

Commit

Permalink
Merge pull request #84 from feinoujc/v6
Browse files Browse the repository at this point in the history
V6
  • Loading branch information
feinoujc authored Dec 29, 2018
2 parents 3e70381 + 46911f5 commit 7bbcf6f
Show file tree
Hide file tree
Showing 18 changed files with 201 additions and 61 deletions.
Binary file added Mandrill.net.snk
Binary file not shown.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Mandrill.net
============

Simple, cross-platform Mandrill api wrapper for .NET Core and .NET 4.5+
Simple, cross-platform Mandrill api wrapper for .NET Core and .NET 4.6+

[![Travis](https://travis-ci.org/feinoujc/Mandrill.net.svg?branch=master)](https://travis-ci.org/feinoujc/Mandrill.net)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/kfgnqdmrvhlc36co/branch/master?svg=true)](https://ci.appveyor.com/project/feinoujc/mandrill-net/branch/master)
Expand All @@ -21,7 +21,7 @@ Install-Package Mandrill.net
## Building
```sh
dotnet build src/Mandrill.net
# if on mac/linux, you cannot build against the .net45 target:
# if on mac/linux, you cannot build against the .net461 target:
# dotnet build src/Mandrill.net -f netstandard2.0
```

Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ before_build:
- dotnet --version
- where dotnet
- dotnet restore
- nuget install coveralls.io -version 1.3.4 -OutputDirectory .\packages
- nuget install coveralls.io -version 1.4.2 -OutputDirectory .\packages
build: off
build_script:
- dotnet pack src/Mandrill.net --include-symbols --configuration Release --output artifacts
test: off
test_script:
- if defined MANDRILL_API_KEY dotnet test tests /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
- if defined MANDRILL_API_KEY .\packages\coveralls.io.1.3.4\tools\coveralls.net.exe --opencover .\tests\coverage.xml
- if defined MANDRILL_API_KEY .\packages\coveralls.io.1.4.2\tools\coveralls.net.exe --opencover .\tests\coverage.opencover.xml
artifacts:
- path: 'src\**\*.nupkg'
deploy:
Expand Down
44 changes: 44 additions & 0 deletions src/Mandrill.net/DefaultHttpClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;

namespace Mandrill
{
internal class DefaultHttpClient : HttpClient
{
private DefaultHttpClient()
{

}
private static readonly Lazy<Version> UserAgentVersionLazy = new Lazy<Version>(() => new AssemblyName(typeof(MandrillRequest).GetTypeInfo().Assembly.FullName).Version);
private static readonly Uri BaseUrl = new Uri("https://mandrillapp.com/api/1.0/");

public static HttpClient CreateDefault()
{
var httpClient = new DefaultHttpClient();
return ApplyDefaults(httpClient);
}
public static HttpClient ApplyDefaults(HttpClient httpClient)
{
if (httpClient == null) throw new ArgumentNullException(nameof(httpClient));

if (httpClient.BaseAddress == null)
{
httpClient.BaseAddress = BaseUrl;
}

if (httpClient.DefaultRequestHeaders.UserAgent.Count == 0)
{
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Mandrill.net", UserAgentVersionLazy.Value.ToString(3)));

}
if (httpClient.DefaultRequestHeaders.Accept.Count == 0)
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

}
return httpClient;
}
}
}
10 changes: 6 additions & 4 deletions src/Mandrill.net/Mandrill.net.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<VersionPrefix>5.0.0</VersionPrefix>
<VersionPrefix>6.0.0</VersionPrefix>
</PropertyGroup>

<PropertyGroup>
<Description>.NET wrapper for the Mandrill API</Description>
<AssemblyTitle>Mandrill.net</AssemblyTitle>
<Description>Simple .net wrapper for the Mandrill.net api</Description>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblyName>Mandrill.net</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\Mandrill.net.snk</AssemblyOriginatorKeyFile>
<PackageId>Mandrill.net</PackageId>
<PackageTags>mandrill;mailchimp;mail</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/feinoujc/Mandrill.net/master/logo.png</PackageIconUrl>
Expand All @@ -21,10 +23,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Net.Http" />
<Reference Include="System" />
Expand Down
25 changes: 21 additions & 4 deletions src/Mandrill.net/MandrillApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Mandrill
{
public class MandrillApi
public class MandrillApi : IDisposable
{
private readonly MandrillRequest _request;
private MandrillExportsApi _exports;
Expand All @@ -20,10 +20,19 @@ public class MandrillApi
private MandrillWebHooksApi _webhooks;
private MandrillWhitelistsApi _whitelists;

public MandrillApi(string apiKey)
public HttpClient HttpClient => _request.HttpClient;

public MandrillApi(string apiKey) : this(new MandrillRequest(apiKey, DefaultHttpClient.CreateDefault()))
{
}

public MandrillApi(string apiKey, HttpClient client) : this(new MandrillRequest(apiKey, DefaultHttpClient.ApplyDefaults(client)))
{
}

private MandrillApi(MandrillRequest request)
{
if (apiKey == null) throw new ArgumentNullException(nameof(apiKey));
_request = new MandrillRequest(apiKey);
_request = request;
}

public string ApiKey => _request.ApiKey;
Expand All @@ -50,6 +59,14 @@ public MandrillApi(string apiKey)

public IMandrillExportsApi Exports => _exports ?? (_exports = new MandrillExportsApi(this));

public void Dispose()
{
if (HttpClient is DefaultHttpClient)
{
HttpClient.Dispose();
}
}

internal Task<TResponse> PostAsync<TRequest, TResponse>(string requestUri, TRequest value)
where TRequest : MandrillRequestBase
{
Expand Down
13 changes: 5 additions & 8 deletions src/Mandrill.net/MandrillRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Mandrill.Model;
Expand All @@ -13,16 +12,14 @@ namespace Mandrill
{
internal class MandrillRequest
{
public HttpClient HttpClient { get; } = new HttpClient();
public HttpClient HttpClient { get; }
public string ApiKey { get; }
private static readonly Lazy<Version> UserAgentVersionLazy = new Lazy<Version>(() => new AssemblyName(typeof(MandrillRequest).GetTypeInfo().Assembly.FullName).Version);
private static readonly Uri BaseUrl = new Uri("https://mandrillapp.com/api/1.0/");
public MandrillRequest(string apiKey)
public MandrillRequest(string apiKey, HttpClient httpClient)
{
if (apiKey == null) throw new ArgumentNullException(nameof(apiKey));

ApiKey = apiKey;
HttpClient.BaseAddress = BaseUrl;
HttpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Mandrill.net", UserAgentVersionLazy.Value.ToString(3)));
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
this.HttpClient = httpClient;
}

public async Task<TResponse> PostAsync<TRequest, TResponse>(string requestUri, TRequest value) where TRequest : MandrillRequestBase
Expand Down
13 changes: 13 additions & 0 deletions src/Mandrill.net/Model/WebHook/MandrillInboundAttachment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Newtonsoft.Json;

namespace Mandrill.Model
{
public class MandrillInboundAttachment
{
public string Name { get; set; }
public string Type { get; set; }
public string Content { get; set; }
[JsonProperty("base64")]
public bool Base64 { get; set; }
}
}
9 changes: 9 additions & 0 deletions src/Mandrill.net/Model/WebHook/MandrillInboundImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Mandrill.Model
{
public class MandrillInboundImage
{
public string Name { get; set; }
public string Type { get; set; }
public byte[] Content { get; set; }
}
}
3 changes: 3 additions & 0 deletions src/Mandrill.net/Model/WebHook/MandrillInboundMessageInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public class MandrillInboundMessageInfo

public MandrillInboundSpamReport SpamReport { get; set; }

public List<MandrillInboundAttachment> Attachments { get; set; } = new List<MandrillInboundAttachment>();

public List<MandrillInboundImage> Images { get; set; } = new List<MandrillInboundImage>();

public MandrillInboundSpfInfo Spf { get; set; }

Expand Down
4 changes: 2 additions & 2 deletions src/Mandrill.net/Model/WebHook/MandrillMessageEventType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public enum MandrillMessageEventType
{
Send,
Deferral,
[EnumMember(Value = "hard_bounce")] HardBounce,
[EnumMember(Value = "soft_bounce")] SoftBounce,
HardBounce,
SoftBounce,
Open,
Click,
Spam,
Expand Down
2 changes: 0 additions & 2 deletions src/Mandrill.net/Model/WebHook/MandrillWebHookEventType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ namespace Mandrill.Model
public enum MandrillWebHookEventType
{
Send,
[EnumMember(Value = "hard_bounce")]
HardBounce,
[EnumMember(Value = "soft_bounce")]
SoftBounce,
Open,
Click,
Expand Down
31 changes: 4 additions & 27 deletions src/Mandrill.net/Serialization/MandrillJsonContractResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,11 @@ namespace Mandrill.Serialization
{
internal class MandrillJsonContractResolver : DefaultContractResolver
{
private static readonly Regex CamelCaseRegex = new Regex("^[A-Z][a-z]+(?:[A-Z][a-z]+)*$", RegexOptions.Compiled);

protected static string ConvertCamelCasePropertyNamesToLowerCaseUnderscoreStyle(string propertyName)
public MandrillJsonContractResolver()
{
if (CamelCaseRegex.IsMatch(propertyName))
{
return Regex.Replace(
Regex.Replace(
Regex.Replace(propertyName, @"([A-Z]+)([A-Z][a-z])", "$1_$2"), @"([a-z\d])([A-Z])",
"$1_$2"), @"[-\s]", "_").ToLower();

}
return (propertyName).ToLower();
NamingStrategy = new SnakeCaseNamingStrategy(false, false);
}


protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var jsonProperty = base.CreateProperty(member, memberSerialization);
Expand All @@ -37,7 +26,7 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
if (propertyType.GetTypeInfo().IsGenericType && propertyType.GenericTypeArguments.Length == 1)
{
var t = propertyType.GenericTypeArguments[0];
if (typeof (IList<>).MakeGenericType(t).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
if (typeof(IList<>).MakeGenericType(t).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
{
var prop = jsonProperty.DeclaringType.GetTypeInfo().GetDeclaredProperty(member.Name);
jsonProperty.ShouldSerialize = instance =>
Expand All @@ -48,7 +37,7 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
}
}

if (typeof (IDictionary<string, string>).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
if (typeof(IDictionary<string, string>).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
{
var prop = jsonProperty.DeclaringType.GetTypeInfo().GetDeclaredProperty(member.Name);

Expand All @@ -72,19 +61,7 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
}
}

//leave the keys of a dictionary alone, otherwise convert to lowercase underscore
if (!PropertyIsInDictionary(jsonProperty))
{
jsonProperty.PropertyName = ConvertCamelCasePropertyNamesToLowerCaseUnderscoreStyle(jsonProperty.PropertyName);
}

return jsonProperty;
}

private static bool PropertyIsInDictionary(JsonProperty jsonProperty)
{
return typeof (IDictionary<string, string>).GetTypeInfo().IsAssignableFrom(jsonProperty.DeclaringType.GetTypeInfo())
|| typeof (IDictionary<string, object>).GetTypeInfo().IsAssignableFrom(jsonProperty.DeclaringType.GetTypeInfo());
}
}
}
5 changes: 3 additions & 2 deletions src/Mandrill.net/Serialization/MandrillSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace Mandrill.Serialization
{
Expand All @@ -12,10 +13,10 @@ public static class MandrillSerializer

private static JsonSerializer CreateSerializer()
{
var settings = new JsonSerializerSettings {ContractResolver = new MandrillJsonContractResolver()};
var settings = new JsonSerializerSettings { ContractResolver = new MandrillJsonContractResolver() };

settings.Converters.Add(new UnixDateTimeConverter());
settings.Converters.Add(new StringEnumConverter {CamelCaseText = true, AllowIntegerValues = false});
settings.Converters.Add(new StringEnumConverter { NamingStrategy = new SnakeCaseNamingStrategy(), AllowIntegerValues = false });
settings.NullValueHandling = NullValueHandling.Ignore;
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
return JsonSerializer.Create(settings);
Expand Down
2 changes: 1 addition & 1 deletion tests/IntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Tests


[Trait("Category", "integration")]
public abstract class IntegrationTest: IDisposable
public abstract class IntegrationTest : IDisposable
{
private static readonly Lazy<string> ApiKeyLazy = new Lazy<string>(() =>
{
Expand Down
Loading

0 comments on commit 7bbcf6f

Please sign in to comment.