commit
0825c8d06d
6 changed files with 374 additions and 5 deletions
|
@ -1,4 +1,5 @@
|
||||||
using System.Threading.Tasks;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
|
|
||||||
namespace BirdsiteLive.Domain.BusinessUseCases
|
namespace BirdsiteLive.Domain.BusinessUseCases
|
||||||
|
@ -38,8 +39,16 @@ namespace BirdsiteLive.Domain.BusinessUseCases
|
||||||
if (follower.FollowingsSyncStatus.ContainsKey(twitterUserId))
|
if (follower.FollowingsSyncStatus.ContainsKey(twitterUserId))
|
||||||
follower.FollowingsSyncStatus.Remove(twitterUserId);
|
follower.FollowingsSyncStatus.Remove(twitterUserId);
|
||||||
|
|
||||||
// Save Follower
|
// Save or delete Follower
|
||||||
await _followerDal.UpdateFollowerAsync(follower);
|
if (follower.Followings.Any())
|
||||||
|
await _followerDal.UpdateFollowerAsync(follower);
|
||||||
|
else
|
||||||
|
await _followerDal.DeleteFollowerAsync(followerUsername, followerDomain);
|
||||||
|
|
||||||
|
// Check if TwitterUser has still followers
|
||||||
|
var followers = await _followerDal.GetFollowersAsync(twitterUser.Id);
|
||||||
|
if (!followers.Any())
|
||||||
|
await _twitterUserDal.DeleteTwitterUserAsync(twitterUsername);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -137,7 +137,7 @@ namespace BirdsiteLive.Domain
|
||||||
if (!sigValidation.SignatureIsValidated) return false;
|
if (!sigValidation.SignatureIsValidated) return false;
|
||||||
|
|
||||||
// Save Follow in DB
|
// Save Follow in DB
|
||||||
var followerUserName = sigValidation.User.name.ToLowerInvariant();
|
var followerUserName = sigValidation.User.preferredUsername.ToLowerInvariant();
|
||||||
var followerHost = sigValidation.User.url.Replace("https://", string.Empty).Split('/').First();
|
var followerHost = sigValidation.User.url.Replace("https://", string.Empty).Split('/').First();
|
||||||
//var followerInbox = sigValidation.User.inbox;
|
//var followerInbox = sigValidation.User.inbox;
|
||||||
var twitterUser = activity.apObject.apObject.Split('/').Last().Replace("@", string.Empty);
|
var twitterUser = activity.apObject.apObject.Split('/').Last().Replace("@", string.Empty);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<UserSecretsId>d21486de-a812-47eb-a419-05682bb68856</UserSecretsId>
|
<UserSecretsId>d21486de-a812-47eb-a419-05682bb68856</UserSecretsId>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
<Version>0.2.0</Version>
|
<Version>0.3.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||||
|
<PackageReference Include="Moq" Version="4.14.5" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||||
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.DAL.Contracts;
|
||||||
|
using BirdsiteLive.DAL.Models;
|
||||||
|
using BirdsiteLive.Domain.BusinessUseCases;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Moq;
|
||||||
|
using Org.BouncyCastle.Crypto.Prng;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Domain.Tests.BusinessUseCases
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class ProcessFollowUserTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_UserDontExists_TwitterDontExists_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
var followerInbox = "/user/testest";
|
||||||
|
var inbox = "/inbox";
|
||||||
|
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Acct = username,
|
||||||
|
Host = domain,
|
||||||
|
SharedInboxRoute = followerInbox,
|
||||||
|
InboxRoute = inbox,
|
||||||
|
Followings = new List<int>(),
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long>()
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Acct = twitterName,
|
||||||
|
LastTweetPostedId = -1,
|
||||||
|
LastTweetSynchronizedForAllFollowersId = -1
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.SetupSequence(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync((Follower)null)
|
||||||
|
.ReturnsAsync(follower);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.CreateFollowerAsync(
|
||||||
|
It.Is<string>(y => y == username),
|
||||||
|
It.Is<string>(y => y == domain),
|
||||||
|
It.Is<string>(y => y == followerInbox),
|
||||||
|
It.Is<string>(y => y == inbox),
|
||||||
|
null,
|
||||||
|
null))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Followings.Contains(twitterUser.Id)
|
||||||
|
&& y.FollowingsSyncStatus[twitterUser.Id] == -1)
|
||||||
|
))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.SetupSequence(x => x.GetTwitterUserAsync(twitterName))
|
||||||
|
.ReturnsAsync((SyncTwitterUser)null)
|
||||||
|
.ReturnsAsync(twitterUser);
|
||||||
|
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.CreateTwitterUserAsync(
|
||||||
|
It.Is<string>(y => y == twitterName),
|
||||||
|
It.Is<long>(y => y == -1)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName, followerInbox, inbox);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_UserExists_TwitterExists_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
var followerInbox = "/user/testest";
|
||||||
|
var inbox = "/inbox";
|
||||||
|
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Acct = username,
|
||||||
|
Host = domain,
|
||||||
|
SharedInboxRoute = followerInbox,
|
||||||
|
InboxRoute = inbox,
|
||||||
|
Followings = new List<int>(),
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long>()
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Acct = twitterName,
|
||||||
|
LastTweetPostedId = -1,
|
||||||
|
LastTweetSynchronizedForAllFollowersId = -1
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync(follower);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Followings.Contains(twitterUser.Id)
|
||||||
|
&& y.FollowingsSyncStatus[twitterUser.Id] == -1)
|
||||||
|
))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.GetTwitterUserAsync(twitterName))
|
||||||
|
.ReturnsAsync(twitterUser);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName, followerInbox, inbox);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,210 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.DAL.Contracts;
|
||||||
|
using BirdsiteLive.DAL.Models;
|
||||||
|
using BirdsiteLive.Domain.BusinessUseCases;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Domain.Tests.BusinessUseCases
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class ProcessUnfollowUserTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_NoFollowerFound_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync((Follower) null);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessUndoFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName );
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_NoTwitterUserFound_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Acct = username,
|
||||||
|
Host = domain,
|
||||||
|
Followings = new List<int>(),
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long>()
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync(follower);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.GetTwitterUserAsync(twitterName))
|
||||||
|
.ReturnsAsync((SyncTwitterUser)null);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessUndoFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_MultiFollows_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Acct = username,
|
||||||
|
Host = domain,
|
||||||
|
Followings = new List<int> { 2, 3 },
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { 2, 460 }, { 3, 563} }
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Acct = twitterName,
|
||||||
|
LastTweetPostedId = 460,
|
||||||
|
LastTweetSynchronizedForAllFollowersId = 460
|
||||||
|
};
|
||||||
|
|
||||||
|
var followerList = new List<Follower>
|
||||||
|
{
|
||||||
|
new Follower(),
|
||||||
|
new Follower()
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync(follower);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => !y.Followings.Contains(twitterUser.Id)
|
||||||
|
&& !y.FollowingsSyncStatus.ContainsKey(twitterUser.Id))
|
||||||
|
))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowersAsync(twitterUser.Id))
|
||||||
|
.ReturnsAsync(followerList.ToArray());
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.GetTwitterUserAsync(twitterName))
|
||||||
|
.ReturnsAsync(twitterUser);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessUndoFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_CleanUp_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var username = "testest";
|
||||||
|
var domain = "m.s";
|
||||||
|
var twitterName = "handle";
|
||||||
|
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Acct = username,
|
||||||
|
Host = domain,
|
||||||
|
Followings = new List<int> { 2 },
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { 2, 460 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Acct = twitterName,
|
||||||
|
LastTweetPostedId = 460,
|
||||||
|
LastTweetSynchronizedForAllFollowersId = 460
|
||||||
|
};
|
||||||
|
|
||||||
|
var followerList = new List<Follower>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowerAsync(username, domain))
|
||||||
|
.ReturnsAsync(follower);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.DeleteFollowerAsync(
|
||||||
|
It.Is<string>(y => y == username),
|
||||||
|
It.Is<string>(y => y == domain)
|
||||||
|
))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowersAsync(twitterUser.Id))
|
||||||
|
.ReturnsAsync(followerList.ToArray());
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.GetTwitterUserAsync(twitterName))
|
||||||
|
.ReturnsAsync(twitterUser);
|
||||||
|
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.DeleteTwitterUserAsync(
|
||||||
|
It.Is<string>(y => y == twitterName)
|
||||||
|
))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessUndoFollowUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(username, domain, twitterName);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue