-
Notifications
You must be signed in to change notification settings - Fork 0
✨ Add functionality for managing user favorite activities #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -67,6 +67,98 @@ public IEnumerable<ActivityEntity> GetActiveActivitiesFiltered(int typeId, int e | |||||||||||
| return query; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| public List<ActivityEntity> GetFavouriteActivitiesByUser(int userId, int editionId) | ||||||||||||
| { | ||||||||||||
| if (userId == default || editionId == default) | ||||||||||||
| { | ||||||||||||
| return new List<ActivityEntity>(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| return GetFavActivitiesFiltered(0, editionId, null, null, userId).ToList(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| public bool AddFavouriteActivity(int activityId, int userId) | ||||||||||||
| { | ||||||||||||
| try | ||||||||||||
| { | ||||||||||||
| var user = _unitOfWork.UserRepository.GetById(userId); | ||||||||||||
| var activity = _unitOfWork.ActivityRepository.GetById(activityId); | ||||||||||||
|
|
||||||||||||
| if (user == null || activity == null) | ||||||||||||
| { | ||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| activity = _unitOfWork.ActivityRepository.GetAllIncludeFavs(activity.EditionId) | ||||||||||||
| .FirstOrDefault(a => a.Id == activityId); | ||||||||||||
|
|
||||||||||||
| if (activity == null) | ||||||||||||
| { | ||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (activity.UsersFav == null) | ||||||||||||
| { | ||||||||||||
| activity.UsersFav = new List<UserEntity>(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (activity.UsersFav.Any(u => u.Id == userId)) | ||||||||||||
| { | ||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| activity.UsersFav.Add(user); | ||||||||||||
|
|
||||||||||||
| _unitOfWork.ActivityRepository.Update(activity); | ||||||||||||
| _unitOfWork.ActivityRepository.Save(); | ||||||||||||
|
|
||||||||||||
| return true; | ||||||||||||
| } | ||||||||||||
| catch (Exception) | ||||||||||||
| { | ||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| public bool RemoveFavouriteActivity(int activityId, int userId) | ||||||||||||
| { | ||||||||||||
| try | ||||||||||||
| { | ||||||||||||
| var activity = _unitOfWork.ActivityRepository.GetById(activityId); | ||||||||||||
|
|
||||||||||||
| if (activity == null) | ||||||||||||
| { | ||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| activity = _unitOfWork.ActivityRepository.GetAllIncludeFavs(activity.EditionId) | ||||||||||||
| .FirstOrDefault(a => a.Id == activityId); | ||||||||||||
|
|
||||||||||||
| if (activity?.UsersFav == null) | ||||||||||||
|
Comment on lines
+134
to
+137
|
||||||||||||
| activity = _unitOfWork.ActivityRepository.GetAllIncludeFavs(activity.EditionId) | |
| .FirstOrDefault(a => a.Id == activityId); | |
| if (activity?.UsersFav == null) | |
| if (activity.UsersFav == null) |
Copilot
AI
Mar 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetFavActivitiesFiltered starts from GetAllIncludeFavs(editionId), which already applies an edition filter when editionId is non-default, and then immediately filters a.EditionId == editionId again. This redundancy makes the intent harder to read and risks diverging if repository filtering logic changes. Consider removing the duplicate edition predicate (or, more broadly, pushing the whole filter down into the repository so it runs in the database).
| .Where(a => a.EditionId == editionId | |
| && a.StatusId == activeStatus.Id | |
| .Where(a => a.StatusId == activeStatus.Id |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -365,6 +365,179 @@ public void ChangeActivityStatus_Success() | |||||
| commands.Verify(x => x.ChangeActivityStatusCommand(dto.StatusId, dto.ActivityId), Times.Once); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void GetFavouriteActivitiesByUser_Success() | ||||||
| { | ||||||
| // Arrange | ||||||
| int userId = 1; | ||||||
| int editionId = 2; | ||||||
| Mock<IActivityCommands> commands = new(); | ||||||
| Mock<IActivityQueries> queries = new(); | ||||||
| List<ActivityDto> dto = new() | ||||||
| { | ||||||
| new ActivityDto() | ||||||
| }; | ||||||
|
|
||||||
| queries.Setup(x => x.FavouriteActivitiesByUserQuery(userId, editionId)) | ||||||
| .Returns(dto); | ||||||
|
|
||||||
| ActivityController target = new(commands.Object, queries.Object); | ||||||
|
|
||||||
| // Act | ||||||
| IActionResult result = target.GetFavouriteActivitiesByUser(userId, editionId); | ||||||
|
|
||||||
| // Assert | ||||||
| var resultAsObjResult = result as ObjectResult; | ||||||
|
|
||||||
| result.Should().NotBeNull(); | ||||||
| resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status200OK); | ||||||
|
|
||||||
| queries.Verify(x => x.FavouriteActivitiesByUserQuery(userId, editionId), Times.Once); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void GetFavouriteActivitiesByUser_EmptyResult_Success() | ||||||
| { | ||||||
| // Arrange | ||||||
| int userId = 1; | ||||||
| int editionId = 2; | ||||||
| Mock<IActivityCommands> commands = new(); | ||||||
| Mock<IActivityQueries> queries = new(); | ||||||
| List<ActivityDto> dto = new(); | ||||||
|
|
||||||
| queries.Setup(x => x.FavouriteActivitiesByUserQuery(userId, editionId)) | ||||||
| .Returns(dto); | ||||||
|
|
||||||
| ActivityController target = new(commands.Object, queries.Object); | ||||||
|
|
||||||
| // Act | ||||||
| IActionResult result = target.GetFavouriteActivitiesByUser(userId, editionId); | ||||||
|
|
||||||
| // Assert | ||||||
| var resultAsObjResult = result as StatusCodeResult; | ||||||
|
|
||||||
| result.Should().NotBeNull(); | ||||||
| resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status204NoContent); | ||||||
|
|
||||||
| queries.Verify(x => x.FavouriteActivitiesByUserQuery(userId, editionId), Times.Once); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void AddFavouriteActivity_Success() | ||||||
| { | ||||||
| // Arrange | ||||||
| Mock<IActivityCommands> commands = new(); | ||||||
| Mock<IActivityQueries> queries = new(); | ||||||
| ActivityEnrollmentRequest request = new() | ||||||
| { | ||||||
| ActivityId = 1, | ||||||
| UserId = 1 | ||||||
| }; | ||||||
|
|
||||||
| commands.Setup(x => x.AddFavouriteActivityCommand(request)) | ||||||
| .Returns(true); | ||||||
|
|
||||||
| ActivityController target = new(commands.Object, queries.Object); | ||||||
|
|
||||||
| // Act | ||||||
| IActionResult result = target.AddFavouriteActivity(request); | ||||||
|
|
||||||
| // Assert | ||||||
| var resultAsObjResult = result as ObjectResult; | ||||||
|
|
||||||
| result.Should().NotBeNull(); | ||||||
| resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status200OK); | ||||||
|
|
||||||
| commands.Verify(x => x.AddFavouriteActivityCommand(request), Times.Once); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void AddFavouriteActivity_Fail_Success() | ||||||
|
||||||
| public void AddFavouriteActivity_Fail_Success() | |
| public void AddFavouriteActivity_Failure_ReturnsBadRequest() |
Copilot
AI
Mar 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test name RemoveFavouriteActivity_Fail_Success is contradictory (it’s a failure-path test expecting 400). Consider renaming it to something like RemoveFavouriteActivity_Failure_ReturnsBadRequest for clarity.
| public void RemoveFavouriteActivity_Fail_Success() | |
| public void RemoveFavouriteActivity_Failure_ReturnsBadRequest() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AddFavouriteActivityloads the full list of activities (withUsersFavincluded) for the edition viaGetAllIncludeFavs(...)and then filters in-memory withFirstOrDefault. This can become expensive as activities/users grow and is unnecessary when you only need a single activity. Prefer a repository method that fetches a single activity by id withUsersFavincluded (or changeGetAllIncludeFavsto return anIQueryableso the filter runs in SQL).