Skip to content

Commit

Permalink
massive refactor to support mocked http requests
Browse files Browse the repository at this point in the history
  • Loading branch information
ctolkien committed Sep 22, 2016
1 parent e237bc9 commit 78414de
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 47 deletions.
40 changes: 23 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Install via Nuget
```csharp
using (var png = new TinyPngClient("yourSecretApiKey"))
{
await (await png.Compress("cat.jpg")).SaveImageToDisk("compressedCat.jpg");
await png.Compress("cat.jpg");
}
```

Expand All @@ -39,31 +39,36 @@ using (var png = new TinyPngClient("yourSecretApiKey"))
using (var png = new TinyPngClient("yourSecretApiKey"))
{
//compress an image
var compressResult = await png.Compress("pathToFile or byte array or stream");
var result = await png.Compress("pathToFile or byte array or stream");

//this gives you the information about your image as stored by TinyPNG
//they don't give you the actual bits as you may want to chain this with a resize
//operation without caring for the originally sied image. For that, we need to:
var compressedImage = await result.Download();

//get the image data as a byte array
var bytes = await compressResult.GetImageByteData();
var bytes = await compressedImage.GetImageByteData();

//get a stream instead
var stream = await compressResult.GetImageStreamData()
var stream = await compressedImage.GetImageStreamData()

//or just save to disk
await compressResult.SaveImageToDisk("pathToSaveImage");
await compressedImage.SaveImageToDisk("pathToSaveImage");

}
```

Further details about the result of the compression are also available on the `Input` and `Output` properties. Some examples:
Further details about the result of the compression are also available on the `Input` and `Output` properties of a `Compress` operation. Some examples:
```csharp

//old size
compressResult.Input.Size;
result.Input.Size;

//new size
compressResult.Output.Size;
result.Output.Size;

//URL of the compressed Image
compressResult.Output.Url;
result.Output.Url;

```

Expand All @@ -72,9 +77,9 @@ Further details about the result of the compression are also available on the `I
```csharp
using (var png = new TinyPngClient("yourSecretApiKey"))
{
var compressResult = await png.Compress("pathToFile or byte array or stream");
var result = await png.Compress("pathToFile or byte array or stream");

var resizedImage = await png.Resize(compressResult, width, height, ResizeType);
var resizedImage = await png.Resize(result, width, height, ResizeType);

await resizedImage.SaveImageToDisk("pathToSaveImage");
}
Expand All @@ -90,12 +95,12 @@ depending on the type of resize you want to do.
```csharp
using (var png = new TinyPngClient("yourSecretApiKey"))
{
var compressResult = await png.Compress("pathToFile or byte array or stream");
var result = await png.Compress("pathToFile or byte array or stream");

await png.Resize(compressResult, new ScaleWidthResizeOperation(width));
await png.Resize(compressResult, new ScaleHeightResizeOperation(width));
await png.Resize(compressResult, new FitResizeOperation(width, height));
await png.Resize(compressResult, new CoverResizeOperation(width, height));
await png.Resize(result, new ScaleWidthResizeOperation(width));
await png.Resize(result, new ScaleHeightResizeOperation(width));
await png.Resize(result, new FitResizeOperation(width, height));
await png.Resize(result, new CoverResizeOperation(width, height));
}

