Преглед изворни кода

Added tests for users controller & service

pull/61/head
meris.ahmatovic пре 3 година
родитељ
комит
2063bf7ead

+ 1
- 1
Diligent.WebAPI.Business/Services/Interfaces/IUserService.cs Прегледај датотеку

@@ -8,7 +8,7 @@ namespace Diligent.WebAPI.Business.Services.Interfaces
Task<User?> GetById(int id);
Task<User?> GetByEmail(string email);
Task CreateUser(CreateUserRequestDto model);
Task ToggleEnable(User user);
Task<bool?> ToggleEnable(User user);
Task RemoveUser(User user);
Task<bool> VerifyToken(User user, string token);
Task<ServiceResponseDTO<object>> SendRegistrationLink(InviteDTO invite);

+ 10
- 8
Diligent.WebAPI.Business/Services/UserService.cs Прегледај датотеку

@@ -12,25 +12,25 @@ namespace Diligent.WebAPI.Business.Services

public class UserService : IUserService
{
private readonly AuthorizationSettings _authSettings;
private readonly FrontEndSettings _frontEndSettings;
private readonly UserManager<User> _userManager;
private readonly IMapper _mapper;
private readonly DatabaseContext _databaseContext;
private readonly IEmailer _emailer;
private readonly ILogger<UserService> _logger;
private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}";
private string[] SupportedClientsIds = { "" };
//private readonly AuthorizationSettings _authSettings;
//private readonly ILogger<UserService> _logger;
//private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}";
//private string[] SupportedClientsIds = { "" };

public UserService(IOptions<AuthorizationSettings> authSettings, IOptions<FrontEndSettings> frontEndSettings, UserManager<User> userManager, IMapper mapper, DatabaseContext databaseContext, IEmailer emailer, ILogger<UserService> logger)
public UserService(IOptions<FrontEndSettings> frontEndSettings, UserManager<User> userManager, IMapper mapper, DatabaseContext databaseContext, IEmailer emailer)
{
_authSettings = authSettings.Value;
_frontEndSettings = frontEndSettings.Value;
_userManager = userManager;
_mapper = mapper;
_databaseContext = databaseContext;
_emailer = emailer;
_logger = logger;
//_authSettings = authSettings.Value;
//_logger = logger;
}

public async Task<IEnumerable<User?>> GetAll() =>
@@ -54,11 +54,13 @@ namespace Diligent.WebAPI.Business.Services
await _databaseContext.SaveChangesAsync();
}

public async Task ToggleEnable(User user)
public async Task<bool?> ToggleEnable(User user)
{
user.IsEnabled = !user.IsEnabled;

await _databaseContext.SaveChangesAsync();

return user.IsEnabled;
}

public async Task<ServiceResponseDTO<object>> SendRegistrationLink(InviteDTO invite)

+ 6
- 0
Diligent.WebAPI.Data/DatabaseContext.cs Прегледај датотеку

@@ -36,5 +36,11 @@ public class DatabaseContext : IdentityDbContext<User, AppRole, int>
modelBuilder.ApplyConfiguration(new CommentConfiguration());
modelBuilder.ApplyConfiguration(new UserConfiguration());
modelBuilder.ApplyConfiguration(new AdConfiguration());

modelBuilder
.Entity<User>()
.HasMany(user => user.Processes)
.WithOne(process => process.Scheduler)
.OnDelete(DeleteBehavior.SetNull);
}
}

+ 1
- 0
Diligent.WebAPI.Data/Entities/User.cs Прегледај датотеку

@@ -9,4 +9,5 @@ public class User : IdentityUser<int>
public string? PasswordResetToken { get; set; }
public List<Comment> Comments { get; set; }
public bool? IsEnabled { get; set; }
public List<SelectionProcess> Processes { get; set; } = new();
}

+ 1019
- 0
Diligent.WebAPI.Data/Migrations/20221124121921_typeOfEmployment.Designer.cs
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 26
- 0
Diligent.WebAPI.Data/Migrations/20221124121921_typeOfEmployment.cs Прегледај датотеку

@@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Diligent.WebAPI.Data.Migrations
{
public partial class typeOfEmployment : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "TypeOfEmployment",
table: "Applicants",
type: "nvarchar(max)",
nullable: false,
defaultValue: "");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TypeOfEmployment",
table: "Applicants");
}
}
}

+ 1022
- 0
Diligent.WebAPI.Data/Migrations/20221124125727_RestrictDelete.Designer.cs
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 38
- 0
Diligent.WebAPI.Data/Migrations/20221124125727_RestrictDelete.cs Прегледај датотеку

@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Diligent.WebAPI.Data.Migrations
{
public partial class RestrictDelete : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses");

migrationBuilder.AddForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses",
column: "SchedulerId",
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses");

migrationBuilder.AddForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses",
column: "SchedulerId",
principalTable: "AspNetUsers",
principalColumn: "Id");
}
}
}

+ 1022
- 0
Diligent.WebAPI.Data/Migrations/20221124132257_DeleteBehaviorSetNull.Designer.cs
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 39
- 0
Diligent.WebAPI.Data/Migrations/20221124132257_DeleteBehaviorSetNull.cs Прегледај датотеку

@@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Diligent.WebAPI.Data.Migrations
{
public partial class DeleteBehaviorSetNull : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses");

migrationBuilder.AddForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses",
column: "SchedulerId",
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses");

migrationBuilder.AddForeignKey(
name: "FK_SelectionProcesses_AspNetUsers_SchedulerId",
table: "SelectionProcesses",
column: "SchedulerId",
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
}
}

+ 24
- 17
Diligent.WebAPI.Data/Migrations/DatabaseContextModelSnapshot.cs Прегледај датотеку

@@ -34,7 +34,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("ApplicantsApplicantId");

b.ToTable("AdApplicant", (string)null);
b.ToTable("AdApplicant");
});

modelBuilder.Entity("AdTechnology", b =>
@@ -49,7 +49,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("TechnologiesTechnologyId");

b.ToTable("AdTechnology", (string)null);
b.ToTable("AdTechnology");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Ad", b =>
@@ -95,7 +95,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("Ads", (string)null);
b.ToTable("Ads");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Applicant", b =>
@@ -153,9 +153,13 @@ namespace Diligent.WebAPI.Data.Migrations
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");

b.Property<string>("TypeOfEmployment")
.IsRequired()
.HasColumnType("nvarchar(max)");

b.HasKey("ApplicantId");

b.ToTable("Applicants", (string)null);
b.ToTable("Applicants");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.AppRole", b =>
@@ -216,7 +220,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("UserId");

b.ToTable("Comments", (string)null);
b.ToTable("Comments");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsuranceCompany", b =>
@@ -270,7 +274,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("InsuranceCompanies", (string)null);
b.ToTable("InsuranceCompanies");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b =>
@@ -310,7 +314,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("InsurerId");

b.ToTable("InsurancePolicies", (string)null);
b.ToTable("InsurancePolicies");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b =>
@@ -372,7 +376,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("InsuranceCompanyId");

b.ToTable("Insurers", (string)null);
b.ToTable("Insurers");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.RefreshToken", b =>
@@ -410,7 +414,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("UserId");

b.ToTable("RefreshTokens", (string)null);
b.ToTable("RefreshTokens");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.SelectionLevel", b =>
@@ -427,7 +431,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("SelectionLevels", (string)null);
b.ToTable("SelectionLevels");

b.HasData(
new
@@ -491,7 +495,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("SelectionLevelId");

b.ToTable("SelectionProcesses", (string)null);
b.ToTable("SelectionProcesses");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Technology", b =>
@@ -513,7 +517,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("TechnologyId");

b.ToTable("Technologies", (string)null);
b.ToTable("Technologies");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.TechnologyApplicant", b =>
@@ -536,7 +540,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("TechnologyId");

b.ToTable("ApplicantTechnologies", (string)null);
b.ToTable("ApplicantTechnologies");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.User", b =>
@@ -656,7 +660,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("WebhookDefinitions", (string)null);
b.ToTable("WebhookDefinitions");
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b =>
@@ -690,7 +694,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("WebhookDefinitionId");

b.ToTable("WebhookSubscriptions", (string)null);
b.ToTable("WebhookSubscriptions");
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
@@ -887,8 +891,9 @@ namespace Diligent.WebAPI.Data.Migrations
.IsRequired();

b.HasOne("Diligent.WebAPI.Data.Entities.User", "Scheduler")
.WithMany()
.HasForeignKey("SchedulerId");
.WithMany("Processes")
.HasForeignKey("SchedulerId")
.OnDelete(DeleteBehavior.SetNull);

b.HasOne("Diligent.WebAPI.Data.Entities.SelectionLevel", "SelectionLevel")
.WithMany("SelectionProcesses")
@@ -1006,6 +1011,8 @@ namespace Diligent.WebAPI.Data.Migrations
modelBuilder.Entity("Diligent.WebAPI.Data.Entities.User", b =>
{
b.Navigation("Comments");

b.Navigation("Processes");
});
#pragma warning restore 612, 618
}

+ 0
- 1
Diligent.WebAPI.Host/Controllers/V1/UsersController.cs Прегледај датотеку

@@ -103,5 +103,4 @@ namespace Diligent.WebAPI.Host.Controllers.V1
return Ok();
}
}

}

