diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index c5b61101..ede6c379 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -33,7 +33,7 @@ - - + + diff --git a/net/tests/Sails.Client.Tests/GlobalUsings.cs b/net/tests/Sails.Client.Tests/GlobalUsings.cs index 51244d1c..ad4d8e84 100644 --- a/net/tests/Sails.Client.Tests/GlobalUsings.cs +++ b/net/tests/Sails.Client.Tests/GlobalUsings.cs @@ -1,6 +1,4 @@ -global using System; -global using System.Collections.Generic; -global using System.Linq; +global using System.Collections.Generic; global using System.Threading; global using System.Threading.Tasks; global using NSubstitute; diff --git a/net/tests/Sails.DemoClient.Tests/AssemblyAttributes.cs b/net/tests/Sails.DemoClient.Tests/AssemblyAttributes.cs index 991f08f6..140d3109 100644 --- a/net/tests/Sails.DemoClient.Tests/AssemblyAttributes.cs +++ b/net/tests/Sails.DemoClient.Tests/AssemblyAttributes.cs @@ -4,3 +4,5 @@ [assembly: AssemblyFixture( typeof(Sails.DemoClient.Tests._Infra.XUnit.Fixtures.SailsFixture))] + +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/net/tests/Sails.DemoClient.Tests/CounterTests.cs b/net/tests/Sails.DemoClient.Tests/CounterTests.cs new file mode 100644 index 00000000..6ec9bbb6 --- /dev/null +++ b/net/tests/Sails.DemoClient.Tests/CounterTests.cs @@ -0,0 +1,107 @@ +using System; +using System.Threading; +using Sails.DemoClient.Tests._Infra.XUnit.Fixtures; +using Sails.Remoting.Abstractions; +using Substrate.NetApi.Model.Types.Base; +using Substrate.NetApi.Model.Types.Primitive; + +namespace Sails.DemoClient.Tests; + +public class CounterTests(SailsFixture sailsFixture) : RemotingTestsBase(sailsFixture) +{ + [Fact] + public async Task Counter_Add_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var counterClient = new Demo.Counter(this.Remoting); + // TODO add listener + //var counterClient = new Demo.CounterListener(this.remoting); + + // act + var dogPosition = new BaseOpt>(new BaseTuple(new I32(0), new I32(0))); + var programId = await demoFactory + .New(counter: new U32(42), dogPosition: dogPosition) + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var result = await counterClient.Add(new U32(10)).SendReceiveAsync(programId, CancellationToken.None); + + // assert + Assert.NotNull(result); + Assert.Equal(52u, result.Value); + // TODO add event assert + } + + [Fact] + public async Task Counter_Sub_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var counterClient = new Demo.Counter(this.Remoting); + // TODO add listener + //var counterClient = new Demo.CounterListener(this.remoting); + + // act + var dogPosition = new BaseOpt>(new BaseTuple(new I32(0), new I32(0))); + var programId = await demoFactory + .New(counter: new U32(42), dogPosition: dogPosition) + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var result = await counterClient.Sub(new U32(10)).SendReceiveAsync(programId, CancellationToken.None); + + // assert + Assert.NotNull(result); + Assert.Equal(32u, result.Value); + // TODO add event assert + } + + [Fact] + public async Task Counter_Query_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var counterClient = new Demo.Counter(this.Remoting); + + // act + var dogPosition = new BaseOpt>(new BaseTuple(new I32(0), new I32(0))); + var programId = await demoFactory + .New(counter: new U32(42), dogPosition: dogPosition) + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var result = await counterClient.Value().QueryAsync(programId, CancellationToken.None); + + // assert + Assert.NotNull(result); + Assert.Equal(42u, result.Value); + } + + [Fact] + public async Task Counter_Query_Throws_NotEnoughGas() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var counterClient = new Demo.Counter(this.Remoting); + + // act + var dogPosition = new BaseOpt>(new BaseTuple(new I32(0), new I32(0))); + var programId = await demoFactory + .New(counter: new U32(42), dogPosition: dogPosition) + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var ex = await Assert.ThrowsAsync(() => counterClient.Value() + .WithGasLimit(new GasUnit(0)) + .QueryAsync(programId, CancellationToken.None) + ); + + // assert + Assert.NotNull(ex); + } +} diff --git a/net/tests/Sails.DemoClient.Tests/DemoFactoryTests.cs b/net/tests/Sails.DemoClient.Tests/DemoFactoryTests.cs index 60f4f229..7b1a2c8a 100644 --- a/net/tests/Sails.DemoClient.Tests/DemoFactoryTests.cs +++ b/net/tests/Sails.DemoClient.Tests/DemoFactoryTests.cs @@ -1,21 +1,51 @@ +using System; +using System.Threading; using Sails.DemoClient.Tests._Infra.XUnit.Fixtures; namespace Sails.DemoClient.Tests; -public sealed class DemoFactoryTests : IAssemblyFixture +public sealed class DemoFactoryTests(SailsFixture fixture) : RemotingTestsBase(fixture) { - public DemoFactoryTests(SailsFixture fixture) + [Fact] + public async Task Test1() { - this.sailsFixture = fixture; - // Assert that IDL file from the Sails.DemoClient project is the same as the one - // from the SailsFixture + var demoContractCodeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); } - private readonly SailsFixture sailsFixture; + [Fact] + public async Task Demo_DefaultConstructor_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + // act + var demoFactory = new Demo.DemoFactory(this.Remoting); + var activate = await demoFactory + .Default() + .ActivateAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + var programId = await activate.ReceiveAsync(CancellationToken.None); + + // assert + Assert.NotNull(programId); + } [Fact] - public async Task Test1() + public async Task Demo_Activation_Throws_NotEnoughGas() { - var demoContractCodeId = await this.sailsFixture.GetDemoContractCodeIdAsync(); + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + // act + var demoFactory = new Demo.DemoFactory(this.Remoting); + var activate = await demoFactory + .Default() + .WithGasLimit(new GasUnit(0)) + .ActivateAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + // throws on ReceiveAsync + var ex = await Assert.ThrowsAsync(() => activate.ReceiveAsync(CancellationToken.None)); + + // assert + // TODO assert custom exception + Assert.NotNull(ex); } } diff --git a/net/tests/Sails.DemoClient.Tests/GlobalUsings.cs b/net/tests/Sails.DemoClient.Tests/GlobalUsings.cs index 8f37676d..797b115d 100644 --- a/net/tests/Sails.DemoClient.Tests/GlobalUsings.cs +++ b/net/tests/Sails.DemoClient.Tests/GlobalUsings.cs @@ -1,3 +1,5 @@ global using System.Threading.Tasks; global using Sails.Tests.Shared.XUnit; global using Xunit; +global using GasUnit = Substrate.NetApi.Model.Types.Primitive.U64; +global using ValueUnit = Substrate.NetApi.Model.Types.Primitive.U128; diff --git a/net/tests/Sails.DemoClient.Tests/PingPongTests.cs b/net/tests/Sails.DemoClient.Tests/PingPongTests.cs new file mode 100644 index 00000000..85e1ea50 --- /dev/null +++ b/net/tests/Sails.DemoClient.Tests/PingPongTests.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading; +using Sails.DemoClient.Tests._Infra.XUnit.Fixtures; +using Sails.Remoting.Abstractions; +using Substrate.Gear.Client.NetApi.Model.Types.Base; +using Substrate.NetApi.Model.Types.Primitive; + +namespace Sails.DemoClient.Tests; + +public class PingPongTests(SailsFixture sailsFixture) : RemotingTestsBase(sailsFixture) +{ + [Fact] + public async Task PingPong_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var pingPongClient = new Demo.PingPong(this.Remoting); + + // act + var programId = await demoFactory + .Default() + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var result = await pingPongClient.Ping(new Str("ping")).SendReceiveAsync(programId, CancellationToken.None); + + // assert + Assert.True(result.Matches(BaseResultEnum.Ok, s => s == "pong")); + } +} diff --git a/net/tests/Sails.DemoClient.Tests/RemotingTestsBase.cs b/net/tests/Sails.DemoClient.Tests/RemotingTestsBase.cs new file mode 100644 index 00000000..078c25bf --- /dev/null +++ b/net/tests/Sails.DemoClient.Tests/RemotingTestsBase.cs @@ -0,0 +1,33 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Sails.DemoClient.Tests._Infra.XUnit.Fixtures; +using Sails.Remoting.Abstractions.Core; +using Sails.Remoting.DependencyInjection; +using Sails.Remoting.Options; + +namespace Sails.DemoClient.Tests; + +public class RemotingTestsBase : IAssemblyFixture +{ + public RemotingTestsBase(SailsFixture fixture) + { + this.SailsFixture = fixture; + // Assert that IDL file from the Sails.DemoClient project is the same as the one + // from the SailsFixture + var serviceCollection = new ServiceCollection(); + serviceCollection.AddRemotingViaNodeClient( + new NodeClientOptions + { + GearNodeUri = this.SailsFixture.GearNodeWsUrl, + }); + var serviceProvider = serviceCollection.BuildServiceProvider(); + this.RemotingProvider = serviceProvider.GetRequiredService(); + this.Remoting = this.RemotingProvider.CreateRemoting(SailsFixture.AliceAccount); + } + + protected static readonly Random Random = new((int)DateTime.UtcNow.Ticks); + + protected readonly SailsFixture SailsFixture; + protected readonly IRemotingProvider RemotingProvider; + protected readonly IRemoting Remoting; +} diff --git a/net/tests/Sails.DemoClient.Tests/Sails.DemoClient.Tests.csproj b/net/tests/Sails.DemoClient.Tests/Sails.DemoClient.Tests.csproj index eeb8d95e..dd914419 100644 --- a/net/tests/Sails.DemoClient.Tests/Sails.DemoClient.Tests.csproj +++ b/net/tests/Sails.DemoClient.Tests/Sails.DemoClient.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/net/tests/Sails.DemoClient.Tests/ValueFeeTests.cs b/net/tests/Sails.DemoClient.Tests/ValueFeeTests.cs new file mode 100644 index 00000000..39f254cf --- /dev/null +++ b/net/tests/Sails.DemoClient.Tests/ValueFeeTests.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading; +using Sails.DemoClient.Tests._Infra.XUnit.Fixtures; +using Sails.Remoting.Abstractions; + +namespace Sails.DemoClient.Tests; + +public class ValueFeeTests(SailsFixture sailsFixture) : RemotingTestsBase(sailsFixture) +{ + [Fact] + public async Task ValueFee_Works() + { + // arrange + var codeId = await this.SailsFixture.GetDemoContractCodeIdAsync(); + + var demoFactory = new Demo.DemoFactory(this.Remoting); + var valueFeeClient = new Demo.ValueFee(this.Remoting); + + // act + var programId = await demoFactory + .Default() + .SendReceiveAsync(codeId, BitConverter.GetBytes(Random.NextInt64()), CancellationToken.None); + + var result = await valueFeeClient + .DoSomethingAndTakeFee() + .WithValue(new ValueUnit(15_000_000_000_000)) + .SendReceiveAsync(programId, CancellationToken.None); + + // assert + Assert.True(result); + // TODO assert balances + } +}