added reply filtering
This commit is contained in:
parent
fee7810d8a
commit
40d6f69446
10 changed files with 600 additions and 17 deletions
|
@ -10,4 +10,5 @@ You can configure some of BirdsiteLIVE's settings via environment variables (tho
|
||||||
## Instance customization
|
## Instance customization
|
||||||
|
|
||||||
* `Instance:Name` (default: BirdsiteLIVE) the name of the instance
|
* `Instance:Name` (default: BirdsiteLIVE) the name of the instance
|
||||||
* `Instance:ResolveMentionsInProfiles` (default: true) to enable or disable mentions parsing in profile's description. Resolving it will consume more User's API calls since newly discovered account can also contain references to others accounts as well. On a big instance it is recommended to disable it.
|
* `Instance:ResolveMentionsInProfiles` (default: true) to enable or disable mentions parsing in profile's description. Resolving it will consume more User's API calls since newly discovered account can also contain references to others accounts as well. On a big instance it is recommended to disable it.
|
||||||
|
* `Instance:PublishReplies` (default: false) to enable or disable replies publishing.
|
|
@ -6,5 +6,6 @@
|
||||||
public string Domain { get; set; }
|
public string Domain { get; set; }
|
||||||
public string AdminEmail { get; set; }
|
public string AdminEmail { get; set; }
|
||||||
public bool ResolveMentionsInProfiles { get; set; }
|
public bool ResolveMentionsInProfiles { get; set; }
|
||||||
|
public bool PublishReplies { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.Common.Settings;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
using BirdsiteLive.Domain;
|
using BirdsiteLive.Domain;
|
||||||
|
@ -21,15 +22,17 @@ namespace BirdsiteLive.Pipeline.Processors.SubTasks
|
||||||
private readonly IActivityPubService _activityPubService;
|
private readonly IActivityPubService _activityPubService;
|
||||||
private readonly IStatusService _statusService;
|
private readonly IStatusService _statusService;
|
||||||
private readonly IFollowersDal _followersDal;
|
private readonly IFollowersDal _followersDal;
|
||||||
|
private readonly InstanceSettings _settings;
|
||||||
private readonly ILogger<SendTweetsToInboxTask> _logger;
|
private readonly ILogger<SendTweetsToInboxTask> _logger;
|
||||||
|
|
||||||
|
|
||||||
#region Ctor
|
#region Ctor
|
||||||
public SendTweetsToInboxTask(IActivityPubService activityPubService, IStatusService statusService, IFollowersDal followersDal, ILogger<SendTweetsToInboxTask> logger)
|
public SendTweetsToInboxTask(IActivityPubService activityPubService, IStatusService statusService, IFollowersDal followersDal, InstanceSettings settings, ILogger<SendTweetsToInboxTask> logger)
|
||||||
{
|
{
|
||||||
_activityPubService = activityPubService;
|
_activityPubService = activityPubService;
|
||||||
_statusService = statusService;
|
_statusService = statusService;
|
||||||
_followersDal = followersDal;
|
_followersDal = followersDal;
|
||||||
|
_settings = settings;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -52,8 +55,13 @@ namespace BirdsiteLive.Pipeline.Processors.SubTasks
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var note = _statusService.GetStatus(user.Acct, tweet);
|
if (!tweet.IsReply ||
|
||||||
await _activityPubService.PostNewNoteActivity(note, user.Acct, tweet.Id.ToString(), follower.Host, inbox);
|
tweet.IsReply && tweet.IsThread ||
|
||||||
|
_settings.PublishReplies)
|
||||||
|
{
|
||||||
|
var note = _statusService.GetStatus(user.Acct, tweet);
|
||||||
|
await _activityPubService.PostNewNoteActivity(note, user.Acct, tweet.Id.ToString(), follower.Host, inbox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ArgumentException e)
|
catch (ArgumentException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.Common.Settings;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
using BirdsiteLive.Domain;
|
using BirdsiteLive.Domain;
|
||||||
|
@ -20,14 +21,16 @@ namespace BirdsiteLive.Pipeline.Processors.SubTasks
|
||||||
private readonly IStatusService _statusService;
|
private readonly IStatusService _statusService;
|
||||||
private readonly IActivityPubService _activityPubService;
|
private readonly IActivityPubService _activityPubService;
|
||||||
private readonly IFollowersDal _followersDal;
|
private readonly IFollowersDal _followersDal;
|
||||||
|
private readonly InstanceSettings _settings;
|
||||||
private readonly ILogger<SendTweetsToSharedInboxTask> _logger;
|
private readonly ILogger<SendTweetsToSharedInboxTask> _logger;
|
||||||
|
|
||||||
#region Ctor
|
#region Ctor
|
||||||
public SendTweetsToSharedInboxTask(IActivityPubService activityPubService, IStatusService statusService, IFollowersDal followersDal, ILogger<SendTweetsToSharedInboxTask> logger)
|
public SendTweetsToSharedInboxTask(IActivityPubService activityPubService, IStatusService statusService, IFollowersDal followersDal, InstanceSettings settings, ILogger<SendTweetsToSharedInboxTask> logger)
|
||||||
{
|
{
|
||||||
_activityPubService = activityPubService;
|
_activityPubService = activityPubService;
|
||||||
_statusService = statusService;
|
_statusService = statusService;
|
||||||
_followersDal = followersDal;
|
_followersDal = followersDal;
|
||||||
|
_settings = settings;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -52,8 +55,13 @@ namespace BirdsiteLive.Pipeline.Processors.SubTasks
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var note = _statusService.GetStatus(user.Acct, tweet);
|
if (!tweet.IsReply ||
|
||||||
await _activityPubService.PostNewNoteActivity(note, user.Acct, tweet.Id.ToString(), host, inbox);
|
tweet.IsReply && tweet.IsThread ||
|
||||||
|
_settings.PublishReplies)
|
||||||
|
{
|
||||||
|
var note = _statusService.GetStatus(user.Acct, tweet);
|
||||||
|
await _activityPubService.PostNewNoteActivity(note, user.Acct, tweet.Id.ToString(), host, inbox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ArgumentException e)
|
catch (ArgumentException e)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +74,7 @@ namespace BirdsiteLive.Pipeline.Processors.SubTasks
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncStatus = tweet.Id;
|
syncStatus = tweet.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ namespace BirdsiteLive.Twitter.Extractors
|
||||||
InReplyToAccount = tweet.InReplyToScreenName,
|
InReplyToAccount = tweet.InReplyToScreenName,
|
||||||
MessageContent = ExtractMessage(tweet),
|
MessageContent = ExtractMessage(tweet),
|
||||||
Media = ExtractMedia(tweet.Media),
|
Media = ExtractMedia(tweet.Media),
|
||||||
CreatedAt = tweet.CreatedAt.ToUniversalTime()
|
CreatedAt = tweet.CreatedAt.ToUniversalTime(),
|
||||||
|
IsReply = tweet.InReplyToUserId != null,
|
||||||
|
IsThread = tweet.InReplyToUserId != null && tweet.InReplyToUserId == tweet.CreatedBy.Id
|
||||||
};
|
};
|
||||||
return extractedTweet;
|
return extractedTweet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,7 @@ namespace BirdsiteLive.Twitter.Models
|
||||||
public ExtractedMedia[] Media { get; set; }
|
public ExtractedMedia[] Media { get; set; }
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public string InReplyToAccount { get; set; }
|
public string InReplyToAccount { get; set; }
|
||||||
|
public bool IsReply { get; set; }
|
||||||
|
public bool IsThread { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -40,7 +40,7 @@ namespace BirdsiteLive.Twitter
|
||||||
var tweet = Tweet.GetTweet(statusId);
|
var tweet = Tweet.GetTweet(statusId);
|
||||||
_statisticsHandler.CalledTweetApi();
|
_statisticsHandler.CalledTweetApi();
|
||||||
if (tweet == null) return null; //TODO: test this
|
if (tweet == null) return null; //TODO: test this
|
||||||
return _tweetExtractor.Extract(tweet);
|
return _tweetExtractor.Extract(tweet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1)
|
public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1)
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
"Name": "BirdsiteLIVE",
|
"Name": "BirdsiteLIVE",
|
||||||
"Domain": "domain.name",
|
"Domain": "domain.name",
|
||||||
"AdminEmail": "me@domain.name",
|
"AdminEmail": "me@domain.name",
|
||||||
"ResolveMentionsInProfiles": true
|
"ResolveMentionsInProfiles": true,
|
||||||
|
"PublishReplies": false
|
||||||
},
|
},
|
||||||
"Db": {
|
"Db": {
|
||||||
"Type": "postgres",
|
"Type": "postgres",
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BirdsiteLive.ActivityPub.Models;
|
using BirdsiteLive.ActivityPub.Models;
|
||||||
|
using BirdsiteLive.Common.Settings;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
using BirdsiteLive.Domain;
|
using BirdsiteLive.Domain;
|
||||||
|
@ -54,6 +55,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
InboxRoute = inbox,
|
InboxRoute = inbox,
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -83,7 +89,239 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_Reply_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/user/inbox";
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
InboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_ReplyThread_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/user/inbox";
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
InboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
activityPubService
|
||||||
|
.Setup(x => x.PostNewNoteActivity(
|
||||||
|
It.Is<Note>(y => y.id == noteId),
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<string>(y => y == tweetId.ToString()),
|
||||||
|
It.Is<string>(y => y == host),
|
||||||
|
It.Is<string>(y => y == inbox)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
statusServiceMock
|
||||||
|
.Setup(x => x.GetStatus(
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<ExtractedTweet>(y => y.Id == tweetId)))
|
||||||
|
.Returns(note);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_PublishReply_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/user/inbox";
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
InboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = true
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
activityPubService
|
||||||
|
.Setup(x => x.PostNewNoteActivity(
|
||||||
|
It.Is<Note>(y => y.id == noteId),
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<string>(y => y == tweetId.ToString()),
|
||||||
|
It.Is<string>(y => y == host),
|
||||||
|
It.Is<string>(y => y == inbox)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
statusServiceMock
|
||||||
|
.Setup(x => x.GetStatus(
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<ExtractedTweet>(y => y.Id == tweetId)))
|
||||||
|
.Returns(note);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
|
@ -126,6 +364,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
InboxRoute = inbox,
|
InboxRoute = inbox,
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 10 } }
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 10 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -161,7 +404,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
await task.ExecuteAsync(tweets.ToArray(), follower, twitterUser);
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
|
@ -205,6 +448,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
InboxRoute = inbox,
|
InboxRoute = inbox,
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 10 } }
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 10 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -247,7 +495,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BirdsiteLive.ActivityPub.Models;
|
using BirdsiteLive.ActivityPub.Models;
|
||||||
|
using BirdsiteLive.Common.Settings;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
using BirdsiteLive.Domain;
|
using BirdsiteLive.Domain;
|
||||||
|
@ -72,6 +73,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 7 } }
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 7 } }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -105,7 +111,303 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_Reply_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/inbox";
|
||||||
|
var followers = new List<Follower>
|
||||||
|
{
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 8 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 7 } }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
foreach (var follower in followers)
|
||||||
|
{
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_ReplyThread_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/inbox";
|
||||||
|
var followers = new List<Follower>
|
||||||
|
{
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 8 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 7 } }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
activityPubService
|
||||||
|
.Setup(x => x.PostNewNoteActivity(
|
||||||
|
It.Is<Note>(y => y.id == noteId),
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<string>(y => y == tweetId.ToString()),
|
||||||
|
It.Is<string>(y => y == host),
|
||||||
|
It.Is<string>(y => y == inbox)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
statusServiceMock
|
||||||
|
.Setup(x => x.GetStatus(
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<ExtractedTweet>(y => y.Id == tweetId)))
|
||||||
|
.Returns(note);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
foreach (var follower in followers)
|
||||||
|
{
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
activityPubService.VerifyAll();
|
||||||
|
statusServiceMock.VerifyAll();
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_SingleTweet_PublishReply_Test()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var tweetId = 10;
|
||||||
|
var tweets = new List<ExtractedTweet>
|
||||||
|
{
|
||||||
|
new ExtractedTweet
|
||||||
|
{
|
||||||
|
Id = tweetId,
|
||||||
|
IsReply = true,
|
||||||
|
IsThread = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var noteId = "noteId";
|
||||||
|
var note = new Note()
|
||||||
|
{
|
||||||
|
id = noteId
|
||||||
|
};
|
||||||
|
|
||||||
|
var twitterHandle = "Test";
|
||||||
|
var twitterUserId = 7;
|
||||||
|
var twitterUser = new SyncTwitterUser
|
||||||
|
{
|
||||||
|
Id = twitterUserId,
|
||||||
|
Acct = twitterHandle
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = "domain.ext";
|
||||||
|
var inbox = "/inbox";
|
||||||
|
var followers = new List<Follower>
|
||||||
|
{
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 9 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 8 } }
|
||||||
|
},
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Host = host,
|
||||||
|
SharedInboxRoute = inbox,
|
||||||
|
FollowingsSyncStatus = new Dictionary<int, long> { { twitterUserId, 7 } }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = true
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var activityPubService = new Mock<IActivityPubService>(MockBehavior.Strict);
|
||||||
|
activityPubService
|
||||||
|
.Setup(x => x.PostNewNoteActivity(
|
||||||
|
It.Is<Note>(y => y.id == noteId),
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<string>(y => y == tweetId.ToString()),
|
||||||
|
It.Is<string>(y => y == host),
|
||||||
|
It.Is<string>(y => y == inbox)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var statusServiceMock = new Mock<IStatusService>(MockBehavior.Strict);
|
||||||
|
statusServiceMock
|
||||||
|
.Setup(x => x.GetStatus(
|
||||||
|
It.Is<string>(y => y == twitterHandle),
|
||||||
|
It.Is<ExtractedTweet>(y => y.Id == tweetId)))
|
||||||
|
.Returns(note);
|
||||||
|
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
foreach (var follower in followers)
|
||||||
|
{
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.UpdateFollowerAsync(
|
||||||
|
It.Is<Follower>(y => y.Id == follower.Id && y.FollowingsSyncStatus[twitterUserId] == tweetId)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
|
@ -165,6 +467,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> {{twitterUserId, 7}}
|
FollowingsSyncStatus = new Dictionary<int, long> {{twitterUserId, 7}}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -204,7 +511,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
await task.ExecuteAsync(tweets.ToArray(), twitterUser, host, followers.ToArray());
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
|
@ -265,6 +572,11 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
FollowingsSyncStatus = new Dictionary<int, long> {{twitterUserId, 7}}
|
FollowingsSyncStatus = new Dictionary<int, long> {{twitterUserId, 7}}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var settings = new InstanceSettings
|
||||||
|
{
|
||||||
|
PublishReplies = false
|
||||||
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -311,7 +623,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors.SubTasks
|
||||||
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
var loggerMock = new Mock<ILogger<SendTweetsToSharedInboxTask>>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, loggerMock.Object);
|
var task = new SendTweetsToSharedInboxTask(activityPubService.Object, statusServiceMock.Object, followersDalMock.Object, settings, loggerMock.Object);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue