Skip to content

Commit

Permalink
Unity Compatibility + Customizability + Various Improvements (#25)
Browse files Browse the repository at this point in the history
* Thirdweb.Http

Refactor to a cross-platform http client wrapper, must test thoroughly with Unity use case.
May require additional conditional compilation.

* clear out temp auth header

* support oldschool ews and fix header

* Unity config, support and wrappers

Needs cleanup specially config and build pipeline

* Generic APIs, move Unity-specific code back to Unity

* dupe header fix

* zkcandy support

* HttpTests

* HttpContent

* Update ThirdwebHttpContent.cs

* final http tests

* improved tx tests, bump gas per pubdata

* Create Thirdweb.ZkSmartWallet.Tests.cs

* Update Thirdweb.PrivateKeyWallet.Tests.cs

* Update Thirdweb.Transactions.Tests.cs

* improve estimations
  • Loading branch information
0xFirekeeper authored Jun 12, 2024
1 parent 71dee5c commit b22d405
Show file tree
Hide file tree
Showing 29 changed files with 1,058 additions and 399 deletions.
4 changes: 2 additions & 2 deletions Thirdweb.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@
// var txHash = await ThirdwebTransaction.Send(transaction: tx);
// Console.WriteLine($"Transaction hash: {txHash}");

var zkSmartWallet = await SmartWallet.Create(client: client, personalWallet: privateKeyWallet, chainId: 324, gasless: true);
var zkSmartWallet = await SmartWallet.Create(client: client, personalWallet: privateKeyWallet, chainId: 302, gasless: true);
Console.WriteLine($"Smart wallet address: {await zkSmartWallet.GetAddress()}");
var zkAaTx = await ThirdwebTransaction.Create(client, zkSmartWallet, new ThirdwebTransactionInput() { From = await zkSmartWallet.GetAddress(), To = await zkSmartWallet.GetAddress(), }, 324);
var zkAaTx = await ThirdwebTransaction.Create(client, zkSmartWallet, new ThirdwebTransactionInput() { From = await zkSmartWallet.GetAddress(), To = await zkSmartWallet.GetAddress(), }, 302);
var zkSyncSignatureBasedAaTxHash = await ThirdwebTransaction.Send(zkAaTx);
Console.WriteLine($"Transaction hash: {zkSyncSignatureBasedAaTxHash}");

Expand Down
2 changes: 1 addition & 1 deletion Thirdweb.Tests/Thirdweb.Contracts.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public ContractsTests(ITestOutputHelper output)
[Fact]
public async Task FetchAbi()
{
var abi = await ThirdwebContract.FetchAbi(address: "0x1320Cafa93fb53Ed9068E3272cb270adbBEf149C", chainId: 84532);
var abi = await ThirdwebContract.FetchAbi(client: ThirdwebClient.Create(secretKey: _secretKey), address: "0x1320Cafa93fb53Ed9068E3272cb270adbBEf149C", chainId: 84532);
Assert.NotNull(abi);
Assert.NotEmpty(abi);
}
Expand Down
358 changes: 358 additions & 0 deletions Thirdweb.Tests/Thirdweb.Http.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,358 @@
using System.Numerics;
using System.Text;

namespace Thirdweb.Tests
{
public class HttpTests : BaseTests
{
public HttpTests(ITestOutputHelper output)
: base(output) { }

#region ThirdwebHttpClient

[Fact]
public async Task GetAsync_ShouldReturnSuccessResponse()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var requestUri = "https://jsonplaceholder.typicode.com/posts/1";

// Act
var response = await httpClient.GetAsync(requestUri);

// Assert
Assert.True(response.IsSuccessStatusCode);
Assert.Equal(200, response.StatusCode);
}

[Fact]
public async Task PostAsync_ShouldReturnSuccessResponse()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var requestUri = "https://jsonplaceholder.typicode.com/posts";
var content = new StringContent("{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}", System.Text.Encoding.UTF8, "application/json");

// Act
var response = await httpClient.PostAsync(requestUri, content);

// Assert
Assert.True(response.IsSuccessStatusCode);
Assert.Equal(201, response.StatusCode);
}

[Fact]
public void SetHeaders_ShouldAddHeaders()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var headers = new Dictionary<string, string> { { "Authorization", "Bearer token" } };

// Act
httpClient.SetHeaders(headers);

// Assert
_ = Assert.Single(httpClient.Headers);
Assert.Equal("Bearer token", httpClient.Headers["Authorization"]);
}

[Fact]
public void ClearHeaders_ShouldRemoveAllHeaders()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var headers = new Dictionary<string, string> { { "Authorization", "Bearer token" } };
httpClient.SetHeaders(headers);

// Act
httpClient.ClearHeaders();

// Assert
Assert.Empty(httpClient.Headers);
}

[Fact]
public void AddHeader_ShouldAddHeader()
{
// Arrange
var httpClient = new ThirdwebHttpClient();

// Act
httpClient.AddHeader("Authorization", "Bearer token");

// Assert
_ = Assert.Single(httpClient.Headers);
Assert.Equal("Bearer token", httpClient.Headers["Authorization"]);
}

[Fact]
public void RemoveHeader_ShouldRemoveHeader()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
httpClient.AddHeader("Authorization", "Bearer token");

// Act
httpClient.RemoveHeader("Authorization");

// Assert
Assert.Empty(httpClient.Headers);
}

[Fact]
public async Task PutAsync_ShouldThrowNotImplementedException()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var requestUri = "https://jsonplaceholder.typicode.com/posts/1";
var content = new StringContent("{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}", System.Text.Encoding.UTF8, "application/json");

// Act & Assert
_ = await Assert.ThrowsAsync<NotImplementedException>(() => httpClient.PutAsync(requestUri, content));
}

[Fact]
public async Task DeleteAsync_ShouldThrowNotImplementedException()
{
// Arrange
var httpClient = new ThirdwebHttpClient();
var requestUri = "https://jsonplaceholder.typicode.com/posts/1";

// Act & Assert
_ = await Assert.ThrowsAsync<NotImplementedException>(() => httpClient.DeleteAsync(requestUri));
}

[Fact]
public void Dispose_ShouldDisposeHttpClient()
{
// Arrange
var httpClient = new ThirdwebHttpClient();

// Act
httpClient.Dispose();

// Assert
// Check that disposing twice does not throw an exception
var exception = Record.Exception(() => httpClient.Dispose());
Assert.Null(exception);
}

#endregion

#region ThirdwebHttpContent

[Fact]
public async Task Constructor_WithString_ShouldInitializeContent()
{
// Arrange
var contentString = "Hello, World!";
var expectedBytes = Encoding.UTF8.GetBytes(contentString);

// Act
var content = new ThirdwebHttpContent(contentString);
var resultBytes = await content.ReadAsByteArrayAsync();

// Assert
Assert.Equal(expectedBytes, resultBytes);
}

[Fact]
public async Task Constructor_WithByteArray_ShouldInitializeContent()
{
// Arrange
var contentBytes = Encoding.UTF8.GetBytes("Hello, World!");

// Act
var content = new ThirdwebHttpContent(contentBytes);
var resultBytes = await content.ReadAsByteArrayAsync();

// Assert
Assert.Equal(contentBytes, resultBytes);
}

[Fact]
public async Task Constructor_WithStream_ShouldInitializeContent()
{
// Arrange
var contentString = "Hello, World!";
var contentStream = new MemoryStream(Encoding.UTF8.GetBytes(contentString));
var expectedBytes = Encoding.UTF8.GetBytes(contentString);

// Act
var content = new ThirdwebHttpContent(contentStream);
var resultBytes = await content.ReadAsByteArrayAsync();

// Assert
Assert.Equal(expectedBytes, resultBytes);
}

[Fact]
public async Task ReadAsStringAsync_ShouldReturnContentAsString()
{
// Arrange
var contentString = "Hello, World!";
var content = new ThirdwebHttpContent(contentString);

// Act
var resultString = await content.ReadAsStringAsync();

// Assert
Assert.Equal(contentString, resultString);
}

[Fact]
public async Task ReadAsByteArrayAsync_ShouldReturnContentAsByteArray()
{
// Arrange
var contentBytes = Encoding.UTF8.GetBytes("Hello, World!");
var content = new ThirdwebHttpContent(contentBytes);

// Act
var resultBytes = await content.ReadAsByteArrayAsync();

// Assert
Assert.Equal(contentBytes, resultBytes);
}

[Fact]
public async Task ReadAsStreamAsync_ShouldReturnContentAsStream()
{
// Arrange
var contentString = "Hello, World!";
var content = new ThirdwebHttpContent(contentString);
var expectedStream = new MemoryStream(Encoding.UTF8.GetBytes(contentString));

// Act
var resultStream = await content.ReadAsStreamAsync();

// Assert
using (var reader = new StreamReader(resultStream))
using (var expectedReader = new StreamReader(expectedStream))
{
var resultString = await reader.ReadToEndAsync();
var expectedString = await expectedReader.ReadToEndAsync();
Assert.Equal(expectedString, resultString);
}
}

#nullable disable

[Fact]
public void Constructor_WithNullString_ShouldThrowArgumentNullException()
{
// Arrange, Act & Assert
_ = Assert.Throws<ArgumentNullException>(() => new ThirdwebHttpContent((string)null));
}

[Fact]
public void Constructor_WithNullByteArray_ShouldThrowArgumentNullException()
{
// Arrange, Act & Assert
_ = Assert.Throws<ArgumentNullException>(() => new ThirdwebHttpContent((byte[])null));
}

[Fact]
public void Constructor_WithNullStream_ShouldThrowArgumentNullException()
{
// Arrange, Act & Assert
_ = Assert.Throws<ArgumentNullException>(() => new ThirdwebHttpContent((Stream)null));
}

#nullable restore

#endregion

#region ThirdwebHttpResponseMessage

[Fact]
public void Constructor_ShouldInitializeProperties()
{
// Arrange
var statusCode = 200;
var content = new ThirdwebHttpContent("Test Content");
var isSuccessStatusCode = true;

// Act
var responseMessage = new ThirdwebHttpResponseMessage(statusCode, content, isSuccessStatusCode);

// Assert
Assert.Equal(statusCode, responseMessage.StatusCode);
Assert.Equal(content, responseMessage.Content);
Assert.Equal(isSuccessStatusCode, responseMessage.IsSuccessStatusCode);
}

[Fact]
public void EnsureSuccessStatusCode_ShouldReturnSelfOnSuccess()
{
// Arrange
var statusCode = 200;
var content = new ThirdwebHttpContent("Test Content");
var isSuccessStatusCode = true;
var responseMessage = new ThirdwebHttpResponseMessage(statusCode, content, isSuccessStatusCode);

// Act
var result = responseMessage.EnsureSuccessStatusCode();

// Assert
Assert.Equal(responseMessage, result);
}

[Fact]
public async Task EnsureSuccessStatusCode_ShouldThrowExceptionOnFailure()
{
// Arrange
var statusCode = 400;
var content = new ThirdwebHttpContent("Error Content");
var isSuccessStatusCode = false;
var responseMessage = new ThirdwebHttpResponseMessage(statusCode, content, isSuccessStatusCode);

// Act & Assert
var exception = await Assert.ThrowsAsync<Exception>(() => Task.FromResult(responseMessage.EnsureSuccessStatusCode()));
var contentString = await content.ReadAsStringAsync();
Assert.Equal($"Request failed with status code {statusCode} and content: {contentString}", exception.Message);
}

[Fact]
public void StatusCode_ShouldSetAndGet()
{
// Arrange
var responseMessage = new ThirdwebHttpResponseMessage(200, new ThirdwebHttpContent("Test Content"), true);

// Act
responseMessage.StatusCode = 404;

// Assert
Assert.Equal(404, responseMessage.StatusCode);
}

[Fact]
public void Content_ShouldSetAndGet()
{
// Arrange
var initialContent = new ThirdwebHttpContent("Initial Content");
var newContent = new ThirdwebHttpContent("New Content");
var responseMessage = new ThirdwebHttpResponseMessage(200, initialContent, true);

// Act
responseMessage.Content = newContent;

// Assert
Assert.Equal(newContent, responseMessage.Content);
}

[Fact]
public void IsSuccessStatusCode_ShouldSetAndGet()
{
// Arrange
var responseMessage = new ThirdwebHttpResponseMessage(200, new ThirdwebHttpContent("Test Content"), true);

// Act
responseMessage.IsSuccessStatusCode = false;

// Assert
Assert.False(responseMessage.IsSuccessStatusCode);
}

#endregion
}
}
Loading

0 comments on commit b22d405

Please sign in to comment.