mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-08-07 04:18:38 +00:00
Prevent heart activity spam and fix photo grouping
This commit is contained in:
parent
4d2645b7c3
commit
41d2b5be7d
3 changed files with 274 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Database;
|
||||
|
@ -205,6 +206,55 @@ public class ActivityEventHandlerTests
|
|||
.FirstOrDefault(a => a.Type == EventType.HeartLevel && a.SlotId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedLevel_InsertDuplicate_ShouldRemoveOldActivity()
|
||||
{
|
||||
ActivityEntityEventHandler eventHandler = new();
|
||||
DatabaseContext database = await MockHelper.GetTestDatabase(new List<UserEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Username = "test",
|
||||
UserId = 1,
|
||||
},
|
||||
});
|
||||
|
||||
SlotEntity slot = new()
|
||||
{
|
||||
SlotId = 1,
|
||||
CreatorId = 1,
|
||||
};
|
||||
database.Slots.Add(slot);
|
||||
|
||||
LevelActivityEntity levelActivity = new()
|
||||
{
|
||||
UserId = 1,
|
||||
SlotId = 1,
|
||||
Type = EventType.HeartLevel,
|
||||
Timestamp = DateTime.MinValue,
|
||||
};
|
||||
|
||||
database.Activities.Add(levelActivity);
|
||||
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
HeartedLevelEntity heartedLevel = new()
|
||||
{
|
||||
HeartedLevelId = 1,
|
||||
UserId = 1,
|
||||
SlotId = 1,
|
||||
Slot = slot,
|
||||
};
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<LevelActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.HeartLevel && a.SlotId == 1 && a.Timestamp == DateTime.MinValue));
|
||||
|
||||
eventHandler.OnEntityInserted(database, heartedLevel);
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<LevelActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.HeartLevel && a.SlotId == 1 && a.Timestamp != DateTime.MinValue));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedProfile_Insert_ShouldCreateUserActivity()
|
||||
{
|
||||
|
@ -231,6 +281,46 @@ public class ActivityEventHandlerTests
|
|||
.FirstOrDefault(a => a.Type == EventType.HeartUser && a.TargetUserId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedProfile_InsertDuplicate_ShouldRemoveOldActivity()
|
||||
{
|
||||
ActivityEntityEventHandler eventHandler = new();
|
||||
DatabaseContext database = await MockHelper.GetTestDatabase(new List<UserEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Username = "test",
|
||||
UserId = 1,
|
||||
},
|
||||
});
|
||||
|
||||
UserActivityEntity userActivity = new()
|
||||
{
|
||||
UserId = 1,
|
||||
TargetUserId = 1,
|
||||
Type = EventType.HeartUser,
|
||||
Timestamp = DateTime.MinValue,
|
||||
};
|
||||
|
||||
database.Activities.Add(userActivity);
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<UserActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.HeartUser && a.TargetUserId == 1 && a.Timestamp == DateTime.MinValue));
|
||||
|
||||
HeartedProfileEntity heartedProfile = new()
|
||||
{
|
||||
HeartedProfileId = 1,
|
||||
UserId = 1,
|
||||
HeartedUserId = 1,
|
||||
};
|
||||
|
||||
eventHandler.OnEntityInserted(database, heartedProfile);
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<UserActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.HeartUser && a.TargetUserId == 1 && a.Timestamp != DateTime.MinValue));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedPlaylist_Insert_ShouldCreatePlaylistActivity()
|
||||
{
|
||||
|
@ -265,6 +355,54 @@ public class ActivityEventHandlerTests
|
|||
.FirstOrDefault(a => a.Type == EventType.HeartPlaylist && a.PlaylistId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedPlaylist_InsertDuplicate_ShouldCreatePlaylistActivity()
|
||||
{
|
||||
ActivityEntityEventHandler eventHandler = new();
|
||||
DatabaseContext database = await MockHelper.GetTestDatabase(new List<UserEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Username = "test",
|
||||
UserId = 1,
|
||||
},
|
||||
});
|
||||
|
||||
PlaylistEntity playlist = new()
|
||||
{
|
||||
PlaylistId = 1,
|
||||
CreatorId = 1,
|
||||
};
|
||||
database.Playlists.Add(playlist);
|
||||
|
||||
PlaylistActivityEntity playlistActivity = new()
|
||||
{
|
||||
UserId = 1,
|
||||
PlaylistId = 1,
|
||||
Type = EventType.HeartPlaylist,
|
||||
Timestamp = DateTime.MinValue,
|
||||
};
|
||||
database.Activities.Add(playlistActivity);
|
||||
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
HeartedPlaylistEntity heartedPlaylist = new()
|
||||
{
|
||||
HeartedPlaylistId = 1,
|
||||
UserId = 1,
|
||||
PlaylistId = 1,
|
||||
};
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<PlaylistActivityEntity>()
|
||||
.FirstOrDefault(a =>
|
||||
a.Type == EventType.HeartPlaylist && a.PlaylistId == 1 && a.Timestamp == DateTime.MinValue));
|
||||
|
||||
eventHandler.OnEntityInserted(database, heartedPlaylist);
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<PlaylistActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.HeartPlaylist && a.PlaylistId == 1 && a.Timestamp != DateTime.MinValue));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task VisitedLevel_Insert_ShouldCreateLevelActivity()
|
||||
{
|
||||
|
@ -696,6 +834,52 @@ public class ActivityEventHandlerTests
|
|||
.FirstOrDefault(a => a.Type == EventType.UnheartLevel && a.SlotId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedLevel_DeleteDuplicate_ShouldRemoveOldActivity()
|
||||
{
|
||||
ActivityEntityEventHandler eventHandler = new();
|
||||
DatabaseContext database = await MockHelper.GetTestDatabase(new List<UserEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Username = "test",
|
||||
UserId = 1,
|
||||
},
|
||||
});
|
||||
|
||||
SlotEntity slot = new()
|
||||
{
|
||||
SlotId = 1,
|
||||
CreatorId = 1,
|
||||
};
|
||||
database.Slots.Add(slot);
|
||||
|
||||
LevelActivityEntity levelActivity = new()
|
||||
{
|
||||
UserId = 1,
|
||||
SlotId = 1,
|
||||
Type = EventType.UnheartLevel,
|
||||
Timestamp = DateTime.MinValue,
|
||||
};
|
||||
|
||||
database.Activities.Add(levelActivity);
|
||||
|
||||
HeartedLevelEntity heartedLevel = new()
|
||||
{
|
||||
HeartedLevelId = 1,
|
||||
UserId = 1,
|
||||
SlotId = 1,
|
||||
};
|
||||
|
||||
database.HeartedLevels.Add(heartedLevel);
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
eventHandler.OnEntityDeleted(database, heartedLevel);
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<LevelActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.UnheartLevel && a.SlotId == 1 && a.Timestamp != DateTime.MinValue));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedProfile_Delete_ShouldCreateLevelActivity()
|
||||
{
|
||||
|
@ -731,5 +915,46 @@ public class ActivityEventHandlerTests
|
|||
Assert.NotNull(database.Activities.OfType<UserActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.UnheartUser && a.UserId == 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HeartedProfile_DeleteDuplicate_ShouldCreateLevelActivity()
|
||||
{
|
||||
ActivityEntityEventHandler eventHandler = new();
|
||||
DatabaseContext database = await MockHelper.GetTestDatabase(new List<UserEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Username = "test",
|
||||
UserId = 1,
|
||||
},
|
||||
});
|
||||
|
||||
UserActivityEntity userActivity = new()
|
||||
{
|
||||
UserId = 1,
|
||||
TargetUserId = 1,
|
||||
Type = EventType.UnheartUser,
|
||||
Timestamp = DateTime.MinValue,
|
||||
};
|
||||
database.Activities.Add(userActivity);
|
||||
|
||||
HeartedProfileEntity heartedProfile = new()
|
||||
{
|
||||
HeartedProfileId = 1,
|
||||
UserId = 1,
|
||||
HeartedUserId = 1,
|
||||
};
|
||||
|
||||
database.HeartedProfiles.Add(heartedProfile);
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<UserActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.UnheartUser && a.UserId == 1 && a.Timestamp == DateTime.MinValue));
|
||||
|
||||
eventHandler.OnEntityDeleted(database, heartedProfile);
|
||||
|
||||
Assert.NotNull(database.Activities.OfType<UserActivityEntity>()
|
||||
.FirstOrDefault(a => a.Type == EventType.UnheartUser && a.UserId == 1 && a.Timestamp != DateTime.MinValue));
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -118,7 +118,7 @@ public static class ActivityQueryExtensions
|
|||
? ((UserActivityEntity)a).TargetUserId
|
||||
: a is CommentActivityEntity && ((CommentActivityEntity)a).Comment.Type == CommentType.Profile
|
||||
? ((CommentActivityEntity)a).Comment.TargetUserId
|
||||
: a is PhotoActivityEntity && ((PhotoActivityEntity)a).Photo.SlotId != 0
|
||||
: a is PhotoActivityEntity && ((PhotoActivityEntity)a).Photo.SlotId == 0
|
||||
? ((PhotoActivityEntity)a).Photo.CreatorId
|
||||
: 0,
|
||||
TargetPlaylistId = a is PlaylistActivityEntity || a is PlaylistWithSlotActivityEntity
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using LBPUnion.ProjectLighthouse.Database;
|
||||
using LBPUnion.ProjectLighthouse.Extensions;
|
||||
using LBPUnion.ProjectLighthouse.Logging;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Activity;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
|
||||
|
@ -144,12 +146,57 @@ public class ActivityEntityEventHandler : IEntityEventHandler
|
|||
InsertActivity(database, activity);
|
||||
}
|
||||
|
||||
private static void RemoveDuplicateEvents(DatabaseContext database, ActivityEntity activity)
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
|
||||
switch (activity.Type)
|
||||
{
|
||||
case EventType.HeartLevel:
|
||||
case EventType.UnheartLevel:
|
||||
{
|
||||
if (activity is not LevelActivityEntity levelActivity) break;
|
||||
|
||||
DeleteActivity(a => a.TargetSlotId == levelActivity.SlotId);
|
||||
break;
|
||||
}
|
||||
case EventType.HeartUser:
|
||||
case EventType.UnheartUser:
|
||||
{
|
||||
if (activity is not UserActivityEntity userActivity) break;
|
||||
|
||||
DeleteActivity(a => a.TargetUserId == userActivity.TargetUserId);
|
||||
break;
|
||||
}
|
||||
case EventType.HeartPlaylist:
|
||||
{
|
||||
if (activity is not PlaylistActivityEntity playlistActivity) break;
|
||||
|
||||
DeleteActivity(a => a.TargetPlaylistId == playlistActivity.PlaylistId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
void DeleteActivity(Expression<Func<ActivityDto, bool>> predicate)
|
||||
{
|
||||
database.Activities.ToActivityDto()
|
||||
.Where(a => a.Activity.UserId == activity.UserId)
|
||||
.Where(a => a.Activity.Type == activity.Type)
|
||||
.Where(predicate)
|
||||
.Select(a => a.Activity)
|
||||
.ExecuteDelete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertActivity(DatabaseContext database, ActivityEntity? activity)
|
||||
{
|
||||
if (activity == null) return;
|
||||
|
||||
Logger.Debug("Inserting activity: " + activity.GetType().Name, LogArea.Activity);
|
||||
|
||||
RemoveDuplicateEvents(database, activity);
|
||||
|
||||
activity.Timestamp = DateTime.UtcNow;
|
||||
database.Activities.Add(activity);
|
||||
database.SaveChanges();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue