Skip to content

Commit

Permalink
Merge develop into feature/ja-114
Browse files Browse the repository at this point in the history
  • Loading branch information
Zjyslav committed Jun 26, 2024
2 parents b1690df + dce3b36 commit 6e68f13
Show file tree
Hide file tree
Showing 42 changed files with 2,550 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Moq;
using TutorLizard.BusinessLogic.Models;
using TutorLizard.Shared.Models.DTOs.Requests;
using TutorLizard.BusinessLogic.Services;

namespace TutorLizard.BusinessLogic.Tests.Services.Student
{
public class StudentServiceScheduleItemRequestTests : StudentServiceTestBase
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task CreateScheduleItemRequest_ShouldSetIsRemoteCorrectly(bool isRemote)
{
// Arrange
var ad = new Ad
{
Description = "Test Description",
Location = "Test Location",
Subject = "Test Subject",
Title = "Test Title",
TutorId = 2
};
var scheduleItem = new ScheduleItem { Id = 1, Ad = ad };

SetupMockGetScheduleItemById(scheduleItem);
SetupMockGetAllScheduleItems(new List<ScheduleItem> { scheduleItem });

var request = new CreateScheduleItemRequestRequest
{
StudentId = 3,
ScheduleItemId = 1,
IsRemote = isRemote
};

MockScheduleItemRequestRepository
.Setup(x => x.Create(It.Is<ScheduleItemRequest>(req => req.IsRemote == isRemote)))
.Returns((ScheduleItemRequest req) => Task.FromResult(req))
.Verifiable(Times.Once);

// Act
await StudentService.CreateScheduleItemRequest(request);

// Assert
MockScheduleItemRequestRepository.VerifyAll();
}

[Fact]
public async Task CreateScheduleItemRequest_WhenRequestSent_ShouldReturnSuccess()
{
// Arrange
var scheduleItem = new ScheduleItem { Id = 1 };
var studentId = 1;
var isRemote = true;

SetupMockGetScheduleItemById(scheduleItem);

var request = new CreateScheduleItemRequestRequest
{
StudentId = studentId,
ScheduleItemId = scheduleItem.Id,
IsRemote = isRemote
};

// Act
var response = await StudentService.CreateScheduleItemRequest(request);

// Assert
Assert.True(response.Success);
}





}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using AutoFixture;
using Moq;
using TutorLizard.BusinessLogic.Interfaces.Data.Repositories;
using TutorLizard.BusinessLogic.Models;
using TutorLizard.BusinessLogic.Services;

namespace TutorLizard.BusinessLogic.Tests.Services.Student
{
public class StudentServiceTestBase : TestsWithInMemoryDbBase
{
protected StudentService StudentService;
protected Fixture Fixture = new();
protected Mock<IDbRepository<Ad>> MockAdRepository = new();
protected Mock<IDbRepository<AdRequest>> MockAdRequestRepository = new();
protected Mock<IDbRepository<ScheduleItem>> MockScheduleItemRepository = new();
protected Mock<IDbRepository<ScheduleItemRequest>> MockScheduleItemRequestRepository = new();


protected StudentServiceTestBase() : base()
{
StudentService = new StudentService(MockAdRepository.Object,
MockAdRequestRepository.Object,
MockScheduleItemRepository.Object,
MockScheduleItemRequestRepository.Object);
}

protected void SetupMockGetScheduleItemById(ScheduleItem? scheduleItem)
{
MockScheduleItemRepository
.Setup(x => x.GetById(It.IsAny<int>()))
.Returns(Task.FromResult(scheduleItem));
}

protected void SetupMockGetAllScheduleItems(List<ScheduleItem> scheduleItems)
{
var scheduleItemsInDb = AddEntitiesToInMemoryDb(scheduleItems);
MockScheduleItemRepository
.Setup(x => x.GetAll())
.Returns(scheduleItemsInDb);
}

protected IQueryable<TEntity> AddEntitiesToInMemoryDb<TEntity>(List<TEntity> entities)
where TEntity : class
{
DbContext
.Set<TEntity>()
.AddRange(entities);
DbContext.SaveChanges();

return DbContext
.Set<TEntity>()
.AsQueryable();
}
}
}
5 changes: 5 additions & 0 deletions TutorLizard.BusinessLogic/Data/JaszczurContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
.Property(user => user.Id)
.ValueGeneratedOnAdd();

modelBuilder.Entity<User>()
.Property(user => user.IsActive)
.HasDefaultValue(false)
.IsRequired();

modelBuilder.Entity<User>()
.Property(user => user.UserType)
.HasConversion<byte>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public UserJsonRepository(IOptions<DataJsonFilePaths> options) : base(options.Va

}

public User CreateUser(string name, UserType type, string email, string passwordHash)
public User CreateUser(string name, UserType type, string email, string passwordHash, string googleid)
{
User newUser = new(GetNewId(), name, type, email, passwordHash);
User newUser = new(GetNewId(), name, type, email, passwordHash, googleid);
Data.Add(newUser);
SaveToJson();

Expand Down
3 changes: 2 additions & 1 deletion TutorLizard.BusinessLogic/Extensions/DtoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public static UserDto ToDto(this User user)
user.Name,
user.UserType,
user.Email,
user.DateCreated);
user.DateCreated,
user.GoogleId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace TutorLizard.BusinessLogic.Interfaces.Data.Repositories;
public interface IUserRepository
{
User CreateUser(string name, UserType type, string email, string passwordHash);
User CreateUser(string name, UserType type, string email, string passwordHash, string googleId);
void DeleteUserById(int id);
List<User> GetAllUsers();
User? GetUserById(int id);
Expand Down
8 changes: 6 additions & 2 deletions TutorLizard.BusinessLogic/Interfaces/Services/IUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ namespace TutorLizard.BusinessLogic.Interfaces.Services;

public interface IUserService
{
public Task<UserDto?> LogIn(string username, string password);
public Task<bool> RegisterUser(string userName, UserType type, string email, string password);
public Task<LogInResult> LogIn(string username, string password);
public Task<bool> RegisterUser(string userName, UserType type, string email, string password, string activationCode);
Task<ActivationResultDto> ActivateUserAsync(string activationCode);
public Task<bool> RegisterUserWithGoogle(string username, string email, string googleId);
public Task<bool> IsTheGoogleUserRegistered(string googleId);
public Task<UserDto?> LogInWithGoogle(string username, string googleId);
}
12 changes: 8 additions & 4 deletions TutorLizard.BusinessLogic/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

namespace TutorLizard.BusinessLogic.Models;

public class User
public class User
{
public int Id { get; set; }
public bool IsActive { get; set; }

[Required]
[MinLength(5)]
Expand All @@ -19,21 +20,23 @@ public class User
[MaxLength(100)]
public string Email { get; set; }

[Required]
[DataType(DataType.Password)]
[MinLength(8)]
[MaxLength(100)]
public string PasswordHash { get; set; }
public string? PasswordHash { get; set; }

public DateTime DateCreated { get; set; } = DateTime.Now;

public User(int id, string name, UserType userType, string email, string passwordHash)
public string? GoogleId { get; set; }

public User(int id, string name, UserType userType, string email, string passwordHash, string? googleId)
{
Id = id;
Name = name;
UserType = userType;
Email = email;
PasswordHash = passwordHash;
GoogleId = googleId;
}
public User()
{
Expand All @@ -43,4 +46,5 @@ public User()
public ICollection<Ad> Ads { get; set; } = new List<Ad>();
public ICollection<AdRequest> AdRequests { get; set; } = new List<AdRequest>();
public ICollection<ScheduleItemRequest> ScheduleItemRequests { get; set; } = new List<ScheduleItemRequest>();
public string? ActivationCode { get; set; }
}
80 changes: 46 additions & 34 deletions TutorLizard.BusinessLogic/Services/StudentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class StudentService : IStudentService
_scheduleItemRequestRepository = scheduleItemRequestRepository;
}

#region Schedule
public async Task<CreateScheduleItemRequestResponse> CreateScheduleItemRequest(CreateScheduleItemRequestRequest request)
{
int studentId = request.StudentId;
Expand All @@ -47,18 +48,57 @@ public async Task<CreateScheduleItemRequestResponse> CreateScheduleItemRequest(C
ScheduleItemId = scheduleItemId,
DateCreated = DateTime.UtcNow,
StudentId = studentId,
IsAccepted = false
IsAccepted = false,
IsRemote = request.IsRemote
};

await _scheduleItemRequestRepository.Create(scheduleItemRequest);

return new CreateScheduleItemRequestResponse
{

return new CreateScheduleItemRequestResponse
{
Success = true,
CreatedScheduleItemRequestId = scheduleItemRequest.Id,
CreatedScheduleItemRequestId = scheduleItemRequest.Id
};
}

public async Task<GetAvailableScheduleForAdResponse> GetAvailableScheduleForAd(GetAvailableScheduleForAdRequest request)
{
List<ScheduleItemDto> items = await _scheduleItemRepository.GetAll()
.Where(si => si.Ad.AdRequests.Any(ar => ar.StudentId == request.StudentId && ar.IsAccepted))
.Select(si => new ScheduleItemDto()
{
AdId = si.AdId,
DateTime = si.DateTime,
Id = si.Id,
Status = si.ScheduleItemRequests.Any(sir => sir.StudentId == request.StudentId && sir.IsAccepted) ? ScheduleItemDto.ScheduleItemRequestStatus.Accepted
: si.ScheduleItemRequests.Any(sir => sir.StudentId == request.StudentId) ? ScheduleItemDto.ScheduleItemRequestStatus.Pending
: ScheduleItemDto.ScheduleItemRequestStatus.RequestNotSent
})
.ToListAsync();

bool isAccepted = await _adRequestRepository.GetAll()
.Where(ar => ar.AdId == request.AdId)
.AnyAsync(ar => ar.StudentId == request.StudentId && ar.IsAccepted);

bool isRemote = await _adRepository.GetAll()
.Where(ad => ad.Id == request.AdId)
.Select(ad => ad.IsRemote)
.FirstOrDefaultAsync();

GetAvailableScheduleForAdResponse response = new()
{
AdId = request.AdId,
IsAccepted = isAccepted,
IsRemote = isRemote,
Items = items
};

return response;
}

#endregion
#region Ads
public async Task<GetStudentsAcceptedAdsResponse> GetStudentsAcceptedAds(GetStudentsAcceptedAdsRequest request)
{
var studentId = request.StudentId;
Expand Down Expand Up @@ -141,7 +181,7 @@ public async Task<GetAdRequestStatusResponse> GetAdRequestStatus(GetAdRequestSta
.FirstOrDefaultAsync();

if (adRequestDetails is null)
return new GetAdRequestStatusResponse() { IsSuccessful = false };
return new GetAdRequestStatusResponse() { IsSuccessful = false };

GetAdRequestStatusResponse response = new GetAdRequestStatusResponse()
{
Expand Down Expand Up @@ -231,33 +271,5 @@ public async Task<CreateAdRequestResponse> CreateAdRequest(CreateAdRequestReques
Success = true
};
}

public async Task<GetAvailableScheduleForAdResponse> GetAvailableScheduleForAd(GetAvailableScheduleForAdRequest request)
{
List<ScheduleItemDto> items = await _scheduleItemRepository.GetAll()
.Where(si => si.Ad.AdRequests.Any(ar => ar.StudentId == request.StudentId && ar.IsAccepted) && si.AdId == request.AdId)
.Select(si => new ScheduleItemDto()
{
AdId = si.AdId,
DateTime = si.DateTime,
Id = si.Id,
Status = si.ScheduleItemRequests.Any(sir => sir.StudentId == request.StudentId && sir.IsAccepted) ? ScheduleItemDto.ScheduleItemRequestStatus.Accepted
: si.ScheduleItemRequests.Any(sir => sir.StudentId == request.StudentId) ? ScheduleItemDto.ScheduleItemRequestStatus.Pending
: ScheduleItemDto.ScheduleItemRequestStatus.RequestNotSent
})
.ToListAsync();

bool isAccepted = await _adRequestRepository.GetAll()
.Where(ar => ar.AdId == request.AdId)
.AnyAsync(ar => ar.StudentId == request.StudentId && ar.IsAccepted);

GetAvailableScheduleForAdResponse response = new()
{
AdId = request.AdId,
IsAccepted = isAccepted,
Items = items
};

return response;
}
}
#endregion
Loading

0 comments on commit 6e68f13

Please sign in to comment.