+ 134
- 0
Diligent.WebAPI.Tests/Controllers/UsersControllerTest.cs Прегледај датотеку

@@ -0,0 +1,134 @@
using AutoMapper;
using Diligent.WebAPI.Business.MappingProfiles;
using Diligent.WebAPI.Contracts.DTOs;
using Diligent.WebAPI.Contracts.DTOs.User;
using Diligent.WebAPI.Data.Entities;

namespace Diligent.WebAPI.Tests.Controllers
{
public class UsersControllerTest
{
private IUserService _userService = Substitute.For<IUserService>();
private readonly List<User> _users;
private readonly User _user;
private readonly IMapper _mapper;

public UsersControllerTest()
{
_user = new User
{
Id = 1,
PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
FirstName = "Dzenis",
LastName = "Dzenis",
UserName = "dzenis",
NormalizedUserName = "DZENIS",
Email = "dzenis@dilig.net",
NormalizedEmail = "DZENIS@DILIG.NET",
EmailConfirmed = false,
IsEnabled = true,
AccessFailedCount = 0,
SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
};

_users = new List<User>
{
_user,
};

// configure mapper
var configuration = new MapperConfiguration(cfg => cfg.AddProfiles(
new List<Profile>
{
new UserMappingProfile(),
}));
_mapper = new Mapper(configuration);
}

[Fact]
public async Task GetUsers_ShouldReturn_200OK()
{
_userService.GetAll().Returns(_users);
UsersController usersController = new(_userService, _mapper);

var result = await usersController.GetAll();

(result as OkObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task GetUserById_ShouldReturn_200OK()
{
_userService.GetById(Arg.Any<int>()).Returns(_user);
UsersController usersController = new(_userService, _mapper);

var result = await usersController.GetUser(1);

(result as OkObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task GetUserById_ShouldReturn404_WhenUserDoesNotExist()
{
_userService.GetById(Arg.Any<int>()).Returns<User>(x => null);
UsersController usersController = new(_userService, _mapper);

var result = await usersController.GetUser(1);

(result as ObjectResult).StatusCode.Should().Be(400);
}

[Fact]
public async Task InviteUser_ShouldReturn200_WhenUserDoesNotExist()
{
_userService.SendRegistrationLink(Arg.Any<InviteDTO>()).Returns(x => new ServiceResponseDTO<object>
{
Data = new { Message = "Link has been sent!" }
});

UsersController usersController = new(_userService, _mapper);

var result = await usersController.InviteUser(new InviteDTO());

(result as OkObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task InviteUser_ShouldReturn400_WhenUserExists()
{
_userService.SendRegistrationLink(Arg.Any<InviteDTO>()).Returns(x => new ServiceResponseDTO<object>
{
IsError = true,
});

UsersController usersController = new(_userService, _mapper);

var result = await usersController.InviteUser(new InviteDTO());

(result as BadRequestObjectResult).StatusCode.Should().Be(400);
}

[Fact]
public async Task DeleteUser_ShouldReturn200_WhenUserExists()
{
_userService.GetById(Arg.Any<int>()).Returns(_user);
UsersController usersController = new(_userService, _mapper);

var result = await usersController.DeleteUser(1);

(result as ObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task DeleteUser_ShouldReturn400_WhenUserDoesNotExist()
{
_userService.GetById(Arg.Any<int>()).Returns<User>(x => null);
UsersController usersController = new(_userService, _mapper);

var result = await usersController.DeleteUser(1);

(result as ObjectResult).StatusCode.Should().Be(400);
}
}
}

+ 162
- 0
Diligent.WebAPI.Tests/Services/UserServiceTests.cs Прегледај датотеку

@@ -0,0 +1,162 @@
using AutoMapper;
using Diligent.WebAPI.Business.MappingProfiles;
using Diligent.WebAPI.Business.Services;
using Diligent.WebAPI.Business.Settings;
using Diligent.WebAPI.Contracts.DTOs;
using Diligent.WebAPI.Contracts.DTOs.User;
using Diligent.WebAPI.Data;
using Diligent.WebAPI.Data.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NSubstitute;

namespace Diligent.WebAPI.Tests.Services
{
public class UserServiceTests
{

private readonly List<User> _users;
private readonly User _user;
private readonly IMapper _mapper;
private readonly IUserStore<User> _mockStore;
private readonly UserManager<User> _mockUserManager;

public UserServiceTests()
{
_mockStore = Substitute.For<IUserStore<User>>();
_mockUserManager = Substitute.For<UserManager<User>>(_mockStore, null, null, null, null, null, null, null, null);

_user = new User
{
Id = 1,
PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
FirstName = "Dzenis",
LastName = "Dzenis",
UserName = "dzenis",
NormalizedUserName = "DZENIS",
Email = "dzenis@dilig.net",
NormalizedEmail = "DZENIS@DILIG.NET",
EmailConfirmed = false,
IsEnabled = true,
AccessFailedCount = 0,
SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
};

_users = new List<User>
{
_user
};

// configure mapper
var configuration = new MapperConfiguration(cfg => cfg.AddProfiles(
new List<Profile>
{
new UserMappingProfile()
}));

_mapper = new Mapper(configuration);
}

[Fact]
public async Task GetById_ShouldReturnUser()
{
_mockUserManager.FindByIdAsync(Arg.Any<string>()).Returns(_user);
var databaseContext = await Helpers<User>.GetDatabaseContext(_users);

var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();
var mailer = Substitute.For<IEmailer>();

var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);
var result = await service.GetById(1);
result.Should().Be(_user);
}

[Fact]
public async Task GetByEmail_ShouldReturnUser()
{
_mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_user);
var databaseContext = await Helpers<User>.GetDatabaseContext(_users);

var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();
var mailer = Substitute.For<IEmailer>();

var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);
var result = await service.GetByEmail("mail");
result.Should().Be(_user);
}

[Fact]
public async Task RemoveUser_ShouldDeleteUser()
{
var databaseContext = await Helpers<User>.GetDatabaseContext(_users);

var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();
var mailer = Substitute.For<IEmailer>();

var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);
await service.RemoveUser(_user);

var result = await service.GetById(2);
result.Should().Be(null);
}

[Fact]
public async Task ToggleEnable_ShouldDisableUser()
{
var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();
var mailer = Substitute.For<IEmailer>();
var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);

var result = await service.ToggleEnable(_user);
Assert.Equal(false, result);
}

[Fact]
public async Task Invite_ShouldFailIfUserExists()
{
_mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_user);
var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();
var mailer = Substitute.For<IEmailer>();
var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);

var result = await service.SendRegistrationLink(new Contracts.DTOs.User.InviteDTO
{
Email = "string",
FirstName = "string",
LastName = "string",
});

Assert.Equal(true, result.IsError);
}

//[Fact] To be debuged later
//public async Task Invite_ShouldPassIfUserDoesNotExist()
//{
// _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns<User>(x => null);
// var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
// var frontSettings = Substitute.For<IOptions<FrontEndSettings>>();

// var mailer = Substitute.For<IEmailer>();
// mailer.When(x => x.SendEmailAndWriteToDbAsync(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<bool>())).Do(x => { });

// var service = new UserService(frontSettings, _mockUserManager, _mapper, databaseContext, mailer);

// var result = await service.SendRegistrationLink(new InviteDTO
// {
// Email = "string@dilig.net",
// FirstName = "string",
// LastName = "string",
// });

// result.Data.Should().BeEquivalentTo(new
// {
// Message = "Link has been sent!"
// });
//}
}
}

Loading…
Откажи
Сачувај