From 9415eb2e0c3ed29ddfa38d7e6cc0979f629c8d8a Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 10 Feb 2022 00:34:51 -0500 Subject: [PATCH] remove users if not followed --- .../Processors/SaveProgressionProcessor.cs | 25 ++- .../SaveProgressionProcessorTests.cs | 198 +++++++++++++++++- 2 files changed, 204 insertions(+), 19 deletions(-) diff --git a/src/BirdsiteLive.Pipeline/Processors/SaveProgressionProcessor.cs b/src/BirdsiteLive.Pipeline/Processors/SaveProgressionProcessor.cs index 1437255..f262f39 100644 --- a/src/BirdsiteLive.Pipeline/Processors/SaveProgressionProcessor.cs +++ b/src/BirdsiteLive.Pipeline/Processors/SaveProgressionProcessor.cs @@ -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 _logger; + private readonly IRemoveTwitterAccountAction _removeTwitterAccountAction; #region Ctor - public SaveProgressionProcessor(ITwitterUserDal twitterUserDal, ILogger logger) + public SaveProgressionProcessor(ITwitterUserDal twitterUserDal, ILogger 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); + } } } \ No newline at end of file diff --git a/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/SaveProgressionProcessorTests.cs b/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/SaveProgressionProcessorTests.cs index 4587071..feffbff 100644 --- a/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/SaveProgressionProcessorTests.cs +++ b/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/SaveProgressionProcessorTests.cs @@ -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() )) .Returns(Task.CompletedTask); + + var removeTwitterAccountActionMock = new Mock(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 + { + {1, 37} + } + }; + + var usersWithTweets = new UserWithDataToSync + { + Tweets = new[] + { + tweet1, + tweet2 + }, + Followers = new[] + { + follower1 + }, + User = user + }; + + var loggerMock = new Mock>(); + #endregion + + #region Mocks + var twitterUserDalMock = new Mock(MockBehavior.Strict); + twitterUserDalMock + .Setup(x => x.UpdateTwitterUserAsync( + It.Is(y => y == user.Id), + It.Is(y => y == tweet2.Id), + It.Is(y => y == tweet2.Id), + It.Is(y => y == 0), + It.IsAny() + )) + .Throws(new ArgumentException()); + + var removeTwitterAccountActionMock = new Mock(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>(); + + var removeTwitterAccountActionMock = new Mock(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>(); + + var removeTwitterAccountActionMock = new Mock(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 + { + {1, 37} + } + }; + + var usersWithTweets = new UserWithDataToSync + { + Tweets = Array.Empty(), + Followers = new[] + { + follower1 + }, + User = user + }; + + var loggerMock = new Mock>(); + #endregion + + #region Mocks + var twitterUserDalMock = new Mock(MockBehavior.Strict); + twitterUserDalMock + .Setup(x => x.UpdateTwitterUserAsync( + It.Is(y => y.LastTweetPostedId == 42 + && y.LastSync > DateTime.UtcNow.AddDays(-1)) + )) + .Returns(Task.CompletedTask); + + var removeTwitterAccountActionMock = new Mock(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(), + User = user + }; + + var loggerMock = new Mock>(); + #endregion + + #region Mocks + var twitterUserDalMock = new Mock(MockBehavior.Strict); + + var removeTwitterAccountActionMock = new Mock(MockBehavior.Strict); + removeTwitterAccountActionMock + .Setup(x => x.ProcessAsync(It.Is(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 + } + } } \ No newline at end of file