mirror of
https://github.com/opengram-server/opengram.git
synced 2026-07-19 04:00:18 +03:00
Initial commit
This commit is contained in:
+214
@@ -0,0 +1,214 @@
|
||||
//using EventFlow.Extensions;
|
||||
//using Microsoft.Extensions.DependencyInjection;
|
||||
//using MyTelegram.Domain.Aggregates.Channel;
|
||||
//using MyTelegram.Domain.Aggregates.Messaging;
|
||||
//using MyTelegram.Domain.Aggregates.User;
|
||||
//using MyTelegram.Domain.Commands.Channel;
|
||||
//using MyTelegram.Domain.Commands.Messaging;
|
||||
//using MyTelegram.Domain.Commands.User;
|
||||
//using MyTelegram.Queries;
|
||||
//using MyTelegram.QueryHandlers.InMemory;
|
||||
//using MyTelegram.ReadModel.InMemory;
|
||||
//using MyTelegram.TestBase;
|
||||
//using Shouldly;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Threading.Tasks;
|
||||
//using MyTelegram.Domain.Aggregates.Temp;
|
||||
//using Xunit;
|
||||
|
||||
//namespace MyTelegram.Domain.IntegrationTests.Aggregates.Sagas;
|
||||
|
||||
//public class MessageSagaIntegrationTests : IntegrationTest
|
||||
//{
|
||||
// [Fact]
|
||||
// public async Task SendMessage_To_UserPeer_Test()
|
||||
// {
|
||||
// var senderPeerId = 1;
|
||||
// var recipientPeerId = 2;
|
||||
// var message = A<string>();
|
||||
// await CreateUserAsync(senderPeerId);
|
||||
// await CreateUserAsync(recipientPeerId);
|
||||
|
||||
// await SendMessageToPeerAsync(senderPeerId.ToUserPeer(), recipientPeerId.ToUserPeer(), message);
|
||||
|
||||
// var outboxMessageReadModel = await GetLatestMessageAsync(senderPeerId);
|
||||
// var inboxMessageReadModel = await GetLatestMessageAsync(recipientPeerId);
|
||||
// outboxMessageReadModel.Message.ShouldBe(message);
|
||||
// outboxMessageReadModel.Out.ShouldBeTrue();
|
||||
// inboxMessageReadModel.Message.ShouldBe(message);
|
||||
// inboxMessageReadModel.Out.ShouldBeFalse();
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public async Task SendMessage_To_ChatPeer_Test()
|
||||
// {
|
||||
// var senderPeerId = 1;
|
||||
// var recipientPeerId = 2L;
|
||||
// var message = A<string>();
|
||||
// var chatId = MyTelegramConsts.ChatIdInitId + 1;
|
||||
// await CreateUserAsync(senderPeerId);
|
||||
// await CreateUserAsync(recipientPeerId);
|
||||
// await CreateChatAsync(chatId, senderPeerId, new[] { recipientPeerId });
|
||||
|
||||
// await SendMessageToPeerAsync(senderPeerId.ToUserPeer(), chatId.ToChatPeer(), message);
|
||||
|
||||
// var member1MessageReadModel = await GetLatestMessageAsync(senderPeerId);
|
||||
// var member2MessageReadModel = await GetLatestMessageAsync(recipientPeerId);
|
||||
// member1MessageReadModel.Out.ShouldBeTrue();
|
||||
// member1MessageReadModel.SenderPeerId.ShouldBe(senderPeerId);
|
||||
// member1MessageReadModel.ToPeerId.ShouldBe(chatId);
|
||||
// member1MessageReadModel.Message.ShouldBe(message);
|
||||
// member2MessageReadModel.Out.ShouldBeFalse();
|
||||
// member2MessageReadModel.Message.ShouldBe(message);
|
||||
// member2MessageReadModel.SenderPeerId.ShouldBe(senderPeerId);
|
||||
// member2MessageReadModel.ToPeerId.ShouldBe(chatId);
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public async Task SendMessage_To_ChannelPeer_Test()
|
||||
// {
|
||||
// // Arrange
|
||||
// var senderPeerId = 1;
|
||||
// var recipientPeerId = 2;
|
||||
// var message = A<string>();
|
||||
// var channelId = MyTelegramConsts.ChannelInitId + 1;
|
||||
// await CreateUserAsync(senderPeerId);
|
||||
// await CreateUserAsync(recipientPeerId);
|
||||
// await CreateChannelAsync(channelId, senderPeerId);
|
||||
// await AddChannelMemberAsync(channelId, recipientPeerId, senderPeerId);
|
||||
|
||||
// // Act
|
||||
// await SendMessageToPeerAsync(senderPeerId.ToUserPeer(), channelId.ToChannelPeer(), message);
|
||||
|
||||
// // Assert
|
||||
// var readModel = await GetLatestMessageAsync(channelId);
|
||||
// readModel.Message.ShouldBe(message);
|
||||
// readModel.Out.ShouldBeTrue();
|
||||
// readModel.OwnerPeerId.ShouldBe(channelId);
|
||||
// readModel.SenderPeerId.ShouldBe(senderPeerId);
|
||||
// var channelReadModel = await QueryProcessor.ProcessAsync(new GetChannelByIdQuery(channelId), default)
|
||||
// ;
|
||||
// channelReadModel.TopMessageId.ShouldBe(readModel.MessageId);
|
||||
// }
|
||||
|
||||
// private async Task<IMessageReadModel> GetLatestMessageAsync(long ownerPeerId)
|
||||
// {
|
||||
// var readModels = await QueryProcessor.ProcessAsync(new GetMessagesQuery(ownerPeerId,
|
||||
// MessageType.Text,
|
||||
// null,
|
||||
// null,
|
||||
// 0,
|
||||
// 10,
|
||||
// null,
|
||||
// null,
|
||||
// 0,
|
||||
// 0), default);
|
||||
|
||||
// var maxMessageId = readModels.Max(p => p.MessageId);
|
||||
// return readModels.Single(p => p.MessageId == maxMessageId);
|
||||
// }
|
||||
|
||||
// private Task AddChannelMemberAsync(long channelId,
|
||||
// long memberPeerId,
|
||||
// long inviterId)
|
||||
// {
|
||||
// var command = new StartInviteToChannelCommand(TempId.New,
|
||||
// A<RequestInfo>() with { UserId = inviterId },
|
||||
// channelId,
|
||||
// true,
|
||||
// true,
|
||||
// inviterId,
|
||||
// new[] { memberPeerId },
|
||||
// Array.Empty<long>(),
|
||||
// //A<int>(),
|
||||
// //A<long>(),
|
||||
// Array.Empty<long>(),
|
||||
// A<int>(),
|
||||
// A<long>(),
|
||||
// ChatJoinType.InvitedByAdmin);
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// private Task SendMessageToPeerAsync(Peer senderPeer, Peer toPeer, string message)
|
||||
// {
|
||||
// var randomId = A<long>();
|
||||
// var messageId = A<int>();
|
||||
// var aggregateId = MessageId.Create(senderPeer.PeerId, messageId);
|
||||
// var item = new MessageItem(
|
||||
// toPeer.PeerType == PeerType.Channel ? toPeer : senderPeer,
|
||||
// toPeer,
|
||||
// senderPeer,
|
||||
// senderPeer.PeerId,
|
||||
// messageId,
|
||||
// message,
|
||||
// A<int>(),
|
||||
// randomId,
|
||||
// true);
|
||||
// var command = new CreateOutboxMessageCommand(aggregateId, A<RequestInfo>() with { UserId = senderPeer.PeerId }, item);
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// private Task CreateChannelAsync(long channelId, long creatorId)
|
||||
// {
|
||||
// var title = A<string>();
|
||||
// var command = new CreateChannelCommand(ChannelId.Create(channelId),
|
||||
// A<RequestInfo>() with { UserId = creatorId },
|
||||
// channelId,
|
||||
// creatorId,
|
||||
// title,
|
||||
// true,
|
||||
// false,
|
||||
// null,
|
||||
// null,
|
||||
// 0,
|
||||
// A<int>(),
|
||||
// A<long>(),
|
||||
// A<string>(),
|
||||
// 0,
|
||||
// false,
|
||||
// null, null, null
|
||||
// );
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// private Task CreateChatAsync(long chatId, long creatorId, IReadOnlyList<long> memberUidList)
|
||||
// {
|
||||
// var command = new CreateChatCommand(ChatId.Create(chatId),
|
||||
// A<RequestInfo>() with { UserId = creatorId },
|
||||
// chatId,
|
||||
// creatorId,
|
||||
// A<string>(),
|
||||
// memberUidList,
|
||||
// A<int>(),
|
||||
// A<long>(),
|
||||
// A<string>());
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// private Task CreateUserAsync(long userId)
|
||||
// {
|
||||
// var command = new CreateUserCommand(UserId.Create(userId),
|
||||
// A<RequestInfo>(),
|
||||
// userId,
|
||||
// 1,
|
||||
// userId.ToString(),
|
||||
// userId.ToString(),
|
||||
// null);
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// protected override IServiceProvider Configure(IEventFlowOptions options)
|
||||
// {
|
||||
// options.AddDefaults(typeof(MyTelegram.Domain.IChatInviteLinkHelper).Assembly);
|
||||
// options.ServiceCollection.AddMyEventFlow();
|
||||
// options.ServiceCollection.AddSingleton<IIdGenerator, SimpleInMemoryIdGenerator>();
|
||||
// options.AddInMemoryReadModel();
|
||||
// options.AddInMemoryQueryHandlers();
|
||||
|
||||
// var serviceProvider = options.ServiceCollection.BuildServiceProvider();
|
||||
|
||||
// return serviceProvider;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,4 @@
|
||||
// Global using directives
|
||||
|
||||
global using EventFlow;
|
||||
global using MyTelegram.ReadModel.Interfaces;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MyTelegram.QueryHandlers.InMemory\MyTelegram.QueryHandlers.InMemory.csproj" />
|
||||
<ProjectReference Include="..\..\src\MyTelegram.TestBase\MyTelegram.TestBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Fody">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,23 @@
|
||||
global using EventFlow.Aggregates;
|
||||
global using EventFlow.Exceptions;
|
||||
global using EventFlow.Sagas;
|
||||
global using Moq;
|
||||
global using MyTelegram.Domain.Aggregates.AppCode;
|
||||
global using MyTelegram.Domain.Aggregates.Channel;
|
||||
global using MyTelegram.Domain.Aggregates.Messaging;
|
||||
global using MyTelegram.Domain.Aggregates.User;
|
||||
global using MyTelegram.Domain.Events.AppCode;
|
||||
global using MyTelegram.Domain.Events.Channel;
|
||||
global using MyTelegram.Domain.Events.Messaging;
|
||||
global using MyTelegram.Domain.Events.User;
|
||||
global using MyTelegram.Domain.Extensions;
|
||||
global using MyTelegram.Domain.Sagas;
|
||||
global using MyTelegram.Domain.Sagas.Identities;
|
||||
global using MyTelegram.TestBase;
|
||||
global using Shouldly;
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
global using Xunit;
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
//namespace MyTelegram.Domain.Tests.IntegrationTests.Sagas;
|
||||
|
||||
//public class MessageSagaIntegrationTests : IntegrationTest
|
||||
//{
|
||||
// [Fact]
|
||||
// public async Task SendMessage_To_UserPeer_Test()
|
||||
// {
|
||||
// var senderPeerId = 1;
|
||||
// var recipientPeerId = 2;
|
||||
// await CreateUserAsync(senderPeerId).ConfigureAwait(false);
|
||||
// await CreateUserAsync(recipientPeerId).ConfigureAwait(false);
|
||||
|
||||
// var randomId = 1;
|
||||
// var aggregateId = MessageId.CreateWithRandomId(senderPeerId, randomId);
|
||||
// var messageItem = new MessageItem(aggregateId,
|
||||
// new Peer(PeerType.User, senderPeerId),
|
||||
// new Peer(PeerType.User, recipientPeerId),
|
||||
// new Peer(PeerType.User, senderPeerId),
|
||||
// 0,
|
||||
// "test message",
|
||||
// DateTime.UtcNow.ToTimestamp(),
|
||||
// randomId,
|
||||
// true
|
||||
// );
|
||||
// var command = new StartSendMessageCommand(aggregateId, A<RequestInfo>(), messageItem, correlationId: Guid.NewGuid());
|
||||
|
||||
// await CommandBus.PublishAsync(command, default).ConfigureAwait(false);
|
||||
|
||||
|
||||
// //var outboxMessageReadModel=await QueryProcessor.ProcessAsync(new )
|
||||
// }
|
||||
|
||||
// private Task CreateUserAsync(int userId)
|
||||
// {
|
||||
// var command = new CreateUserCommand(UserId.Create(userId),
|
||||
// A<RequestInfo>(),
|
||||
// userId,
|
||||
// 1,
|
||||
// userId.ToString(),
|
||||
// userId.ToString(),
|
||||
// null);
|
||||
// return CommandBus.PublishAsync(command, default);
|
||||
// }
|
||||
|
||||
// protected override IServiceProvider Configure(IEventFlowOptions options)
|
||||
// {
|
||||
// options.AddDefaults(typeof(StartSendMessageCommand).Assembly);
|
||||
// options.ServiceCollection.AddMyEventFlow();
|
||||
// //options.ServiceCollection.AddSingleton<IIdGenerator, SimpleInMemoryIdGenerator>();
|
||||
// var serviceProvider = options.ServiceCollection.BuildServiceProvider();
|
||||
// //IdGeneratorFactory.SetDefaultIdGenerator(serviceProvider.GetRequiredService<IIdGenerator>());
|
||||
|
||||
|
||||
// return serviceProvider;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MyTelegram.Domain\MyTelegram.Domain.csproj" />
|
||||
<ProjectReference Include="..\..\src\MyTelegram.TestBase\MyTelegram.TestBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Fody">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
using Shouldly;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Aggregates.AppCode;
|
||||
|
||||
public class AppCodeAggregateTests : TestsFor<AppCodeAggregate>
|
||||
{
|
||||
private readonly string _inValidPhoneCodeHash = "2";
|
||||
private readonly int _maxFailedCount = 5;
|
||||
private readonly string _phoneNumber = "0";
|
||||
private readonly string _validPhoneCodeHash = "1";
|
||||
public AppCodeAggregateTests()
|
||||
{
|
||||
Fixture.Customize<AppCodeId>(c => c.FromFactory(() => AppCodeId.Create(_phoneNumber, _validPhoneCodeHash)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cancel_AppCode_Success()
|
||||
{
|
||||
CreateAppCodeAggregate();
|
||||
|
||||
Sut.CancelCode(A<RequestInfo>(), _phoneNumber, _validPhoneCodeHash);
|
||||
|
||||
Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<AppCodeCanceledEvent>();
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignInCode_Exceeded_Max_Failed_Count_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate();
|
||||
// var aggregateEvent = new CheckSignInCodeCompletedEvent(A<RequestInfo>(), false, 1);
|
||||
// var aggregateEvents = Enumerable.Repeat(aggregateEvent, _maxFailedCount + 1);
|
||||
// var domainEvents = aggregateEvents.Select((p,
|
||||
// index) => ADomainEvent<AppCodeAggregate, AppCodeId, CheckSignInCodeCompletedEvent>(p, Sut.Version + index + 1))
|
||||
// .ToList();
|
||||
// Sut.ApplyEvents(domainEvents);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignInCode(A<RequestInfo>(), _validPhoneCodeHash, A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.PhoneCodeInvalid.Message);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignInCode_With_Canceled_Code_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate();
|
||||
// var domainEvent = ADomainEvent<AppCodeAggregate, AppCodeId, AppCodeCanceledEvent>(Sut.Version + 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignInCode(A<RequestInfo>(), _validPhoneCodeHash, A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.PhoneCodeExpired.Message);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public void CheckSignInCode_With_Correct_PhoneCode()
|
||||
{
|
||||
CreateAppCodeAggregate();
|
||||
|
||||
Sut.CheckSignInCode(A<RequestInfo>(), _validPhoneCodeHash, A<long>());
|
||||
|
||||
Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckSignInCodeCompletedEvent>();
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignInCode_With_Empty_PhoneCode_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate(expireMinutes: -5);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignInCode(A<RequestInfo>(), string.Empty, A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.PhoneCodeEmpty.Message);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignInCode_With_Expire_PhoneCode_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate(expireMinutes: -5);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignInCode(A<RequestInfo>(), _validPhoneCodeHash, A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.PhoneCodeExpired.Message);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public void CheckSignInCode_With_Invalid_PhoneCode()
|
||||
{
|
||||
CreateAppCodeAggregate();
|
||||
|
||||
Sut.CheckSignInCode(A<RequestInfo>(), _inValidPhoneCodeHash, A<long>());
|
||||
|
||||
var checkSignUpCodeCompletedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckSignInCodeCompletedEvent>();
|
||||
checkSignUpCodeCompletedEvent.IsCodeValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignUpCode_Exceeded_Max_Failed_Count_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate();
|
||||
// var aggregateEvent = new CheckSignUpCodeCompletedEvent(A<RequestInfo>(), false, 1, 0, "0", "0", null, Guid.Empty);
|
||||
// var aggregateEvents = Enumerable.Repeat(aggregateEvent, _maxFailedCount + 1);
|
||||
// var domainEvents = aggregateEvents.Select((p,
|
||||
// index) => ADomainEvent<AppCodeAggregate, AppCodeId, CheckSignUpCodeCompletedEvent>(p, Sut.Version + index + 1))
|
||||
// .ToList();
|
||||
// Sut.ApplyEvents(domainEvents);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignUpCode(A<RequestInfo>(),
|
||||
// 0,
|
||||
// _validPhoneCodeHash,
|
||||
// 0,
|
||||
// _phoneNumber,
|
||||
// "0",
|
||||
// null,
|
||||
// Guid.Empty));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrorMessages.PhoneCodeInvalid);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignUpCode_With_Canceled_Code_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate();
|
||||
// var domainEvent = ADomainEvent<AppCodeAggregate, AppCodeId, AppCodeCanceledEvent>(Sut.Version + 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignUpCode(A<RequestInfo>(),
|
||||
// 0,
|
||||
// _validPhoneCodeHash,
|
||||
// 0,
|
||||
// _phoneNumber,
|
||||
// "0",
|
||||
// null,
|
||||
// Guid.Empty));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrorMessages.PhoneCodeExpired);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public void CheckSignUpCode_With_Correct_PhoneCode_For_New_User()
|
||||
{
|
||||
CreateAppCodeAggregate();
|
||||
|
||||
Sut.CheckSignUpCode(
|
||||
A<RequestInfo>(),
|
||||
0, _validPhoneCodeHash, 0, _phoneNumber, "0", null);
|
||||
|
||||
//Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<SignUpRequiredEvent>();
|
||||
var uncommittedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckSignUpCodeCompletedEvent>();
|
||||
uncommittedEvent.IsCodeValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckSignUpCode_With_Correct_PhoneCode_For_Old_User()
|
||||
{
|
||||
var oldUid = 1;
|
||||
CreateAppCodeAggregate(oldUid);
|
||||
|
||||
Sut.CheckSignUpCode(A<RequestInfo>(), oldUid, _validPhoneCodeHash, 0, _phoneNumber, "0", null);
|
||||
|
||||
var checkSignUpCodeCompletedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckSignUpCodeCompletedEvent>();
|
||||
checkSignUpCodeCompletedEvent.IsCodeValid.ShouldBeTrue();
|
||||
checkSignUpCodeCompletedEvent.UserId.ShouldBe(oldUid);
|
||||
checkSignUpCodeCompletedEvent.PhoneNumber.ShouldBe(_phoneNumber);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignUpCode_With_Empty_PhoneCode_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate(expireMinutes: -5);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignUpCode(A<RequestInfo>(),
|
||||
// 0,
|
||||
// string.Empty,
|
||||
// 0,
|
||||
// _phoneNumber,
|
||||
// "0",
|
||||
// null,
|
||||
// Guid.Empty));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrorMessages.PhoneCodeEmpty);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignUpCode_With_Expire_PhoneCode_Throws_Exception()
|
||||
//{
|
||||
// CreateAppCodeAggregate(expireMinutes: -5);
|
||||
|
||||
// var exception = Assert.Throws<UserFriendlyException>(() => Sut.CheckSignUpCode(A<RequestInfo>(),
|
||||
// 0,
|
||||
// _validPhoneCodeHash,
|
||||
// 0,
|
||||
// _phoneNumber,
|
||||
// "0",
|
||||
// null,
|
||||
// Guid.Empty));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrorMessages.PhoneCodeExpired);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CheckSignUpCode_With_Invalid_PhoneCode()
|
||||
//{
|
||||
// CreateAppCodeAggregate();
|
||||
|
||||
// Sut.CheckSignUpCode(A<RequestInfo>(), 0, _inValidPhoneCodeHash, 0, _phoneNumber, "0", null, Guid.Empty);
|
||||
|
||||
// var checkSignUpCodeCompletedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckSignUpCodeCompletedEvent>();
|
||||
// checkSignUpCodeCompletedEvent.IsCodeValid.ShouldBeFalse();
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void CreateAppCode_Success()
|
||||
//{
|
||||
// Sut.Create(A<RequestInfo>(), A<long>(), A<string>(), A<string>(), A<int>(), A<string>(), A<long>());
|
||||
|
||||
// Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<AppCodeCreatedEvent>();
|
||||
//}
|
||||
|
||||
private void CreateAppCodeAggregate(long uid = 0, int expireMinutes = 5)
|
||||
{
|
||||
var aggregateId = A<AppCodeId>();
|
||||
var appCodeCreatedEvent = new AppCodeCreatedEvent(A<RequestInfo>(),
|
||||
uid,
|
||||
_phoneNumber,
|
||||
"0",
|
||||
DateTime.UtcNow.AddMinutes(expireMinutes).ToTimestamp(),
|
||||
_validPhoneCodeHash,
|
||||
0);
|
||||
|
||||
Sut.ApplyEvents(new IDomainEvent[]
|
||||
{
|
||||
new DomainEvent<AppCodeAggregate, AppCodeId, AppCodeCreatedEvent>(appCodeCreatedEvent,
|
||||
Metadata.Empty,
|
||||
DateTimeOffset.UtcNow,
|
||||
aggregateId,
|
||||
1)
|
||||
});
|
||||
}
|
||||
}
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
using MyTelegram.Schema;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Aggregates.Channel;
|
||||
|
||||
public class ChannelAggregateTests : TestsFor<ChannelAggregate>
|
||||
{
|
||||
public ChannelAggregateTests()
|
||||
{
|
||||
Fixture.Customize<ChannelId>(x => x.FromFactory(() => ChannelId.Create(MyTelegramConsts.ChannelInitId + 1)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditAbout_For_Not_Exists_Channel_Throws_Exception()
|
||||
{
|
||||
Assert.Throws<DomainError>(() => Sut.EditAbout(A<RequestInfo>(), 1, "test"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditAbout_Success_Test()
|
||||
{
|
||||
var about = "test about";
|
||||
var aggregateEvent = A<ChannelCreatedEvent>();
|
||||
var channelCreatedEvent = ADomainEvent<ChannelAggregate, ChannelId, ChannelCreatedEvent>(aggregateEvent, 1);
|
||||
Sut.ApplyEvents(new IDomainEvent[] { channelCreatedEvent });
|
||||
var requestInfo = A<RequestInfo>() with { UserId = aggregateEvent.CreatorId };
|
||||
|
||||
Sut.EditAbout(requestInfo, aggregateEvent.CreatorId, about);
|
||||
|
||||
var uncommittedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<ChannelAboutEditedEvent>();
|
||||
uncommittedEvent.About.ShouldBe(about);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditAbout_With_Text_Length_GreaterThan_ChatAbout_Max_Length_Throws_Exception()
|
||||
{
|
||||
var longAbout = string.Join("", Enumerable.Repeat("a", MyTelegramConsts.ChatAboutMaxLength + 1));
|
||||
var aggregateEvent = A<ChannelCreatedEvent>();
|
||||
var channelCreatedEvent = ADomainEvent<ChannelAggregate, ChannelId, ChannelCreatedEvent>(aggregateEvent, 1);
|
||||
Sut.ApplyEvents(new IDomainEvent[] { channelCreatedEvent });
|
||||
var requestInfo = A<RequestInfo>() with { UserId = aggregateEvent.CreatorId };
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() => Sut.EditAbout(requestInfo, aggregateEvent.CreatorId, longAbout));
|
||||
|
||||
exception.Message.ShouldBe(RpcErrors.RpcErrors400.ChatAboutTooLong.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Non_Admin_EditAbout_Throws_Exception()
|
||||
{
|
||||
var about = "test about";
|
||||
var aggregateEvent = A<ChannelCreatedEvent>();
|
||||
var channelCreatedEvent = ADomainEvent<ChannelAggregate, ChannelId, ChannelCreatedEvent>(aggregateEvent, 1);
|
||||
Sut.ApplyEvents(new IDomainEvent[] { channelCreatedEvent });
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() => Sut.EditAbout(A<RequestInfo>(), aggregateEvent.CreatorId + 1, about));
|
||||
|
||||
exception.Message.ShouldBe(RpcErrors.RpcErrors400.ChatAdminRequired.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckChannelState_For_Not_Exists_Channel_Throws_Exception()
|
||||
{
|
||||
Assert.Throws<DomainError>(() => Sut.CheckChannelState(A<RequestInfo>(),
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
MessageSubType.Normal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckChannelState_For_Broadcast_Channel_With_Non_Creator_Throws_Exception()
|
||||
{
|
||||
//var aggregateEvent = A<ChannelCreatedEvent>();
|
||||
//var domainEvent = ADomainEvent<ChannelAggregate, ChannelId, ChannelCreatedEvent>(aggregateEvent, 1);
|
||||
//Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
var creatorId = 1;
|
||||
var senderPeerId = 2;
|
||||
Sut.Create(A<RequestInfo>(),
|
||||
1,
|
||||
creatorId,
|
||||
true,
|
||||
false,
|
||||
"test",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
new TMessageActionChatCreate
|
||||
{
|
||||
Title = "test",
|
||||
Users = []
|
||||
},
|
||||
0,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false, [], []);
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() =>
|
||||
Sut.CheckChannelState(A<RequestInfo>(), senderPeerId,
|
||||
1,
|
||||
1,
|
||||
MessageSubType.Normal));
|
||||
|
||||
exception.RpcError.ShouldBe(RpcErrors.RpcErrors403.ChatWriteForbidden);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckChannelState_For_Banned_SendMessage_Rights_MegaGroup_Throws_Exception()
|
||||
{
|
||||
var creatorId = 1;
|
||||
var senderPeerId = 2;
|
||||
var requestInfo = A<RequestInfo>() with { UserId = creatorId };
|
||||
Sut.Create(requestInfo,
|
||||
1,
|
||||
creatorId,
|
||||
false,
|
||||
true,
|
||||
"test",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
new TMessageActionChatCreate
|
||||
{
|
||||
Title = "test",
|
||||
Users = []
|
||||
},
|
||||
0, false, null, null, null,
|
||||
false, false, [], []);
|
||||
var bannedWriteMessageRights = new ChatBannedRights(false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true, true, true, true, true, true, true, true,
|
||||
int.MaxValue);
|
||||
Sut.EditChatDefaultBannedRights(requestInfo, bannedWriteMessageRights, creatorId);
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() =>
|
||||
Sut.CheckChannelState(A<RequestInfo>(), senderPeerId,
|
||||
1,
|
||||
1,
|
||||
MessageSubType.Normal));
|
||||
|
||||
exception.RpcError.ShouldBe(RpcErrors.RpcErrors403.ChatWriteForbidden);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckChannelState_For_Enabled_Slow_Mode_Test()
|
||||
{
|
||||
var creatorId = 1;
|
||||
var senderPeerId = 2;
|
||||
Sut.Create(A<RequestInfo>(),
|
||||
1,
|
||||
creatorId,
|
||||
false,
|
||||
true,
|
||||
"test",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
new TMessageActionChatCreate
|
||||
{
|
||||
Title = "test",
|
||||
Users = []
|
||||
},
|
||||
0,
|
||||
false, null, null, null,
|
||||
false, false, [], []);
|
||||
Sut.ToggleSlowMode(A<RequestInfo>(), 60, 1);
|
||||
var checkStateCompletedEvent = new CheckChannelStateCompletedEvent(
|
||||
A<RequestInfo>(),
|
||||
senderPeerId,
|
||||
1,
|
||||
DateTime.UtcNow.ToTimestamp(),
|
||||
false,
|
||||
null,
|
||||
new List<long>(),
|
||||
null);
|
||||
var domainEvent = ADomainEvent<ChannelAggregate, ChannelId, CheckChannelStateCompletedEvent>(checkStateCompletedEvent, 3);
|
||||
Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() => Sut.CheckChannelState(A<RequestInfo>(), senderPeerId, 2, DateTime.UtcNow.ToTimestamp(), MessageSubType.Normal));
|
||||
|
||||
exception.RpcError.Message.ShouldStartWith("SLOWMODE_WAIT_");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckChannelState_Test()
|
||||
{
|
||||
var creatorId = 1;
|
||||
var senderPeerId = 2;
|
||||
var aggregateEvent = new ChannelCreatedEvent(A<RequestInfo>(),
|
||||
1,
|
||||
creatorId,
|
||||
"test",
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
new TMessageActionChatCreate
|
||||
{
|
||||
Title = "test",
|
||||
Users = []
|
||||
},
|
||||
0, false, null, null, null,
|
||||
false, false, [], []);
|
||||
Sut.ApplyEvents([ADomainEvent<ChannelAggregate, ChannelId, ChannelCreatedEvent>(aggregateEvent, 1)]);
|
||||
|
||||
Sut.CheckChannelState(A<RequestInfo>(), senderPeerId, 1, DateTime.UtcNow.ToTimestamp(), MessageSubType.Normal);
|
||||
|
||||
Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<CheckChannelStateCompletedEvent>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//namespace MyTelegram.Domain.Tests.UnitTests.Aggregates.Chat;
|
||||
|
||||
//public class ChatAggregateTests : TestsFor<ChatAggregate>
|
||||
//{
|
||||
// public ChatAggregateTests()
|
||||
// {
|
||||
// Fixture.Customize<ChatId>(x => x.FromFactory(() => ChatId.Create(MyTelegramConsts.ChatIdInitId + 1)));
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void CreateChat_With_TooMany_Members_Throws_Exception()
|
||||
// {
|
||||
// var members = Enumerable.Range(1, MyTelegramConsts.ChatMemberMaxCount + 1).Select(p => (long)p).ToList();
|
||||
// var creatorId = MyTelegramConsts.ChatMemberMaxCount + 1;
|
||||
|
||||
// var exception = Assert.Throws<RpcException>(() => Sut.Create(A<RequestInfo>(),
|
||||
// A<long>(),
|
||||
// creatorId,
|
||||
// A<string>(),
|
||||
// members,
|
||||
// A<int>(),
|
||||
// A<long>(),
|
||||
// A<string>(), 0));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.UsersTooMuch.Message);
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void AddChatUser_Success()
|
||||
// {
|
||||
// var aggregateEvent = A<ChatCreatedEvent>();
|
||||
// var domainEvent = ADomainEvent<ChatAggregate, ChatId, ChatCreatedEvent>(aggregateEvent, 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
// var inviterId = aggregateEvent.CreatorUid;
|
||||
// var userId = A<long>();
|
||||
// Sut.AddChatUser(A<RequestInfo>() with { UserId = inviterId },
|
||||
// inviterId,
|
||||
// userId,
|
||||
// A<int>(),
|
||||
// A<string>(),
|
||||
// A<long>());
|
||||
|
||||
// var uncommittedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<ChatMemberAddedEvent>();
|
||||
// uncommittedEvent.ChatMember.UserId.ShouldBe(userId);
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void Non_Admin_AddChatUser_Throws_Exception()
|
||||
// {
|
||||
// var aggregateEvent = A<ChatCreatedEvent>();
|
||||
// var domainEvent = ADomainEvent<ChatAggregate, ChatId, ChatCreatedEvent>(aggregateEvent, 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
// var inviterId = aggregateEvent.CreatorUid + 1;
|
||||
// var requestInfo = A<RequestInfo>() with { UserId = inviterId };
|
||||
|
||||
// var exception = Assert.Throws<RpcException>(() => Sut.AddChatUser(requestInfo,
|
||||
// inviterId,
|
||||
// A<int>(),
|
||||
// A<int>(),
|
||||
// A<string>(),
|
||||
// A<long>()));
|
||||
|
||||
// exception.RpcError.ShouldBe(RpcErrors.RpcErrors400.ChatAdminRequired);
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void AddChatUser_Exceeded_Max_Count_Throws_Exception()
|
||||
// {
|
||||
// var aggregateEvent = A<ChatCreatedEvent>();
|
||||
// var domainEvent = ADomainEvent<ChatAggregate, ChatId, ChatCreatedEvent>(aggregateEvent, 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
// var inviterId = aggregateEvent.CreatorUid;
|
||||
// var requestInfo = A<RequestInfo>() with { UserId = aggregateEvent.CreatorUid };
|
||||
// var members = Enumerable.Range((int)inviterId + 1, MyTelegramConsts.ChatMemberMaxCount);
|
||||
// var aggregateEvents = members.Select(p => new ChatMemberAddedEvent(
|
||||
// requestInfo,
|
||||
// aggregateEvent.ChatId,
|
||||
// new ChatMember(p, aggregateEvent.CreatorUid, A<int>()),
|
||||
// A<string>(),
|
||||
// A<long>(), new List<long>()));
|
||||
// var domainEvents = aggregateEvents.Select((p,
|
||||
// index) => ADomainEvent<ChatAggregate, ChatId, ChatMemberAddedEvent>(p, Sut.Version + index + 1)).ToList();
|
||||
// Sut.ApplyEvents(domainEvents);
|
||||
|
||||
// var exception = Assert.Throws<RpcException>(() => Sut.AddChatUser(requestInfo,
|
||||
// inviterId,
|
||||
// A<int>(),
|
||||
// A<int>(),
|
||||
// A<string>(),
|
||||
// A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.UsersTooMuch.Message);
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void AddChatUser_For_Exists_Member_Throws_Exception()
|
||||
// {
|
||||
// var aggregateEvent = A<ChatCreatedEvent>();
|
||||
// var domainEvent = ADomainEvent<ChatAggregate, ChatId, ChatCreatedEvent>(aggregateEvent, 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { domainEvent });
|
||||
// var memberAddedAggregateEvent = new ChatMemberAddedEvent(A<RequestInfo>(),
|
||||
// aggregateEvent.ChatId,
|
||||
// new ChatMember(A<long>(),
|
||||
// aggregateEvent.CreatorUid,
|
||||
// A<int>()),
|
||||
// A<string>(),
|
||||
// A<long>(), Many<long>());
|
||||
// var memberAddedDomainEvent =
|
||||
// ADomainEvent<ChatAggregate, ChatId, ChatMemberAddedEvent>(memberAddedAggregateEvent, Sut.Version + 1);
|
||||
// Sut.ApplyEvents(new IDomainEvent[] { memberAddedDomainEvent });
|
||||
// var requestInfo = A<RequestInfo>() with { UserId = aggregateEvent.CreatorUid };
|
||||
|
||||
// var exception = Assert.Throws<RpcException>(() => Sut.AddChatUser(requestInfo,
|
||||
// aggregateEvent.CreatorUid,
|
||||
// memberAddedAggregateEvent.ChatMember.UserId,
|
||||
// A<int>(),
|
||||
// A<string>(),
|
||||
// A<long>()));
|
||||
|
||||
// exception.Message.ShouldBe(RpcErrors.RpcErrors400.UserAlreadyParticipant.Message);
|
||||
// }
|
||||
//}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
using Shouldly;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Aggregates.Messaging;
|
||||
|
||||
public class MessageAggregateTests : TestsFor<MessageAggregate>
|
||||
{
|
||||
private int _messageId = 1;
|
||||
public MessageAggregateTests()
|
||||
{
|
||||
Fixture.Customize<MessageId>(c => c.FromFactory(() => MessageId.Create(1, 1)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Edit_Message_Success()
|
||||
{
|
||||
var messageId = 1;
|
||||
var newMessage = "new message";
|
||||
CreateMessage(DateTime.UtcNow.ToTimestamp());
|
||||
|
||||
Sut.EditOutboxMessage(A<RequestInfo>(),
|
||||
messageId,
|
||||
newMessage,
|
||||
DateTime.UtcNow.ToTimestamp(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null
|
||||
);
|
||||
|
||||
var uncommittedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<OutboxMessageEditedEvent>();
|
||||
uncommittedEvent.NewMessage.ShouldBe(newMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Edit_Out_Of_Date_Message_Throws_Exception()
|
||||
{
|
||||
var newMessage = "new message";
|
||||
var creationTime = DateTime.UtcNow.ToTimestamp() - MyTelegramConsts.EditTimeLimit - 1000;
|
||||
CreateMessage(creationTime);
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() =>
|
||||
Sut.EditOutboxMessage(A<RequestInfo>(),
|
||||
_messageId,
|
||||
newMessage,
|
||||
DateTime.UtcNow.ToTimestamp(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null
|
||||
));
|
||||
|
||||
exception.Message.ShouldBe(RpcErrors.RpcErrors400.MessageEditTimeExpired.Message);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Only message author can edit message")]
|
||||
public void Edit_Inbox_Message_Throws_Exception()
|
||||
{
|
||||
var newMessage = "new message";
|
||||
CreateMessage(DateTime.UtcNow.ToTimestamp(), false);
|
||||
|
||||
var exception = Assert.Throws<RpcException>(() =>
|
||||
Sut.EditOutboxMessage(A<RequestInfo>(),
|
||||
_messageId,
|
||||
newMessage,
|
||||
DateTime.UtcNow.ToTimestamp(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false, null));
|
||||
|
||||
exception.Message.ShouldBe(RpcErrors.RpcErrors403.MessageAuthorRequired.Message);
|
||||
}
|
||||
|
||||
private MessageItem CreateMessage(int creationDate, bool isOut = true)
|
||||
{
|
||||
var ownerPeerId = 1;
|
||||
var toPeerUserId = A<long>();
|
||||
//var aggregateId = MessageId.Create(ownerPeerId, _messageId);
|
||||
var messageItem = new MessageItem(
|
||||
new Peer(PeerType.User, ownerPeerId),
|
||||
new Peer(PeerType.User, toPeerUserId),
|
||||
new Peer(PeerType.User, ownerPeerId),
|
||||
ownerPeerId,
|
||||
_messageId,
|
||||
"test message",
|
||||
creationDate,
|
||||
1,
|
||||
isOut
|
||||
);
|
||||
var outboxMessageCreatedEvent = new OutboxMessageCreatedEvent(A<RequestInfo>(),
|
||||
messageItem,
|
||||
null, null,
|
||||
true,
|
||||
1,
|
||||
null, null);
|
||||
|
||||
Sut.ApplyEvents([ADomainEvent<MessageAggregate, MessageId, OutboxMessageCreatedEvent>(outboxMessageCreatedEvent, 1)
|
||||
]);
|
||||
return messageItem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Aggregates.User;
|
||||
|
||||
public class UserAggregateTests : TestsFor<UserAggregate>
|
||||
{
|
||||
public UserAggregateTests()
|
||||
{
|
||||
Fixture.Customize<UserId>(c => c.FromFactory(() => UserId.Create(1)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_User_With_Exists_PhoneNumber_Throws_Exception()
|
||||
{
|
||||
var aggregateEvent = A<UserCreatedEvent>();
|
||||
var domainEvent = ADomainEvent<UserAggregate, UserId, UserCreatedEvent>(aggregateEvent, 1);
|
||||
|
||||
Sut.ApplyEvents(new[] { domainEvent });
|
||||
|
||||
Assert.Throws<DomainError>(() => Sut.Create(A<RequestInfo>(),
|
||||
1,
|
||||
0,
|
||||
aggregateEvent.PhoneNumber,
|
||||
"0"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_New_User_Success()
|
||||
{
|
||||
var phoneNumber = "0";
|
||||
var firstName = "0";
|
||||
var userId = 1;
|
||||
var accessHash = 1;
|
||||
|
||||
Sut.Create(A<RequestInfo>(), userId, accessHash, phoneNumber, firstName);
|
||||
|
||||
Sut.Version.ShouldBe(1);
|
||||
Sut.UncommittedEvents.Count().ShouldBe(1);
|
||||
var uncommittedEvent = Sut.UncommittedEvents.Single();
|
||||
var userCreatedEvent = uncommittedEvent.AggregateEvent.ShouldBeOfType<UserCreatedEvent>();
|
||||
userCreatedEvent.PhoneNumber.ShouldBe(phoneNumber);
|
||||
userCreatedEvent.UserId.ShouldBe(userId);
|
||||
userCreatedEvent.FirstName.ShouldBe(firstName);
|
||||
userCreatedEvent.AccessHash.ShouldBe(accessHash);
|
||||
userCreatedEvent.Bot.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_User_With_Empty_FirstName_Throws_Exception()
|
||||
{
|
||||
Assert.Throws<DomainError>(() => Sut.Create(A<RequestInfo>(),
|
||||
1,
|
||||
0,
|
||||
"0",
|
||||
string.Empty));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//namespace MyTelegram.Domain.Tests.UnitTests.Sagas;
|
||||
|
||||
//public class MessageSagaTests : TestsFor<MessageSaga>
|
||||
//{
|
||||
// //private Mock<ICommandBus> _commandBus;
|
||||
// private readonly Mock<ISagaContext> _sagaContext;
|
||||
// private readonly int _messageId = 1;
|
||||
|
||||
// public MessageSagaTests()
|
||||
// {
|
||||
// Fixture.Customize<MessageSagaId>(c => c.FromFactory(() => new MessageSagaId($"messagesaga-{Guid.Empty}")));
|
||||
// //_commandBus = InjectMock<ICommandBus>();
|
||||
// _sagaContext = InjectMock<ISagaContext>();
|
||||
// }
|
||||
|
||||
// [Theory]
|
||||
// [MemberData(nameof(GetSendMessageData))]
|
||||
// public async Task SendMessage_Started_Test(Peer fromPeer, Peer toPeer)
|
||||
// {
|
||||
// var aggregateId = MessageId.Create(fromPeer.PeerId, _messageId);
|
||||
// var messageItem = new MessageItem(
|
||||
// fromPeer,
|
||||
// toPeer,
|
||||
// fromPeer,
|
||||
// _messageId,
|
||||
// "test message",
|
||||
// A<int>(),
|
||||
// A<long>(),
|
||||
// true);
|
||||
// var aggregateEvent = new SendMessageStartedEvent(A<RequestInfo>(),
|
||||
// messageItem,
|
||||
// true,
|
||||
// 1,
|
||||
// false,
|
||||
// Guid.NewGuid()
|
||||
// );
|
||||
// var domainEvent = ADomainEvent<MessageAggregate, MessageId, SendMessageStartedEvent>(aggregateEvent, aggregateId, 1);
|
||||
|
||||
// await Sut.HandleAsync(domainEvent, _sagaContext.Object, CancellationToken.None);
|
||||
|
||||
// var uncommittedEvent = Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<MessageSagaStartedEvent>();
|
||||
// uncommittedEvent.MessageItem.ToPeer.ShouldBe(toPeer);
|
||||
// }
|
||||
|
||||
// //[Fact]
|
||||
// //public async Task SendMessage_To_User_Peer_Started_Test()
|
||||
// //{
|
||||
// // var fromPeer = new Peer(PeerType.User, 1);
|
||||
// // var toPeer = new Peer(PeerType.User, 2);
|
||||
// // var aggregateId = MessageId.Create(fromPeer.PeerId, _messageId);
|
||||
// // var messageItem = new MessageItem(aggregateId,
|
||||
// // fromPeer,
|
||||
// // toPeer,
|
||||
// // fromPeer,
|
||||
// // _messageId,
|
||||
// // "test message",
|
||||
// // A<int>(),
|
||||
// // A<long>(),
|
||||
// // true);
|
||||
// // var aggregateEvent = new SendMessageStartedEvent(A<RequestInfo>(),
|
||||
// // messageItem,
|
||||
// // true,
|
||||
// // 1,
|
||||
// // Guid.NewGuid()
|
||||
// // );
|
||||
// // var domainEvent = ADomainEvent<MessageAggregate, MessageId, SendMessageStartedEvent>(aggregateEvent, aggregateId, 1);
|
||||
// // _commandBus.Setup(c => c.PublishAsync(It.IsAny<ICommand<UserAggregate, UserId, IExecutionResult>>(),
|
||||
// // It.IsAny<CancellationToken>())).Returns(() => Task.FromResult(ExecutionResult.Success()));
|
||||
|
||||
// // await Sut.HandleAsync(domainEvent, _sagaContext.Object, CancellationToken.None);
|
||||
// // await Sut.PublishAsync(_commandBus.Object, CancellationToken.None);
|
||||
|
||||
// // Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<MessageSagaStartedEvent>();
|
||||
// // _commandBus.Verify(c => c.PublishAsync(It.IsAny<ICommand<UserAggregate, UserId, IExecutionResult>>(),
|
||||
// // It.IsAny<CancellationToken>()), Times.Once);
|
||||
// //}
|
||||
|
||||
|
||||
// public static IEnumerable<object[]> GetSendMessageData()
|
||||
// {
|
||||
// yield return new object[] { new Peer(PeerType.User, 1), new Peer(PeerType.User, 2) };
|
||||
// yield return new object[] { new Peer(PeerType.User, 1), new Peer(PeerType.Chat, 2) };
|
||||
// yield return new object[] { new Peer(PeerType.User, 1), new Peer(PeerType.Channel, 2) };
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MyTelegram.Domain.Sagas.Events;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Sagas;
|
||||
|
||||
public class UserSignInSagaTests : TestsFor<SignInSaga>
|
||||
{
|
||||
private readonly Mock<ISagaContext> _sagaContext;
|
||||
|
||||
public UserSignInSagaTests()
|
||||
{
|
||||
Fixture.Customize<AppCodeId>(c => c.FromFactory(() => AppCodeId.Create("0", "0")));
|
||||
Fixture.Customize<SignInSagaId>(c => c.FromFactory(() => new SignInSagaId($"signinsagaid-{Guid.Empty}")));
|
||||
_sagaContext = InjectMock<ISagaContext>();
|
||||
//var idGenerator = InjectMock<IIdGenerator>();
|
||||
//IdGeneratorFactory.SetDefaultIdGenerator(idGenerator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignIn_With_Invalid_PhoneCode_Throws_Exception()
|
||||
{
|
||||
var aggregateEvent = new CheckSignInCodeCompletedEvent(A<RequestInfo>(), false, 1);
|
||||
var domainEvent =
|
||||
ADomainEvent<AppCodeAggregate, AppCodeId, CheckSignInCodeCompletedEvent>(aggregateEvent, A<AppCodeId>(), 1);
|
||||
|
||||
var exception = await Assert.ThrowsAsync<RpcException>(async () => await Sut.HandleAsync(domainEvent, _sagaContext.Object, CancellationToken.None).ConfigureAwait(false));
|
||||
|
||||
exception.RpcError.ShouldBe(RpcErrors.RpcErrors400.PhoneCodeInvalid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignIn_With_Correct_PhoneCode_Success()
|
||||
{
|
||||
var aggregateEvent = new CheckSignInCodeCompletedEvent(A<RequestInfo>(), true, 1);
|
||||
var domainEvent =
|
||||
ADomainEvent<AppCodeAggregate, AppCodeId, CheckSignInCodeCompletedEvent>(aggregateEvent, A<AppCodeId>(), 1);
|
||||
|
||||
await Sut.HandleAsync(domainEvent, _sagaContext.Object, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<SignInStartedSagaEvent>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using MyTelegram.Domain.Sagas.Events;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Sagas;
|
||||
|
||||
public class UserSignUpSagaTests : TestsFor<UserSignUpSaga>
|
||||
{
|
||||
private readonly Mock<ISagaContext> _sagaContext;
|
||||
|
||||
public UserSignUpSagaTests()
|
||||
{
|
||||
Fixture.Customize<AppCodeId>(c => c.FromFactory(() => AppCodeId.Create("0", "0")));
|
||||
Fixture.Customize<UserSignUpSagaId>(c => c.FromFactory(() => new UserSignUpSagaId($"usersignupsagaid-{Guid.Empty}")));
|
||||
_sagaContext = InjectMock<ISagaContext>();
|
||||
//var idGenerator = InjectMock<IIdGenerator>();
|
||||
//IdGeneratorFactory.SetDefaultIdGenerator(idGenerator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignUp_For_New_User_Success()
|
||||
{
|
||||
var aggregateEvent = new CheckSignUpCodeCompletedEvent(A<RequestInfo>(), true, 0, 0, "0", "0", null);
|
||||
var domainEvent = new DomainEvent<AppCodeAggregate, AppCodeId, CheckSignUpCodeCompletedEvent>(aggregateEvent,
|
||||
Metadata.Empty,
|
||||
A<DateTimeOffset>(),
|
||||
A<AppCodeId>(),
|
||||
1);
|
||||
|
||||
await Sut.HandleAsync(domainEvent, _sagaContext.Object, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
Sut.UncommittedEvents.Single().AggregateEvent.ShouldBeOfType<UserSignUpSuccessSagaEvent>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace MyTelegram.Domain.Tests.UnitTests;
|
||||
|
||||
public class SimpleInMemoryIdGeneratorTests : TestsFor<SimpleInMemoryIdGenerator>
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(10)]
|
||||
[InlineData(100)]
|
||||
public async Task SequenceId_Should_Increment_By_Step(int step)
|
||||
{
|
||||
var id1 = await Sut.NextLongIdAsync(IdType.MessageId, 1, step).ConfigureAwait(false);
|
||||
var id2 = await Sut.NextLongIdAsync(IdType.MessageId, 1, step).ConfigureAwait(false);
|
||||
var id3 = await Sut.NextLongIdAsync(IdType.MessageId, 1, step).ConfigureAwait(false);
|
||||
|
||||
id1.ShouldBe(step);
|
||||
id2.ShouldBe(id1 + step);
|
||||
id3.ShouldBe(id2 + step);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using MyTelegram.Domain.Specifications;
|
||||
|
||||
namespace MyTelegram.Domain.Tests.UnitTests.Specifications;
|
||||
|
||||
public class IsEmailAddressSpecificationTests : TestsFor<IsEmailAddressSpecification>
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("email@example.com", true)]
|
||||
//[InlineData("firstname.lastname@example.com", true)]
|
||||
[InlineData("email@subdomain.example.com", true)]
|
||||
//[InlineData("firstname+lastname@example.com", true)]
|
||||
[InlineData("email@123.123.123.123", true)]
|
||||
//[InlineData("email@[123.123.123.123]", true)]
|
||||
//[InlineData("\"email\"@example.com", true)]
|
||||
[InlineData("1234567890@example.com", true)]
|
||||
[InlineData("email@example-one.com", true)]
|
||||
//[InlineData("_______@example.com", true)]
|
||||
[InlineData("email@example.name", true)]
|
||||
[InlineData("email@example.web", true)]
|
||||
[InlineData("email@example.museum", true)]
|
||||
[InlineData("email@example.co.jp", true)]
|
||||
//[InlineData("firstname-lastname@example.com", true)]
|
||||
//[InlineData("much.”more\\ unusual”@example.com", true)]
|
||||
//[InlineData("very.unusual.”@”.unusual.com@example.com", true)]
|
||||
//[InlineData("very.”(),:;<>[]”.VERY.”very@\\ \"very”.unusual@strange.example.com", true)]
|
||||
|
||||
[InlineData("#@%^%#$@#$@#.com", false)]
|
||||
[InlineData("@example.com", false)]
|
||||
[InlineData("Joe Smith <email@example.com>", false)]
|
||||
[InlineData("email.example.com", false)]
|
||||
[InlineData("email@example@example.com", false)]
|
||||
[InlineData(".email@example.com", false)]
|
||||
[InlineData("email.@example.com", false)]
|
||||
[InlineData("email..email@example.com", false)]
|
||||
[InlineData("あいうえお@example.com", false)]
|
||||
[InlineData("email@example.com (Joe Smith)", false)]
|
||||
[InlineData("email@example", false)]
|
||||
//[InlineData("email@-example.com", false)]
|
||||
|
||||
//[InlineData("email@111.222.333.44444", false)]
|
||||
[InlineData("email@example..com", false)]
|
||||
[InlineData("Abc..123@example.com", false)]
|
||||
[InlineData("”(),:;<>[\\]@example.com", false)]
|
||||
[InlineData("just”not”right@example.com", false)]
|
||||
[InlineData("this\\ is\\\"really\\\"not\\allowed@example.com", false)]
|
||||
|
||||
public void IsEmail_Valid_Test(string email,
|
||||
bool isValid)
|
||||
{
|
||||
// Act
|
||||
var isSatisfied = Sut.IsSatisfiedBy(email);
|
||||
|
||||
// Assert
|
||||
isSatisfied.ShouldBe(isValid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
namespace MyTelegram.MTProto.Tests;
|
||||
|
||||
public class AesHelperTest : TestsFor<AesHelper>
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(@"52 BF FD 82 77 DF 92 00 DE 7B DB F7 A3 05 1E AE
|
||||
D0 83 8A 45 D2 20 ED DB 5D EC 68 6A BD FC CA AB",
|
||||
@"40 EF 69 0A 99 B9 33 56 D1 62 77 F0 40 5A 1D 8E",
|
||||
@"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
@"0",
|
||||
// @"00 00 00 00 00 00 00 00",
|
||||
// @"01 00 00 00 CE FD 3C 64",
|
||||
// @"40 00 00 00",
|
||||
// @"63 24 16 05 95 D8 D3 0A 76 09 85 17 57 C1 7B 1F
|
||||
//13 D0 B9 0B 68 2D 71 9D 71 BF 95 55 2A EE 76 1E
|
||||
//CD E2 5B 32 08 17 ED 48 94 1A 08 F9 81 00 00 00
|
||||
//15 C4 B5 1C 01 00 00 00 A4 BD 15 12 08 F5 27 CE",
|
||||
@"15 00 00 00 00 00 00 00 00 01 00 00 00 CE FD 3C
|
||||
64 40 00 00 00 63 24 16 05 95 D8 D3 0A 76 09 85
|
||||
17 57 C1 7B 1F 13 D0 B9 0B 68 2D 71 9D 71 BF 95
|
||||
55 2A EE 76 1E CD E2 5B 32 08 17 ED 48 94 1A 08
|
||||
F9 81 00 00 00 15 C4 B5 1C 01 00 00 00 A4 BD 15
|
||||
12 08 F5 27 CE",
|
||||
// @"52 BF FD 82 77 DF 92 00 DE 7B DB F7 A3 05 1E AE
|
||||
//D0 83 8A 45 D2 20 ED DB 5D EC 68 6A BD FC CA AB",
|
||||
@"40 EF 69 0A 99 B9 33 56 D1 62 77 F0 40 5A 1D 94",
|
||||
@"2D 28 86 16 B1 BE 35 07 34 D2 56 5E 57 59 02 AB",
|
||||
@"5",
|
||||
@"E6 8A 83 90 46 3B EC 5D DB C8 E4 29 C3 E9 36 26
|
||||
AE 58 32 96 D6 2C 57 B6 E7 AE 60 93 0E F4 72 1A
|
||||
6D 40 62 DA 49 74 83 CE 5A 71 89 E5 0B 79 A1 46
|
||||
80 FA 28 DD BE 30 7E 3D 3E A1 3A FF D0 2E FD 67
|
||||
22 D8 90 0F 3D E7 EA 74 0A 8F C3 C1 E3 D0 5C AF
|
||||
3F 20 73 31 7F"
|
||||
)]
|
||||
public void Ctr128Test(string receiveKey,
|
||||
string receiveIv,
|
||||
string ecounter,
|
||||
string n,
|
||||
//string authKeyId,
|
||||
//string messageId,
|
||||
//string messageDataLength,
|
||||
//string messageData,
|
||||
string buffer,
|
||||
//string receiveKey2,
|
||||
string receiveIv2,
|
||||
string ecounter2,
|
||||
string n2,
|
||||
string expectedData)
|
||||
{
|
||||
var span = buffer.ToBytes();
|
||||
var expectedBytes = expectedData.ToBytes();
|
||||
//var key = receiveKey.ToBytes();
|
||||
var outputSpan = new byte[span.Length];
|
||||
|
||||
Sut.CtrEncrypt(span, outputSpan, receiveKey.ToBytes(), receiveIv.ToBytes());
|
||||
|
||||
expectedBytes.ShouldBeEquivalentTo(outputSpan);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace MyTelegram.MTProto.Tests;
|
||||
|
||||
public class ClientData : IClientData
|
||||
{
|
||||
public ProtocolType MtProtoType { get; set; }
|
||||
public bool IsFirstPacketParsed { get; set; }
|
||||
public byte[] SendKey { get; set; } = [];
|
||||
public byte[] ReceiveKey { get; set; } = [];
|
||||
public long AuthKeyId { get; set; }
|
||||
public string ConnectionId { get; set; } = null!;
|
||||
public bool ObfuscationEnabled { get; set; }
|
||||
public int CurrentPacketLength { get; set; }
|
||||
public int SkipCount { get; set; }
|
||||
public byte[] SendIv { get; set; } = [];
|
||||
public byte[] ReceiveIv { get; set; } = [];
|
||||
public ulong ReceiveCount { get; set; }
|
||||
public ulong SendCount { get; set; }
|
||||
public ArrayPool<byte> ArrayPool { get; set; } = ArrayPool<byte>.Shared;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MyTelegram.MTProto.Tests;
|
||||
|
||||
public class FirstPacketParserTest : TestsFor<FirstPacketParser>
|
||||
{
|
||||
private readonly Mock<ILogger<FirstPacketParser>> _loggerMock;
|
||||
public FirstPacketParserTest()
|
||||
{
|
||||
_loggerMock = new();
|
||||
Inject<IAesHelper>(new AesHelper());
|
||||
Inject(_loggerMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseFirstPacket()
|
||||
{
|
||||
var nonce = @"E2 B5 09 29 B6 1A 48 C4 28 5C D7 02 01 A3 98 E5 C3 1E 81 A9 0C 34 B9 7A 0F 1C BC E9 0B 41 75 C9
|
||||
9B 25 73 E7 36 4A 14 71 EF D6 77 7D 73 B2 45 5A 5E 3E BF 31 65 04 71 07 70 F7 7F 86 6A 9E 48 BC".ToBytes();
|
||||
var sendKey = @"28 5C D7 02 01 A3 98 E5 C3 1E 81 A9 0C 34 B9 7A 0F 1C BC E9 0B 41 75 C9 9B 25 73 E7 36 4A 14 71"
|
||||
.ToBytes();
|
||||
var sendIv = "EF D6 77 7D 73 B2 45 5A 5E 3E BF 31 65 04 71 07".ToBytes();
|
||||
var receiveKey =
|
||||
@"07 71 04 65 31 BF 3E 5E 5A 45 B2 73 7D 77 D6 EF 71 14 4A 36 E7 73 25 9B C9 75 41 0B E9 BC 1C 0F"
|
||||
.ToBytes();
|
||||
var receiveIv = "7A B9 34 0C A9 81 1E C3 E5 98 A3 01 02 D7 5C 28".ToBytes();
|
||||
|
||||
var d = Sut.Parse(nonce);
|
||||
|
||||
d.SendKey.ShouldBeEquivalentTo(sendKey);
|
||||
d.SendIv.ShouldBeEquivalentTo(sendIv);
|
||||
d.ReceiveKey.ShouldBeEquivalentTo(receiveKey);
|
||||
d.ReceiveIv.ShouldBeEquivalentTo(receiveIv);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,6 @@
|
||||
global using Xunit;
|
||||
global using MyTelegram.TestBase;
|
||||
global using MyTelegram.MTProto;
|
||||
global using Shouldly;
|
||||
global using Moq;
|
||||
global using System.Buffers;
|
||||
@@ -0,0 +1,62 @@
|
||||
using MyTelegram.Abstractions;
|
||||
|
||||
namespace MyTelegram.MTProto.Tests;
|
||||
|
||||
public class MtpMessageEncoderTest : TestsFor<MtpMessageEncoder>
|
||||
{
|
||||
private readonly Mock<IMessageIdHelper> _messageIdHelperMock;
|
||||
public MtpMessageEncoderTest()
|
||||
{
|
||||
_messageIdHelperMock = new();
|
||||
Inject<IAesHelper>(new AesHelper());
|
||||
Inject(_messageIdHelperMock.Object);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"52 BF FD 82 77 DF 92 00 DE 7B DB F7 A3 05 1E AE
|
||||
D0 83 8A 45 D2 20 ED DB 5D EC 68 6A BD FC CA AB",
|
||||
@"40 EF 69 0A 99 B9 33 56 D1 62 77 F0 40 5A 1D 8E",
|
||||
@"0",
|
||||
@"01 00 00 00 CE FD 3C 64",
|
||||
@"63 24 16 05 95 D8 D3 0A 76 09 85 17 57 C1 7B 1F
|
||||
13 D0 B9 0B 68 2D 71 9D 71 BF 95 55 2A EE 76 1E
|
||||
CD E2 5B 32 08 17 ED 48 94 1A 08 F9 81 00 00 00
|
||||
15 C4 B5 1C 01 00 00 00 A4 BD 15 12 08 F5 27 CE",
|
||||
@"E6 8A 83 90 46 3B EC 5D DB C8 E4 29 C3 E9 36 26
|
||||
AE 58 32 96 D6 2C 57 B6 E7 AE 60 93 0E F4 72 1A
|
||||
6D 40 62 DA 49 74 83 CE 5A 71 89 E5 0B 79 A1 46
|
||||
80 FA 28 DD BE 30 7E 3D 3E A1 3A FF D0 2E FD 67
|
||||
22 D8 90 0F 3D E7 EA 74 0A 8F C3 C1 E3 D0 5C AF
|
||||
3F 20 73 31 7F"
|
||||
)]
|
||||
public void EncodeTest(
|
||||
string receiveKey,
|
||||
string receiveIv,
|
||||
string n,
|
||||
string messageId,
|
||||
string messageData,
|
||||
string expectedData)
|
||||
{
|
||||
var d = new ClientData
|
||||
{
|
||||
MtProtoType = ProtocolType.Abridge,
|
||||
ReceiveKey = receiveKey.ToBytes(),
|
||||
ReceiveIv = receiveIv.ToBytes(),
|
||||
ReceiveCount = uint.Parse(n),
|
||||
ObfuscationEnabled = true
|
||||
};
|
||||
|
||||
var data = messageData.ToBytes();
|
||||
var m = new UnencryptedMessageResponse(0, data, string.Empty, 0);
|
||||
var encodedBytes = ArrayPool<byte>.Shared.Rent(data.Length + 21);
|
||||
Span<byte> span = encodedBytes;
|
||||
var messageId2 = BitConverter.ToInt64(messageId.ToBytes());
|
||||
_messageIdHelperMock.Setup(p => p.GenerateMessageId())
|
||||
.Returns(messageId2);
|
||||
var expectedBuffer = expectedData.ToBytes();
|
||||
|
||||
var count = Sut.Encode(d, m, span);
|
||||
|
||||
span[..count].ToArray().ShouldBeEquivalentTo(expectedBuffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture.Xunit2" />
|
||||
<PackageReference Include="AutoFixture.AutoMoq" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MyTelegram.MTProto\MyTelegram.MTProto.csproj" />
|
||||
<ProjectReference Include="..\..\src\MyTelegram.TestBase\MyTelegram.TestBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Fody">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,12 @@
|
||||
global using System;
|
||||
global using System.IO;
|
||||
global using System.Linq;
|
||||
global using System.Collections;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Buffers;
|
||||
|
||||
global using Xunit;
|
||||
global using Shouldly;
|
||||
|
||||
global using MyTelegram.Schema.Extensions;
|
||||
global using MyTelegram.Schema.Serializer;
|
||||
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<RootNamespace>MyTelegram.Schema</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MyTelegram.Schema\MyTelegram.Schema.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Fody">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class BitArraySerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var value = new BitArray(32) { [0] = true };
|
||||
var expectedValue = "01000000".ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(value, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
[MemberData(nameof(GetData), parameters: new[] { 0 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 1 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 2 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 31 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 1, 2 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 1, 2, 3 })]
|
||||
[MemberData(nameof(GetData), parameters: new[] { 1, 2, 31 })]
|
||||
[Theory]
|
||||
public void DeserializeTest(byte[] value, BitArray expectedValue)
|
||||
{
|
||||
//var stream = new MemoryStream(value);
|
||||
//var br = new BinaryReader(stream);
|
||||
var serializer = CreateSerializer();
|
||||
ReadOnlyMemory<byte> buffer = value;
|
||||
var actualValue = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualValue.ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GetData(params int[] bitOfNSetToTrue)
|
||||
{
|
||||
var bitArray = new BitArray(32);
|
||||
foreach (var i in bitOfNSetToTrue)
|
||||
{
|
||||
bitArray.Set(i, true);
|
||||
}
|
||||
|
||||
var buffer = new byte[4];
|
||||
bitArray.CopyTo(buffer, 0);
|
||||
|
||||
var allData = new List<object[]> { new object[] { buffer, bitArray } };
|
||||
|
||||
return allData;
|
||||
}
|
||||
|
||||
private BitArraySerializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class BooleanSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Deserialize_ErrorData_Throws_Argument_Exception()
|
||||
{
|
||||
var value = new byte[] { 1, 2, 3, 4 };
|
||||
//var br = new BinaryReader(new MemoryStream(value));
|
||||
//var buffer = new ReadOnlySequence<byte>(value);
|
||||
ReadOnlyMemory<byte> buffer = value;
|
||||
var serializer = CreateSerializer();
|
||||
//Assert.Throws<ArgumentException>(() => serializer.Deserialize(ref reader));
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
//var reader = new SequenceReader<byte>(new ReadOnlySequence<byte>(value));
|
||||
//serializer.Deserialize(ref reader);
|
||||
|
||||
serializer.Deserialize(ref buffer);
|
||||
});
|
||||
}
|
||||
|
||||
[InlineData(new byte[] { 55, 151, 121, 188 }, false)]
|
||||
[InlineData(new byte[] { 181, 117, 114, 153 }, true)]
|
||||
[Theory]
|
||||
public void DeserializeTest(byte[] value,
|
||||
bool expectedValue)
|
||||
{
|
||||
//var stream = new MemoryStream(value);
|
||||
//var br = new BinaryReader(stream);
|
||||
var serializer = CreateSerializer();
|
||||
//var reader = new SequenceReader<byte>(new ReadOnlySequence<byte>(value));
|
||||
ReadOnlyMemory<byte> buffer = value;
|
||||
|
||||
var actualValue = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualValue.ShouldBe(expectedValue);
|
||||
}
|
||||
|
||||
[InlineData(false, new byte[] { 55, 151, 121, 188 })]
|
||||
[InlineData(true, new byte[] { 181, 117, 114, 153 })]
|
||||
[Theory]
|
||||
public void SerializeTest(bool value,
|
||||
byte[] expectedValue)
|
||||
{
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(value, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
private BooleanSerializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// ReSharper disable StringLiteralTypo
|
||||
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class BytesSerializerTests
|
||||
{
|
||||
[MemberData(nameof(GetSerializeTestDataLengthLessThan254))]
|
||||
[MemberData(nameof(GetSerializeTestDataLengthGreaterThan253))]
|
||||
[Theory]
|
||||
public void Serialize_Data_Test(string inputBytesData, string expectedBytesData)
|
||||
{
|
||||
// Arrange
|
||||
var dataBytes = inputBytesData.ToBytes();
|
||||
var expectedBytes = expectedBytesData.ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
// Act
|
||||
serializer.Serialize(dataBytes, writer);
|
||||
|
||||
// Assert
|
||||
var serializedBytes = writer.WrittenSpan.ToArray();
|
||||
serializedBytes.ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
[MemberData(nameof(GetSerializeTestDataLengthLessThan254))]
|
||||
[MemberData(nameof(GetSerializeTestDataLengthGreaterThan253))]
|
||||
[Theory]
|
||||
public void Deserialize_Data_Test(string expectedBytesData, string inputBytesData)
|
||||
{
|
||||
// Arrange
|
||||
var expectedBytes = expectedBytesData.ToBytes();
|
||||
var inputBytes = inputBytesData.ToBytes();
|
||||
//var br = new BinaryReader(new MemoryStream(inputBytes));
|
||||
//var buffer = new ReadOnlySequence<byte>(inputBytes);
|
||||
var serializer = CreateSerializer();
|
||||
//var reader = new SequenceReader<byte>(new ReadOnlySequence<byte>(inputBytes));
|
||||
ReadOnlyMemory<byte> buffer = inputBytes;
|
||||
|
||||
// Act
|
||||
var actualData = serializer.Deserialize(ref buffer);
|
||||
|
||||
// Assert
|
||||
actualData.ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GetSerializeTestDataLengthLessThan254()
|
||||
{
|
||||
// 1
|
||||
yield return new object[] { "8A", "018A0000" };
|
||||
|
||||
// 3
|
||||
yield return new object[] { "B05EDE", "03B05EDE" };
|
||||
|
||||
// 253
|
||||
yield return new object[]
|
||||
{
|
||||
"2586A2E2FA26A0CAED85146EC93A1EEE417A45165C0909097B39A7D8FEDB6D4BCCEEC3C74F4054732CEA1EB8C355E259C8A54A19C02C5040A6F61A7881D688A7D69CD8F89281588CD3B7097EAEBA11B757A871442614CE093D1B43CE571951C9AF7DA7AA32BF0D2C4755E7092E9563CA379FCB4C5736B67070F67CDD8D18166FF2C134603518DDBD890CE2294C698E8A1B45FAB17882EB0141863E45583DC4CE09D005F2C0897DDBC026CD12CDCF42F02C4F652AE882237DA65B03EB35317E5E6D58B3E1E00C5CF10C7EE6E5B4768900F761B831C8B6B21E10EE96B0DC05C4B94A21B1D2F877D71C7DEDD6A467A92FA856B58FFF05A45573CF2E67DF78",
|
||||
"FD2586A2E2FA26A0CAED85146EC93A1EEE417A45165C0909097B39A7D8FEDB6D4BCCEEC3C74F4054732CEA1EB8C355E259C8A54A19C02C5040A6F61A7881D688A7D69CD8F89281588CD3B7097EAEBA11B757A871442614CE093D1B43CE571951C9AF7DA7AA32BF0D2C4755E7092E9563CA379FCB4C5736B67070F67CDD8D18166FF2C134603518DDBD890CE2294C698E8A1B45FAB17882EB0141863E45583DC4CE09D005F2C0897DDBC026CD12CDCF42F02C4F652AE882237DA65B03EB35317E5E6D58B3E1E00C5CF10C7EE6E5B4768900F761B831C8B6B21E10EE96B0DC05C4B94A21B1D2F877D71C7DEDD6A467A92FA856B58FFF05A45573CF2E67DF780000"
|
||||
};
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GetSerializeTestDataLengthGreaterThan253()
|
||||
{
|
||||
// 254
|
||||
yield return new object[]
|
||||
{
|
||||
"E3015AEB327305D451B5BFFEAA5E1AEB15DE811373FC0B159D333DB5439715FD19570BCB43C6F3E31D2FF6B501817F67479BCADE30F395B86FDF73ACC354A1D90C2F592FD88CB83337F7D2D249775A2FE4B3EF169AAD2ABD7405940CEFCE9BC025E02FE81F4437C2606E2AD2CF807E334F954671302CD53C47EB8462E44AD73F9FDB3095827542DD6060F3EF2E1472A3B11F0857CBE65B3839C3AD95DE71F0625A6CBDE94B8F3CD1F28993DE72BB9F089C6E30968CB3E365F0AE2D35490AD958C04DE9FF433C5C710D44DF7710C5A5B9A96A113659933B7212BC6BB2715FD7B080E2E01E7583AF6A99967A0E559E74363ACAEE7A94D1A601CF0DAD4B6DC5",
|
||||
"FEFE0000E3015AEB327305D451B5BFFEAA5E1AEB15DE811373FC0B159D333DB5439715FD19570BCB43C6F3E31D2FF6B501817F67479BCADE30F395B86FDF73ACC354A1D90C2F592FD88CB83337F7D2D249775A2FE4B3EF169AAD2ABD7405940CEFCE9BC025E02FE81F4437C2606E2AD2CF807E334F954671302CD53C47EB8462E44AD73F9FDB3095827542DD6060F3EF2E1472A3B11F0857CBE65B3839C3AD95DE71F0625A6CBDE94B8F3CD1F28993DE72BB9F089C6E30968CB3E365F0AE2D35490AD958C04DE9FF433C5C710D44DF7710C5A5B9A96A113659933B7212BC6BB2715FD7B080E2E01E7583AF6A99967A0E559E74363ACAEE7A94D1A601CF0DAD4B6DC50000"
|
||||
};
|
||||
|
||||
// 512
|
||||
yield return new object[]
|
||||
{
|
||||
"1CBB65F9B0CA8EB14FB956E0A7C3285B7A4FCCEACD3E6A12FB231ACC6F53C8ACDE096C2D6619F4DC44DF78EA1C22D0C97B42B3913BAFB20611CB092D8DDE854A91F47CB0C21F61813430469E7C3DCBDC2520494D690A0356965E49351917C4127B3BF76B0531510BD684158565B9CFCD08C51DC9F8A4650EE8B7637ED67CC2E1641713B6D111539902991E81F83B35950302EAC773F1FAC6DE8FA9448A4B40554DD4FDDDB969AC9706AB51CE84C562826C2695A977C20C09874C5264548234F658A83CD59C2870E9AF31423C782368E91852E0AA3F7A73C512017DEAB1D4443E46B61CE5FB9D2ADD800771C7D879C0E457319ACA3D12A1A8737094B079D901C8DCB7BC69428D3502532867CE086788667888D91ADEBCC59342D32ACD76E42D9663260D2069C13DEF4FF35F592287A7B7ECF7A630FC2DF995F736D658C779A4DF255F1BD8629BF427B329A3BBD0AFC2359B5ABD9CACA622723B1990B469DDFAF09D809D28260E5F75035B3EEAB9D1010E4F82E6FF77617C2A48B8E61F47BF264B36E4E4ED7C87F97661395B64DEF2A68C6A980F3EDB930D5B1487E131198B7481D2245C94D938A85A7233EFCA6F30958F147C0C400CA4BB4E6785CAF6581C9C067D2784A7A33EC34C1A52AF1031EB23AA57EBACCC57731466C04759968CA8412FEB11344B1BD377D41A7DEABE8D19DBA4ADF556D99A6095AB49F968CC890066C3",
|
||||
"FE0002001CBB65F9B0CA8EB14FB956E0A7C3285B7A4FCCEACD3E6A12FB231ACC6F53C8ACDE096C2D6619F4DC44DF78EA1C22D0C97B42B3913BAFB20611CB092D8DDE854A91F47CB0C21F61813430469E7C3DCBDC2520494D690A0356965E49351917C4127B3BF76B0531510BD684158565B9CFCD08C51DC9F8A4650EE8B7637ED67CC2E1641713B6D111539902991E81F83B35950302EAC773F1FAC6DE8FA9448A4B40554DD4FDDDB969AC9706AB51CE84C562826C2695A977C20C09874C5264548234F658A83CD59C2870E9AF31423C782368E91852E0AA3F7A73C512017DEAB1D4443E46B61CE5FB9D2ADD800771C7D879C0E457319ACA3D12A1A8737094B079D901C8DCB7BC69428D3502532867CE086788667888D91ADEBCC59342D32ACD76E42D9663260D2069C13DEF4FF35F592287A7B7ECF7A630FC2DF995F736D658C779A4DF255F1BD8629BF427B329A3BBD0AFC2359B5ABD9CACA622723B1990B469DDFAF09D809D28260E5F75035B3EEAB9D1010E4F82E6FF77617C2A48B8E61F47BF264B36E4E4ED7C87F97661395B64DEF2A68C6A980F3EDB930D5B1487E131198B7481D2245C94D938A85A7233EFCA6F30958F147C0C400CA4BB4E6785CAF6581C9C067D2784A7A33EC34C1A52AF1031EB23AA57EBACCC57731466C04759968CA8412FEB11344B1BD377D41A7DEABE8D19DBA4ADF556D99A6095AB49F968CC890066C3"
|
||||
};
|
||||
}
|
||||
|
||||
private BytesSerializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class DoubleSerializerTests
|
||||
{
|
||||
[InlineData(1.2345d)]
|
||||
[InlineData(-1.2345d)]
|
||||
[InlineData(10000.2345d)]
|
||||
[Theory]
|
||||
public void SerializeTest(double a)
|
||||
{
|
||||
var bytes = BitConverter.GetBytes(a);
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(a, writer);
|
||||
|
||||
var actualBytes = writer.WrittenSpan.ToArray();
|
||||
actualBytes.ShouldBeEquivalentTo(bytes);
|
||||
}
|
||||
|
||||
|
||||
[InlineData("8D976E1283C0F33F", 1.2345d)]
|
||||
[InlineData("8D976E1283C0F3BF", -1.2345d)]
|
||||
[InlineData("759318041E88C340", 10000.2345d)]
|
||||
[Theory]
|
||||
public void DeserializeTest(string data, double expectedValue)
|
||||
{
|
||||
var dataBytes = data.ToBytes();
|
||||
//var br = new BinaryReader(new MemoryStream(dataBytes));
|
||||
var serializer = CreateSerializer();
|
||||
ReadOnlyMemory<byte> buffer = dataBytes;
|
||||
|
||||
var actualValue = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualValue.ShouldBe(expectedValue);
|
||||
}
|
||||
|
||||
private DoubleSerializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static byte[] ToBytes(this string hex)
|
||||
{
|
||||
return HexToBytes(hex);
|
||||
}
|
||||
|
||||
//public static string ToHexString(this MemoryStream memoryStream) => memoryStream.ToArray().ToHexString();
|
||||
public static string ToHexString(this byte[] bytes) => BitConverter.ToString(bytes).Replace("-", string.Empty);
|
||||
|
||||
private static byte[] HexToBytes(string hex)
|
||||
{
|
||||
var text = hex.Replace(" ", string.Empty)
|
||||
.Replace("\r\n", string.Empty)
|
||||
.Replace("\n", string.Empty)
|
||||
.Replace("-", string.Empty)
|
||||
;
|
||||
return StringToByteArray(text);
|
||||
}
|
||||
|
||||
public static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class Int128SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var value = "C0CC11F66E1111B8529BB89742D77959".ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(value, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var expectedBytes = "C0CC11F66E1111B8529BB89742D77959".ToBytes();
|
||||
//var stream = new MemoryStream(expectedBytes);
|
||||
//var br = new BinaryReader(stream);
|
||||
var serializer = CreateSerializer();
|
||||
//var reader = new SequenceReader<byte>(new ReadOnlySequence<byte>(expectedBytes));
|
||||
ReadOnlyMemory<byte> buffer = expectedBytes;
|
||||
var actualBytes = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualBytes.ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
private Int128Serializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Buffers;
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
|
||||
|
||||
public class Int256SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var expectedBytes = "6B5DB1FB13049F1CBC9FE635C66786F220BF979222CF064F1A59DD0C23971293".ToBytes();
|
||||
//var stream = new MemoryStream(expectedBytes);
|
||||
//var br = new BinaryReader(stream);
|
||||
ReadOnlyMemory<byte> buffer = expectedBytes;
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
var actualBytes = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualBytes.ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var expectedBytes = "6B5DB1FB13049F1CBC9FE635C66786F220BF979222CF064F1A59DD0C23971293".ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(expectedBytes, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
private Int256Serializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class Int32SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var expectedValue = new byte[] { 01, 0, 0, 0 };
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(1, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var value = new byte[] { 01, 0, 0, 0 };
|
||||
var expectedValue = 1;
|
||||
ReadOnlyMemory<byte> buffer = value;
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
var actualValue = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualValue.ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
private Int32Serializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class Int64SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var expectedBytes = "6300000000000000".ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(99L, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var expectedBytes = "6300000000000000".ToBytes();
|
||||
ReadOnlyMemory<byte> buffer = expectedBytes;
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
var actualBytes = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualBytes.ShouldBeEquivalentTo(99L);
|
||||
}
|
||||
|
||||
private Int64Serializer CreateSerializer() => new();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
// ReSharper disable StringLiteralTypo
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
public class StringSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var value = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+<>?:{}[],./;'";
|
||||
var expectedValue =
|
||||
"576162636465666768696A6B6C6D6E6F707172737475767778797A4142434445464748494A4B4C4D4E4F505152535455565758595A3132333435363738393021402324255E262A28295F2B3C3E3F3A7B7D5B5D2C2E2F3B27"
|
||||
.ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(value, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var expectedValue = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+<>?:{}[],./;'";
|
||||
var value =
|
||||
"576162636465666768696A6B6C6D6E6F707172737475767778797A4142434445464748494A4B4C4D4E4F505152535455565758595A3132333435363738393021402324255E262A28295F2B3C3E3F3A7B7D5B5D2C2E2F3B27"
|
||||
.ToBytes();
|
||||
//var stream = new MemoryStream(value);
|
||||
//var br = new BinaryReader(stream);
|
||||
ReadOnlyMemory<byte> buffer = value;
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
var actualValue = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualValue.ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
private StringSerializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using MyTelegram.Schema.Extensions;
|
||||
|
||||
namespace MyTelegram.Schema.Serializer;
|
||||
|
||||
//public abstract class SerializeTestBase
|
||||
//{
|
||||
// protected void SerializeTest<TData>(TData t, byte[] expectedValue)
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
public class UInt32SerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeTest()
|
||||
{
|
||||
var expectedBytes = "09000080".ToBytes();
|
||||
//var stream = new MemoryStream();
|
||||
//var bw = new BinaryWriter(stream);
|
||||
var value = int.MaxValue + 10u;
|
||||
using var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var serializer = CreateSerializer();
|
||||
|
||||
serializer.Serialize(value, writer);
|
||||
|
||||
writer.WrittenSpan.ToArray().ShouldBeEquivalentTo(expectedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeTest()
|
||||
{
|
||||
var expectedBytes = "09000080".ToBytes();
|
||||
//var stream = new MemoryStream(expectedBytes);
|
||||
//var br = new BinaryReader(stream);
|
||||
//var buffer = new ReadOnlySequence<byte>(expectedBytes);
|
||||
var expectedValue = int.MaxValue + 10u;
|
||||
var serializer = CreateSerializer();
|
||||
ReadOnlyMemory<byte> buffer = expectedBytes;
|
||||
|
||||
var actualBytes = serializer.Deserialize(ref buffer);
|
||||
|
||||
actualBytes.ShouldBeEquivalentTo(expectedValue);
|
||||
}
|
||||
|
||||
private UInt32Serializer CreateSerializer() => new();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,13 @@
|
||||
global using System;
|
||||
global using System.IO;
|
||||
global using System.Linq;
|
||||
global using System.Collections;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Buffers;
|
||||
|
||||
global using Xunit;
|
||||
global using Shouldly;
|
||||
|
||||
global using MyTelegram.Schema.Extensions;
|
||||
global using MyTelegram.Schema.Serializer;
|
||||
global using MyTelegram.TestBase;
|
||||
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MyTelegram.Services\MyTelegram.Services.csproj" />
|
||||
<ProjectReference Include="..\..\src\MyTelegram.TestBase\MyTelegram.TestBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Fody">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,104 @@
|
||||
using Moq;
|
||||
using MyTelegram.Services.TLObjectConverters;
|
||||
|
||||
namespace MyTelegram.Services.Tests.TLObjectConverters;
|
||||
|
||||
public class LayeredServiceTests : TestsFor<LayeredService<ILayeredConverter>>
|
||||
{
|
||||
private List<ILayeredConverter> _converters = [];
|
||||
|
||||
private void SetupConverters(List<int> layers)
|
||||
{
|
||||
_converters =
|
||||
[
|
||||
.. layers.Select(layer =>
|
||||
{
|
||||
var mockConverter = new Mock<ILayeredConverter>();
|
||||
mockConverter.SetupGet(c => c.Layer).Returns(layer);
|
||||
return mockConverter.Object;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
protected override LayeredService<ILayeredConverter> CreateSut()
|
||||
{
|
||||
return new LayeredService<ILayeredConverter>(_converters);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new int[] { 180, 184, 195, 198 }, 0, 198)]
|
||||
[InlineData(new int[] { 180, 184, 195, 198 }, 184, 184)]
|
||||
[InlineData(new int[] { 180, 184, 195, 198 }, 100, 180)]
|
||||
[InlineData(new int[] { 180, 184, 195, 198 }, 250, 198)]
|
||||
[InlineData(new int[] { 180, 184, 195, 198 }, 190, 195)]
|
||||
[InlineData(new int[] { 180, 191, 195, 198 }, 187, 191)]
|
||||
[InlineData(new int[] { 184, 195, 198 }, 187, 195)]
|
||||
|
||||
public void GetConverter_ShouldReturnExpectedLayer(int[] layers, int requestLayer, int expectedLayer)
|
||||
{
|
||||
SetupConverters([.. layers]);
|
||||
var sut = CreateSut();
|
||||
|
||||
var result = sut.GetConverter(requestLayer);
|
||||
|
||||
result.Layer.ShouldBe(expectedLayer);
|
||||
}
|
||||
|
||||
//public LayeredServiceTests()
|
||||
//{
|
||||
// var mockConverter1 = new Mock<ILayeredConverter>();
|
||||
// var mockConverter2 = new Mock<ILayeredConverter>();
|
||||
// var mockConverter3 = new Mock<ILayeredConverter>();
|
||||
// var mockConverter4 = new Mock<ILayeredConverter>();
|
||||
|
||||
// mockConverter1.SetupGet(c => c.Layer).Returns(180);
|
||||
// mockConverter2.SetupGet(c => c.Layer).Returns(184);
|
||||
// mockConverter3.SetupGet(c => c.Layer).Returns(195);
|
||||
// mockConverter4.SetupGet(c => c.Layer).Returns(198);
|
||||
|
||||
// Inject<IEnumerable<ILayeredConverter>>(new List<ILayeredConverter>([mockConverter1.Object, mockConverter2.Object, mockConverter3.Object,
|
||||
// mockConverter4.Object]));
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void Constructor_ShouldInitializeCorrectly()
|
||||
//{
|
||||
// Sut.Converter.Layer.ShouldBe(198);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void GetConverter_ShouldReturnLatestLayerConverter_WhenLayerIsZero()
|
||||
//{
|
||||
// var result = Sut.GetConverter(0);
|
||||
// result.Layer.ShouldBe(198);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void GetConverter_ShouldReturnExactMatch_WhenLayerExists()
|
||||
//{
|
||||
// var result = Sut.GetConverter(184);
|
||||
// result.Layer.ShouldBe(184);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void GetConverter_ShouldReturnMinLayerConverter_WhenLayerBelowMin()
|
||||
//{
|
||||
// var result = Sut.GetConverter(100);
|
||||
// result.Layer.ShouldBe(180);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//[Theory]
|
||||
//public void GetConverter_ShouldReturnMaxLayerConverter_WhenLayerAboveMax()
|
||||
//{
|
||||
// var result = Sut.GetConverter(250);
|
||||
// result.Layer.ShouldBe(198);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public void GetConverter_ShouldReturnClosestLowerLayer_WhenLayerNotExists()
|
||||
//{
|
||||
// var result = Sut.GetConverter(190);
|
||||
// result.Layer.ShouldBe(184);
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//namespace MyTelegram.Services.Tests;
|
||||
|
||||
//public class UnitTest1
|
||||
//{
|
||||
// [Fact]
|
||||
// public void Test1()
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
Reference in New Issue
Block a user