Merge pull request #139 from NicolasConstant/topic_better-progression-handling

remove users if not followed
This commit is contained in:
Nicolas Constant 2022-02-10 00:39:35 -05:00 committed by GitHub
commit 4c4fc95da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 204 additions and 19 deletions

View File

@ -3,6 +3,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.DAL.Models;
using BirdsiteLive.Moderation.Actions;
using BirdsiteLive.Pipeline.Contracts;
using BirdsiteLive.Pipeline.Models;
using Microsoft.Extensions.Logging;
@ -13,12 +15,14 @@ namespace BirdsiteLive.Pipeline.Processors
{
private readonly ITwitterUserDal _twitterUserDal;
private readonly ILogger<SaveProgressionProcessor> _logger;
private readonly IRemoveTwitterAccountAction _removeTwitterAccountAction;
#region Ctor
public SaveProgressionProcessor(ITwitterUserDal twitterUserDal, ILogger<SaveProgressionProcessor> logger)
public SaveProgressionProcessor(ITwitterUserDal twitterUserDal, ILogger<SaveProgressionProcessor> logger, IRemoveTwitterAccountAction removeTwitterAccountAction)
{
_twitterUserDal = twitterUserDal;
_logger = logger;
_removeTwitterAccountAction = removeTwitterAccountAction;
}
#endregion
@ -28,24 +32,19 @@ namespace BirdsiteLive.Pipeline.Processors
{
if (userWithTweetsToSync.Tweets.Length == 0)
{
_logger.LogWarning("No tweets synchronized");
_logger.LogInformation("No tweets synchronized");
await UpdateUserSyncDateAsync(userWithTweetsToSync.User);
return;
}
if(userWithTweetsToSync.Followers.Length == 0)
{
_logger.LogWarning("No Followers found for {User}", userWithTweetsToSync.User.Acct);
_logger.LogInformation("No Followers found for {User}", userWithTweetsToSync.User.Acct);
await _removeTwitterAccountAction.ProcessAsync(userWithTweetsToSync.User);
return;
}
var userId = userWithTweetsToSync.User.Id;
var followingSyncStatuses = userWithTweetsToSync.Followers.Select(x => x.FollowingsSyncStatus[userId]).ToList();
if (followingSyncStatuses.Count == 0)
{
_logger.LogWarning("No Followers sync found for {User}, Id: {UserId}", userWithTweetsToSync.User.Acct, userId);
return;
}
var lastPostedTweet = userWithTweetsToSync.Tweets.Select(x => x.Id).Max();
var minimumSync = followingSyncStatuses.Min();
var now = DateTime.UtcNow;
@ -57,5 +56,11 @@ namespace BirdsiteLive.Pipeline.Processors
throw;
}
}
private async Task UpdateUserSyncDateAsync(SyncTwitterUser user)
{
user.LastSync = DateTime.UtcNow;
await _twitterUserDal.UpdateTwitterUserAsync(user);
}
}
}

View File

@ -1,16 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.DAL.Models;
using BirdsiteLive.Moderation.Actions;
using BirdsiteLive.Pipeline.Models;
using BirdsiteLive.Pipeline.Processors;
using BirdsiteLive.Twitter.Models;
using Castle.DynamicProxy.Contributors;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace BirdsiteLive.Pipeline.Tests.Processors
{
@ -69,14 +69,84 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
It.IsAny<DateTime>()
))
.Returns(Task.CompletedTask);
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object);
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task ProcessAsync_Exception_Test()
{
#region Stubs
var user = new SyncTwitterUser
{
Id = 1
};
var tweet1 = new ExtractedTweet
{
Id = 36
};
var tweet2 = new ExtractedTweet
{
Id = 37
};
var follower1 = new Follower
{
FollowingsSyncStatus = new Dictionary<int, long>
{
{1, 37}
}
};
var usersWithTweets = new UserWithDataToSync
{
Tweets = new[]
{
tweet1,
tweet2
},
Followers = new[]
{
follower1
},
User = user
};
var loggerMock = new Mock<ILogger<SaveProgressionProcessor>>();
#endregion
#region Mocks
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
twitterUserDalMock
.Setup(x => x.UpdateTwitterUserAsync(
It.Is<int>(y => y == user.Id),
It.Is<long>(y => y == tweet2.Id),
It.Is<long>(y => y == tweet2.Id),
It.Is<int>(y => y == 0),
It.IsAny<DateTime>()
))
.Throws(new ArgumentException());
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
@ -137,14 +207,17 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
.Returns(Task.CompletedTask);
var loggerMock = new Mock<ILogger<SaveProgressionProcessor>>();
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object);
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
@ -213,15 +286,122 @@ namespace BirdsiteLive.Pipeline.Tests.Processors
.Returns(Task.CompletedTask);
var loggerMock = new Mock<ILogger<SaveProgressionProcessor>>();
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object);
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
[TestMethod]
public async Task ProcessAsync_NoTweets_Test()
{
#region Stubs
var user = new SyncTwitterUser
{
Id = 1,
LastTweetPostedId = 42,
LastSync = DateTime.UtcNow.AddDays(-3)
};
var follower1 = new Follower
{
FollowingsSyncStatus = new Dictionary<int, long>
{
{1, 37}
}
};
var usersWithTweets = new UserWithDataToSync
{
Tweets = Array.Empty<ExtractedTweet>(),
Followers = new[]
{
follower1
},
User = user
};
var loggerMock = new Mock<ILogger<SaveProgressionProcessor>>();
#endregion
#region Mocks
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
twitterUserDalMock
.Setup(x => x.UpdateTwitterUserAsync(
It.Is<SyncTwitterUser>(y => y.LastTweetPostedId == 42
&& y.LastSync > DateTime.UtcNow.AddDays(-1))
))
.Returns(Task.CompletedTask);
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
[TestMethod]
public async Task ProcessAsync_NoFollower_Test()
{
#region Stubs
var user = new SyncTwitterUser
{
Id = 1
};
var tweet1 = new ExtractedTweet
{
Id = 36
};
var tweet2 = new ExtractedTweet
{
Id = 37
};
var usersWithTweets = new UserWithDataToSync
{
Tweets = new[]
{
tweet1,
tweet2
},
Followers = Array.Empty<Follower>(),
User = user
};
var loggerMock = new Mock<ILogger<SaveProgressionProcessor>>();
#endregion
#region Mocks
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
var removeTwitterAccountActionMock = new Mock<IRemoveTwitterAccountAction>(MockBehavior.Strict);
removeTwitterAccountActionMock
.Setup(x => x.ProcessAsync(It.Is<SyncTwitterUser>(y => y.Id == user.Id)))
.Returns(Task.CompletedTask);
#endregion
var processor = new SaveProgressionProcessor(twitterUserDalMock.Object, loggerMock.Object, removeTwitterAccountActionMock.Object);
await processor.ProcessAsync(usersWithTweets, CancellationToken.None);
#region Validations
twitterUserDalMock.VerifyAll();
loggerMock.VerifyAll();
removeTwitterAccountActionMock.VerifyAll();
#endregion
}
}
}