Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better testing, apply recommendations #27

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions BunnyCDN.Net.Storage.Tests/BunnyCDN.Net.Storage.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
32 changes: 32 additions & 0 deletions BunnyCDN.Net.Storage.Tests/ChecksumTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Xunit;
using System.IO;
using System.Text;

namespace BunnyCDN.Net.Storage.Tests
{
public class ChecksumTests
{
/*
Hashes generated using: echo -n "<<Data>>" | shasum -a 256 | awk '{print toupper($1)}'
Shasum version: 6.02
*/
[Theory]
[InlineData("Test",
"532EAABD9574880DBF76B9B8CC00832C20A6EC113D682299550D7A6E0F345E25")]
[InlineData("szdhjfkgdsjzhfgjsdfjzshfgjkskdjfzdjkhgj",
"48593515AEF42567E7FF4BF352D984A41F86D030CBF439A07D1A5C4FDD4F4179")]
[InlineData("It'sTh3Way...TheBunnyW4y",
"48CF44BB1031DDF5F2FB2531AB1F10CAA1C49DC3EE6764D8180CD26A50C6DF1E")]
public void Generate_ShouldGenerateCorrectHash(string input, string expectedOutput)
{
// Arrange
var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));

// Act
var result = Checksum.Generate(stream);

// Assert
Assert.Equal(expectedOutput, result);
}
}
}
40 changes: 40 additions & 0 deletions BunnyCDN.Net.Storage.Tests/SerializerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using Xunit;
using BunnyCDN.Net.Storage.Models;

namespace BunnyCDN.Net.Storage.Tests
{
public class SerializerTests
{
[Fact]
public void Deserialize_ShouldRetunCorrectObject()
{
// Arrange
var input = "{\"Guid\":\"338d2080-bbbf-407f-b756-048c2eb0838f\",\"StorageZoneName\":\"testStorageZone\",\"Path\":\"/testStorageZone/\",\"ObjectName\":\"folderName\",\"Length\":0,\"LastChanged\":\"2022-11-14T09:34:37.747\",\"ServerId\":0,\"ArrayNumber\":0,\"IsDirectory\":true,\"UserId\":\"6fc9081f-43ce-475a-8215-ba2ebfd36d91\",\"ContentType\":\"\",\"DateCreated\":\"2022-11-14T09:34:37.747\",\"StorageZoneId\":1000009,\"Checksum\":null,\"ReplicatedZones\":null}";
var expected = new StorageObject
{
Checksum = null,
ContentType = "",
Guid = Guid.Parse("338d2080-bbbf-407f-b756-048c2eb0838f"),
StorageZoneName = "testStorageZone",
Path = "/testStorageZone/",
ObjectName = "folderName",
Length = 0,
LastChanged = DateTime.Parse("2022-11-14T09:34:37.747"),
ServerId = 0,
ArrayNumber = 0,
IsDirectory = true,
UserId = Guid.Parse("6fc9081f-43ce-475a-8215-ba2ebfd36d91"),
DateCreated = DateTime.Parse("2022-11-14T09:34:37.747"),
StorageZoneId = 1000009,
ReplicatedZones = null
};

// Act
var result = Serializer.Deserialize<StorageObject>(input);

// Assert
Assert.Equivalent(expected, result);
}
}
}
13 changes: 10 additions & 3 deletions BunnyCDN.Net.Storage/BunnyCDN.Net.Storage.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<Version>1.0.5</Version>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0</TargetFrameworks>
<Version>1.1.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Company>BunnyWay d.o.o.</Company>
<Description>The official .NET library used for interacting with the BunnyCDN Storage API.</Description>
Expand All @@ -15,6 +15,7 @@
<PackageTags>storage</PackageTags>
<Copyright>Copyright 2020 BunnyWay d.o.o.</Copyright>
<AssemblyName>BunnyCDN.Net.Storage</AssemblyName>
<LangVersion>10.0</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -24,14 +25,20 @@
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
<ItemGroup Condition="'$(TargetFramework)'!='netstandard2.0'">
<PackageReference Include="System.Text.Json" Version="4.7.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>BunnyCDN.Net.Storage.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<ItemGroup>
<None Include="..\Nuget\icon.png">
<Pack>True</Pack>
Expand Down
54 changes: 41 additions & 13 deletions BunnyCDN.Net.Storage/BunnyCDNStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@

namespace BunnyCDN.Net.Storage
{
public class BunnyCDNStorage
public class BunnyCDNStorage : IDisposable
{
/// <summary>
/// The API access key used for authentication
/// </summary>
public string ApiAccessKey { get; private set; }
#if !NETSTANDARD
private string ApiAccessKey { get; init; }
#else
private string ApiAccessKey { get; set; }
#endif

/// <summary>
/// The name of the storage zone we are working on
/// </summary>
public string StorageZoneName { get; private set; }
#if !NETSTANDARD
private string StorageZoneName { get; init; }
#else
private string StorageZoneName { get; set; }
#endif

/// <summary>
/// The HTTP Client used for the API communication
/// </summary>
private HttpClient _http = null;
private bool _disposed = false;

/// <summary>
/// Initializes a new instance of the BunnyCDNStorage class
Expand All @@ -42,7 +51,7 @@ public BunnyCDNStorage(string storageZoneName, string apiAccessKey, string mainR
_http.BaseAddress = new Uri(this.GetBaseAddress(mainReplicationRegion));
}

#region Delete
#region Delete
/// <summary>
/// Delete an object at the given path. If the object is a directory, the contents will also be deleted.
/// </summary>
Expand All @@ -63,7 +72,7 @@ public async Task<bool> DeleteObjectAsync(string path)
}
#endregion

#region List
#region List
/// <summary>
/// Get the list of storage objects on the given path
/// </summary>
Expand All @@ -84,9 +93,9 @@ public async Task<List<StorageObject>> GetStorageObjectsAsync(string path)
throw this.MapResponseToException(response.StatusCode, normalizedPath);
}
}
#endregion
#endregion

