Skip to content

Commit f43005a

Browse files
committed
✨ Add functionality for managing user favorite activities
1 parent 76b4c2e commit f43005a

10 files changed

Lines changed: 347 additions & 13 deletions

File tree

TaleEngine/TaleEngine.Application.Contracts/IActivityService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public interface IActivityService
1111
List<ActivityEntity> GetPendingActivities(int editionId);
1212
List<ActivityEntity> GetLastThreeActivities(int editionId);
1313
IEnumerable<ActivityEntity> GetActiveActivitiesFiltered(int typeId, int editionId, List<int> timeframes, string title, int skipByPagination, int activitiesPerPage, int userFav = default);
14+
List<ActivityEntity> GetFavouriteActivitiesByUser(int userId, int editionId);
15+
bool AddFavouriteActivity(int activityId, int userId);
16+
bool RemoveFavouriteActivity(int activityId, int userId);
1417

1518
int ChangeActivityStatus(int activityId, int statusId);
1619
int DeleteActivity(int activityId);

TaleEngine/TaleEngine.Application/ActivityService.cs

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,98 @@ public IEnumerable<ActivityEntity> GetActiveActivitiesFiltered(int typeId, int e
6767
return query;
6868
}
6969

70+
public List<ActivityEntity> GetFavouriteActivitiesByUser(int userId, int editionId)
71+
{
72+
if (userId == default || editionId == default)
73+
{
74+
return new List<ActivityEntity>();
75+
}
76+
77+
return GetFavActivitiesFiltered(0, editionId, null, null, userId).ToList();
78+
}
79+
80+
public bool AddFavouriteActivity(int activityId, int userId)
81+
{
82+
try
83+
{
84+
var user = _unitOfWork.UserRepository.GetById(userId);
85+
var activity = _unitOfWork.ActivityRepository.GetById(activityId);
86+
87+
if (user == null || activity == null)
88+
{
89+
return false;
90+
}
91+
92+
activity = _unitOfWork.ActivityRepository.GetAllIncludeFavs(activity.EditionId)
93+
.FirstOrDefault(a => a.Id == activityId);
94+
95+
if (activity == null)
96+
{
97+
return false;
98+
}
99+
100+
if (activity.UsersFav == null)
101+
{
102+
activity.UsersFav = new List<UserEntity>();
103+
}
104+
105+
if (activity.UsersFav.Any(u => u.Id == userId))
106+
{
107+
return false;
108+
}
109+
110+
activity.UsersFav.Add(user);
111+
112+
_unitOfWork.ActivityRepository.Update(activity);
113+
_unitOfWork.ActivityRepository.Save();
114+
115+
return true;
116+
}
117+
catch (Exception)
118+
{
119+
return false;
120+
}
121+
}
122+
123+
public bool RemoveFavouriteActivity(int activityId, int userId)
124+
{
125+
try
126+
{
127+
var activity = _unitOfWork.ActivityRepository.GetById(activityId);
128+
129+
if (activity == null)
130+
{
131+
return false;
132+
}
133+
134+
activity = _unitOfWork.ActivityRepository.GetAllIncludeFavs(activity.EditionId)
135+
.FirstOrDefault(a => a.Id == activityId);
136+
137+
if (activity?.UsersFav == null)
138+
{
139+
return false;
140+
}
141+
142+
var userToRemove = activity.UsersFav.FirstOrDefault(u => u.Id == userId);
143+
144+
if (userToRemove == null)
145+
{
146+
return false;
147+
}
148+
149+
activity.UsersFav.Remove(userToRemove);
150+
151+
_unitOfWork.ActivityRepository.Update(activity);
152+
_unitOfWork.ActivityRepository.Save();
153+
154+
return true;
155+
}
156+
catch (Exception)
157+
{
158+
return false;
159+
}
160+
}
161+
70162
public int DeleteActivity(int activityId)
71163
{
72164
try
@@ -195,13 +287,14 @@ private IEnumerable<ActivityEntity> GetActiveActivitiesWithFilter(int type, List
195287

196288
private IEnumerable<ActivityEntity> GetFavActivitiesFiltered(int type, int editionId, List<int> timeframes, string title, int userFav)
197289
{
198-
var user = _unitOfWork.UserRepository.GetById(userFav);
199-
200290
var activeStatus = _activityStatusService
201291
.GetById((int)ActivityStatusEnum.ACT);
202292

203293
var query = _unitOfWork.ActivityRepository.GetAllIncludeFavs(editionId)
204-
.Where(a => a.UsersFav.Contains(user) && a.StatusId == activeStatus.Id);
294+
.Where(a => a.EditionId == editionId
295+
&& a.StatusId == activeStatus.Id
296+
&& a.UsersFav != null
297+
&& a.UsersFav.Any(u => u.Id == userFav));
205298

206299
return ApplyActivityFilters(query, type, timeframes, title);
207300
}

TaleEngine/TaleEngine.Bussiness/Commands/ActivityCommands.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,15 @@ public bool LeaveActivityCommand(ActivityEnrollmentRequest request)
140140
{
141141
return _activityService.RemoveUserFromActivity(request.ActivityId, request.UserId);
142142
}
143+
144+
public bool AddFavouriteActivityCommand(ActivityEnrollmentRequest request)
145+
{
146+
return _activityService.AddFavouriteActivity(request.ActivityId, request.UserId);
147+
}
148+
149+
public bool RemoveFavouriteActivityCommand(ActivityEnrollmentRequest request)
150+
{
151+
return _activityService.RemoveFavouriteActivity(request.ActivityId, request.UserId);
152+
}
143153
}
144154
}

TaleEngine/TaleEngine.Bussiness/Contracts/IActivityCommands.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ public interface IActivityCommands
1212
void ChangeActivityStatusCommand(int activityId, int statusId);
1313
ActivityEnrollmentResult EnrollInActivityCommand(ActivityEnrollmentRequest request);
1414
bool LeaveActivityCommand(ActivityEnrollmentRequest request);
15+
bool AddFavouriteActivityCommand(ActivityEnrollmentRequest request);
16+
bool RemoveFavouriteActivityCommand(ActivityEnrollmentRequest request);
1517
}
1618
}

TaleEngine/TaleEngine.Bussiness/Contracts/IActivityQueries.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public interface IActivityQueries
1010
List<ActivityDto> ActiveActivitiesQuery(int editionId);
1111
List<ActivityDto> PendingActivitiesQuery(int editionId);
1212
ActivityFilteredResult ActiveActivitiesFilteredQuery(ActivityFilterRequest activityFilterRequest, int userId = default);
13+
List<ActivityDto> FavouriteActivitiesByUserQuery(int userId, int editionId);
1314
List<ActivityDto> LastThreeActivitiesQuery(int editionId);
1415
WaitingListResult GetWaitingListQuery(int activityId);
1516
int? GetUserPositionInWaitingListQuery(int activityId, int userId);

TaleEngine/TaleEngine.Bussiness/Queries/ActivityQueries.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ public List<ActivityDto> LastThreeActivitiesQuery(int edition)
8484
return result;
8585
}
8686

87+
public List<ActivityDto> FavouriteActivitiesByUserQuery(int userId, int editionId)
88+
{
89+
var activities = _activityService.GetFavouriteActivitiesByUser(userId, editionId);
90+
91+
var models = ActivityMapper.MapEntityToDto(activities);
92+
93+
return models;
94+
}
95+
8796
public WaitingListResult GetWaitingListQuery(int activityId)
8897
{
8998
var activity = _activityService.GetById(activityId);

TaleEngine/TaleEngine.Data.Contracts/Repositories/IActivityRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace TaleEngine.Data.Contracts.Repositories
55
{
66
public interface IActivityRepository : IGenericRepository<ActivityEntity>
77
{
8-
List<ActivityEntity> GetAllIncludeFavs(int eventId);
8+
List<ActivityEntity> GetAllIncludeFavs(int editionId);
99
List<ActivityEntity> GetEventActivities(int eventId);
1010
List<ActivityEntity> GetActivitiesByStatus(int edition, int status);
1111
List<ActivityEntity> GetActiveActivitiesFiltered(int status, int type, int edition, string title, int skip, int activitiesPerPage);

TaleEngine/TaleEngine.Data/Repositories/ActivityRepository.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,18 @@ public int GetTotalActivities(int status, int type, int edition, string title)
9393
throw new System.NotImplementedException();
9494
}
9595

96-
public List<ActivityEntity> GetAllIncludeFavs(int eventId)
96+
public List<ActivityEntity> GetAllIncludeFavs(int editionId)
9797
{
98-
return _context.Activities
98+
var query = _context.Activities
9999
.Include(a => a.UsersFav)
100-
.Where(a => !a.IsDeleted)
101-
.ToList();
100+
.Where(a => !a.IsDeleted);
101+
102+
if (editionId != default)
103+
{
104+
query = query.Where(a => a.EditionId == editionId);
105+
}
106+
107+
return query.ToList();
102108
}
103109

104110
public List<ActivityEntity> GetAllIncludeEnrollments(int activityId)

TaleEngine/TaleEngine.Testing/Controllers/V1/ActivityControllerTests.cs

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,179 @@ public void ChangeActivityStatus_Success()
365365
commands.Verify(x => x.ChangeActivityStatusCommand(dto.StatusId, dto.ActivityId), Times.Once);
366366
}
367367

368+
[Fact]
369+
public void GetFavouriteActivitiesByUser_Success()
370+
{
371+
// Arrange
372+
int userId = 1;
373+
int editionId = 2;
374+
Mock<IActivityCommands> commands = new();
375+
Mock<IActivityQueries> queries = new();
376+
List<ActivityDto> dto = new()
377+
{
378+
new ActivityDto()
379+
};
380+
381+
queries.Setup(x => x.FavouriteActivitiesByUserQuery(userId, editionId))
382+
.Returns(dto);
383+
384+
ActivityController target = new(commands.Object, queries.Object);
385+
386+
// Act
387+
IActionResult result = target.GetFavouriteActivitiesByUser(userId, editionId);
388+
389+
// Assert
390+
var resultAsObjResult = result as ObjectResult;
391+
392+
result.Should().NotBeNull();
393+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status200OK);
394+
395+
queries.Verify(x => x.FavouriteActivitiesByUserQuery(userId, editionId), Times.Once);
396+
}
397+
398+
[Fact]
399+
public void GetFavouriteActivitiesByUser_EmptyResult_Success()
400+
{
401+
// Arrange
402+
int userId = 1;
403+
int editionId = 2;
404+
Mock<IActivityCommands> commands = new();
405+
Mock<IActivityQueries> queries = new();
406+
List<ActivityDto> dto = new();
407+
408+
queries.Setup(x => x.FavouriteActivitiesByUserQuery(userId, editionId))
409+
.Returns(dto);
410+
411+
ActivityController target = new(commands.Object, queries.Object);
412+
413+
// Act
414+
IActionResult result = target.GetFavouriteActivitiesByUser(userId, editionId);
415+
416+
// Assert
417+
var resultAsObjResult = result as StatusCodeResult;
418+
419+
result.Should().NotBeNull();
420+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status204NoContent);
421+
422+
queries.Verify(x => x.FavouriteActivitiesByUserQuery(userId, editionId), Times.Once);
423+
}
424+
425+
[Fact]
426+
public void AddFavouriteActivity_Success()
427+
{
428+
// Arrange
429+
Mock<IActivityCommands> commands = new();
430+
Mock<IActivityQueries> queries = new();
431+
ActivityEnrollmentRequest request = new()
432+
{
433+
ActivityId = 1,
434+
UserId = 1
435+
};
436+
437+
commands.Setup(x => x.AddFavouriteActivityCommand(request))
438+
.Returns(true);
439+
440+
ActivityController target = new(commands.Object, queries.Object);
441+
442+
// Act
443+
IActionResult result = target.AddFavouriteActivity(request);
444+
445+
// Assert
446+
var resultAsObjResult = result as ObjectResult;
447+
448+
result.Should().NotBeNull();
449+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status200OK);
450+
451+
commands.Verify(x => x.AddFavouriteActivityCommand(request), Times.Once);
452+
}
453+
454+
[Fact]
455+
public void AddFavouriteActivity_Fail_Success()
456+
{
457+
// Arrange
458+
Mock<IActivityCommands> commands = new();
459+
Mock<IActivityQueries> queries = new();
460+
ActivityEnrollmentRequest request = new()
461+
{
462+
ActivityId = 1,
463+
UserId = 1
464+
};
465+
466+
commands.Setup(x => x.AddFavouriteActivityCommand(request))
467+
.Returns(false);
468+
469+
ActivityController target = new(commands.Object, queries.Object);
470+
471+
// Act
472+
IActionResult result = target.AddFavouriteActivity(request);
473+
474+
// Assert
475+
var resultAsObjResult = result as ObjectResult;
476+
477+
result.Should().NotBeNull();
478+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status400BadRequest);
479+
480+
commands.Verify(x => x.AddFavouriteActivityCommand(request), Times.Once);
481+
}
482+
483+
[Fact]
484+
public void RemoveFavouriteActivity_Success()
485+
{
486+
// Arrange
487+
Mock<IActivityCommands> commands = new();
488+
Mock<IActivityQueries> queries = new();
489+
ActivityEnrollmentRequest request = new()
490+
{
491+
ActivityId = 1,
492+
UserId = 1
493+
};
494+
495+
commands.Setup(x => x.RemoveFavouriteActivityCommand(request))
496+
.Returns(true);
497+
498+
ActivityController target = new(commands.Object, queries.Object);
499+
500+
// Act
501+
IActionResult result = target.RemoveFavouriteActivity(request);
502+
503+
// Assert
504+
var resultAsObjResult = result as ObjectResult;
505+
506+
result.Should().NotBeNull();
507+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status200OK);
508+
509+
commands.Verify(x => x.RemoveFavouriteActivityCommand(request), Times.Once);
510+
}
511+
512+
[Fact]
513+
public void RemoveFavouriteActivity_Fail_Success()
514+
{
515+
// Arrange
516+
Mock<IActivityCommands> commands = new();
517+
Mock<IActivityQueries> queries = new();
518+
ActivityEnrollmentRequest request = new()
519+
{
520+
ActivityId = 1,
521+
UserId = 1
522+
};
523+
524+
commands.Setup(x => x.RemoveFavouriteActivityCommand(request))
525+
.Returns(false);
526+
527+
ActivityController target = new(commands.Object, queries.Object);
528+
529+
// Act
530+
IActionResult result = target.RemoveFavouriteActivity(request);
531+
532+
// Assert
533+
var resultAsObjResult = result as ObjectResult;
534+
535+
result.Should().NotBeNull();
536+
resultAsObjResult.StatusCode.Should().Be(StatusCodes.Status400BadRequest);
537+
538+
commands.Verify(x => x.RemoveFavouriteActivityCommand(request), Times.Once);
539+
}
540+
368541
[Fact]
369542
public void GetActivitiesFiltered_Success()
370543
{

0 commit comments

Comments
 (0)