```
Expand All @@ -104,7 +109,8 @@ The same `Byte[]`, `Stream` and `File` path API's are available from the result

## Amazon S3 Storage

The result of any compress operation can be stored directly on to Amazon S3 storage. There are two ways to configure this.
The result of any compress operation can be stored directly on to Amazon S3 storage. I'd strongly recommend referring to [TinyPNG.com's documentation](https://tinypng.com/developers/reference) with regard to how to configure
the appropriate S3 access.

If you're going to be storing images for most requests onto S3, then you can pass in an `AmazonS3Configuration` object to the constructor.

Expand Down
14 changes: 14 additions & 0 deletions TinyPNG.v2.ncrunchsolution
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<SolutionConfiguration>
<FileVersion>1</FileVersion>
<InferProjectReferencesUsingAssemblyNames>false</InferProjectReferencesUsingAssemblyNames>
<AllowParallelTestExecution>false</AllowParallelTestExecution>
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
<FrameworkUtilisationTypeForGallio>UseStaticAnalysis</FrameworkUtilisationTypeForGallio>
<FrameworkUtilisationTypeForMSpec>UseStaticAnalysis</FrameworkUtilisationTypeForMSpec>
<FrameworkUtilisationTypeForMSTest>UseStaticAnalysis</FrameworkUtilisationTypeForMSTest>
<FrameworkUtilisationTypeForXUnit2>UseDynamicAnalysis</FrameworkUtilisationTypeForXUnit2>
<NCrunchCacheStoragePath />
<MetricsExclusionList>
</MetricsExclusionList>
</SolutionConfiguration>
7 changes: 3 additions & 4 deletions src/TinyPNG/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ namespace TinyPng
{
public static class Extensions
{

/// <summary>
/// Get the image data as a byte array
/// </summary>
/// <param name="result">The result from compress</param>
/// <returns>Byte array of the image data</returns>
public async static Task<byte[]> GetImageByteData(this TinyPngResponse result)
public async static Task<byte[]> GetImageByteData(this TinyPngImageResponse result)
{
return await result.HttpResponseMessage.Content.ReadAsByteArrayAsync();
}
Expand All @@ -22,7 +21,7 @@ public async static Task<byte[]> GetImageByteData(this TinyPngResponse result)
/// </summary>
/// <param name="result">The result from compress</param>
/// <returns>Stream of compressed image data</returns>
public async static Task<Stream> GetImageStreamData(this TinyPngResponse result)
public async static Task<Stream> GetImageStreamData(this TinyPngImageResponse result)
{
return await result.HttpResponseMessage.Content.ReadAsStreamAsync();
}
Expand All @@ -33,7 +32,7 @@ public async static Task<Stream> GetImageStreamData(this TinyPngResponse result)
/// <param name="result">The result from compress</param>
/// <param name="filePath">The path to store the file</param>
/// <returns></returns>
public async static Task SaveImageToDisk(this TinyPngResponse result, string filePath)
public async static Task SaveImageToDisk(this TinyPngImageResponse result, string filePath)
{
var byteData = await result.GetImageByteData();
File.WriteAllBytes(filePath, byteData);
Expand Down
1 change: 1 addition & 0 deletions src/TinyPNG/Responses/TinyPngCompressResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class TinyPngCompressResponse : TinyPngResponse
public TinyPngApiInput Input { get; private set; }
public TinyPngApiOutput Output { get; private set; }
public TinyPngApiResult ApiResult { get; private set; }

private readonly JsonSerializerSettings jsonSettings;

public TinyPngCompressResponse(HttpResponseMessage msg) : base(msg)
Expand Down
14 changes: 14 additions & 0 deletions src/TinyPNG/Responses/TinyPngImageResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Net.Http;

namespace TinyPng.Responses
{
/// <summary>
/// This is a response which contains actual image data
/// </summary>
public class TinyPngImageResponse : TinyPngResponse
{
public TinyPngImageResponse(HttpResponseMessage msg) : base(msg)
{
}
}
}
2 changes: 1 addition & 1 deletion src/TinyPNG/Responses/TinyPngResizeResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TinyPng.Responses
{
public class TinyPngResizeResponse : TinyPngResponse
public class TinyPngResizeResponse : TinyPngImageResponse
{
public TinyPngResizeResponse(HttpResponseMessage msg) : base(msg)
{
Expand Down
10 changes: 2 additions & 8 deletions src/TinyPNG/Responses/TinyPngResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@ namespace TinyPng.Responses
{
public class TinyPngResponse
{
public HttpResponseMessage HttpResponseMessage { get; private set; }
public HttpResponseMessage HttpResponseMessage { get; }

private int compressionCount;

public int CompressionCount
{
get
{
return compressionCount;
}
}
public int CompressionCount => compressionCount;

protected TinyPngResponse(HttpResponseMessage msg)
{
Expand Down
25 changes: 21 additions & 4 deletions src/TinyPNG/TinyPng.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public class TinyPngClient : IDisposable
{
private readonly string _apiKey;
private const string ApiEndpoint = "https://api.tinify.com/shrink";
private HttpClient httpClient = new HttpClient();

public HttpClient httpClient = new HttpClient();
private readonly JsonSerializerSettings jsonSettings;

/// <summary>
Expand Down Expand Up @@ -125,6 +126,22 @@ public async Task<TinyPngCompressResponse> Compress(Stream data)
var errorMsg = JsonConvert.DeserializeObject<ApiErrorResponse>(await response.Content.ReadAsStringAsync());
throw new TinyPngApiException((int)response.StatusCode, response.ReasonPhrase, errorMsg.Error, errorMsg.Message);
}
public async Task<TinyPngImageResponse> Download(TinyPngCompressResponse result)
{
if (result == null)
throw new ArgumentNullException(nameof(result));

var msg = new HttpRequestMessage(HttpMethod.Get, result.Output.Url);

var response = await httpClient.SendAsync(msg);
if (response.IsSuccessStatusCode)
{
return new TinyPngImageResponse(response);
}

var errorMsg = JsonConvert.DeserializeObject<ApiErrorResponse>(await response.Content.ReadAsStringAsync());
throw new TinyPngApiException((int)response.StatusCode, response.ReasonPhrase, errorMsg.Error, errorMsg.Message);
}


/// <summary>
Expand All @@ -142,7 +159,6 @@ public async Task<TinyPngResizeResponse> Resize(TinyPngCompressResponse result,

var requestBody = JsonConvert.SerializeObject(new { resize = resizeOperation }, jsonSettings);


var msg = new HttpRequestMessage(HttpMethod.Post, result.Output.Url);
msg.Content = new StringContent(requestBody, System.Text.Encoding.UTF8, "application/json");

Expand Down Expand Up @@ -217,8 +233,9 @@ public async Task<Uri> SaveCompressedImageToAmazonS3(TinyPngCompressResponse res
/// Stores a previously compressed image directly into Amazon S3 storage
/// </summary>
/// <param name="result">The previously compressed image</param>
/// <param name="pathBucket">The path and bucket to store in: bucket/file.png format</param>
/// <param name="regionOverride">Optional: To override the previosly configured region</param>
/// <param name="path">The path to storage the image as</param>
/// <param name="bucketOverride">Optional: To override the previously configured bucket</param>
/// <param name="regionOverride">Optional: To override the previously configured region</param>
/// <returns></returns>
public async Task<Uri> SaveCompressedImageToAmazonS3(TinyPngCompressResponse result, string path, string bucketOverride = "", string regionOverride = "")
{
Expand Down
4 changes: 2 additions & 2 deletions src/TinyPNG/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"copyright": "Copyright 2016 Chad Tolkien",
"packOptions": {
"iconUrl": "https://raw.githubusercontent.com/ctolkien/TinyPNG/master/icon.png",
"releaseNotes": "Support for .NET Core 1.0",
"releaseNotes": "Major refactor of the API",
"summary": "This is a .NET wrapper around the TinyPng.com image compression service.",
"description": "This is a .NET wrapper around the TinyPng.com image compression service. Supports .Net Core and full .Net Framework. Non-blocking async turtles all the way down. Byte[], Stream and File API's available.",
"repository": {
Expand Down Expand Up @@ -49,5 +49,5 @@
}
}
},
"version": "1.3.0-*"
"version": "2.0.0-*"
}
41 changes: 41 additions & 0 deletions tests/TinyPng.Tests/FakeResponseHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace TinyPng.Tests
{
public class FakeResponseHandler : DelegatingHandler
{
private readonly Dictionary<Uri, HttpResponseMessage> _FakeGetResponses = new Dictionary<Uri, HttpResponseMessage>();
private readonly Dictionary<Uri, HttpResponseMessage> _FakePostResponses = new Dictionary<Uri, HttpResponseMessage>();


public void AddFakeGetResponse(Uri uri, HttpResponseMessage responseMessage)
{
_FakeGetResponses.Add(uri, responseMessage);
}
public void AddFakePostResponse(Uri uri, HttpResponseMessage responseMessage)
{
_FakePostResponses.Add(uri, responseMessage);
}

protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Method == HttpMethod.Get && _FakeGetResponses.ContainsKey(request.RequestUri))
{
return _FakeGetResponses[request.RequestUri];
}
if (request.Method == HttpMethod.Post &&_FakePostResponses.ContainsKey(request.RequestUri))
{
return _FakePostResponses[request.RequestUri];
}
else
{
return new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request };
}

}
}
}
Binary file modified tests/TinyPng.Tests/Resources/cat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/TinyPng.Tests/Resources/compressedcat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/TinyPng.Tests/Resources/resizedcat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 78414de

Please sign in to comment.