#region Upload
#region Upload
/// <summary>
/// Upload an object from a stream (missing path will be created)
/// </summary>
Expand Down Expand Up @@ -171,9 +180,9 @@ public async Task UploadAsync(string localFilePath, string path, bool validateCh
await UploadAsync(fileStream, path, validateChecksum, sha256Checksum, contentTypeOverride);
}
}
#endregion
#endregion

#region Download
#region Download
/// <summary>
/// Download the object to a local file
/// </summary>
Expand Down Expand Up @@ -220,9 +229,27 @@ public async Task<Stream> DownloadObjectAsStreamAsync(string path)
throw this.MapResponseToException((HttpStatusCode)(int)ex.Status, path);
}
}
#endregion
#endregion

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

#region Utils
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_http.Dispose();
}
_disposed = true;
}
}

#region Utils
/// <summary>
/// Map the API response to the correct BunnyCDNStorageExecption
/// </summary>
Expand All @@ -245,7 +272,7 @@ private BunnyCDNStorageException MapResponseToException(HttpStatusCode statusCod
/// Normalize a path string
/// </summary>
/// <returns>Recognizable, valid string for use against API calls</returns>
public string NormalizePath(string path, bool? isDirectory = null)
internal string NormalizePath(string path, bool? isDirectory = null)
{
// Trim all prepending & tailing whitespace, fix windows-like paths then remove prepending slashes
path = path.Trim()
Expand All @@ -268,7 +295,7 @@ public string NormalizePath(string path, bool? isDirectory = null)

return path;
}
#endregion


/// <summary>
/// Get the base HTTP URL address of the storage endpoint
Expand All @@ -284,5 +311,6 @@ private string GetBaseAddress(string mainReplicationRegion)

return $"https://{mainReplicationRegion}.storage.bunnycdn.com/";
}
#endregion
}
}
2 changes: 1 addition & 1 deletion BunnyCDN.Net.Storage/Checksum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal class Checksum
{
internal static string Generate(Stream stream)
{
using (var sha = new SHA256Managed())
using (var sha = SHA256.Create())
{
byte[] checksumData = sha.ComputeHash(stream);
return BitConverter.ToString(checksumData).Replace("-", String.Empty);
Expand Down
25 changes: 18 additions & 7 deletions BunnyCDN.Net.Storage/Models/StorageObject.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BunnyCDN.Net.Storage.Models
{
Expand All @@ -9,15 +7,24 @@ public class StorageObject
/// <summary>
/// The unique GUID of the file
/// </summary>
public string Guid { get; set; }
public Guid Guid { get; set; }
/// <summary>
/// The ID of the BunnyCDN user that holds the file
/// </summary>
public string UserId { get; set; }
public Guid UserId { get; set; }
/// <summary>
/// The date when the file was created
/// </summary>
public DateTime DateCreated { get; set; }
/// <summary>
/// Content type of the stoage object
/// </summary>
public string ContentType { get; set; }
public int ArrayNumber { get; set; }
/// <summary>
/// File checksum for integrity validation
/// </summary>
public string Checksum { get; set; }

/// <summary>
/// The date when the file was last modified
Expand All @@ -28,6 +35,10 @@ public class StorageObject
/// </summary>
public string StorageZoneName { get; set; }
/// <summary>
/// Replicated zone names
/// </summary>
public string ReplicatedZones { get; set; }
/// <summary>
/// The path to the object
/// </summary>
public string Path { get; set; }
Expand All @@ -38,19 +49,19 @@ public class StorageObject
/// <summary>
/// The total of the object in bytes
/// </summary>
public long Length { get; set; }
public ulong Length { get; set; }
/// <summary>
/// True if the object is a directory
/// </summary>
public bool IsDirectory { get; set; }
/// <summary>
/// The ID of the storage server that the file resides on
/// </summary>
public int ServerId { get; set; }
public uint ServerId { get; set; }
/// <summary>
/// The ID of the storage zone that the object is linked to
/// </summary>
public long StorageZoneId { get; set; }
public ulong StorageZoneId { get; set; }

/// <summary>
/// Gets the full path to the file
Expand Down
4 changes: 1 addition & 3 deletions BunnyCDN.Net.Storage/Serializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
#if NETSTANDARD2_0
#if NETSTANDARD2_0
using Newtonsoft.Json;
#else
using System.Text.Json;
Expand Down