Skip to content

Commit 5442371

Browse files
committed
Added more integration tests for Admin role
1 parent a123935 commit 5442371

File tree

7 files changed

+399
-0
lines changed

7 files changed

+399
-0
lines changed

tests/Api/ClassData/AdminOnlyEndpoints.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public class AdminOnlyEndpoints : IEnumerable<object[]>
99
{
1010
public IEnumerator<object[]> GetEnumerator()
1111
{
12+
yield return new object[] { HttpMethod.Post, "api/accounts/register" };
13+
yield return new object[] { HttpMethod.Put, "api/accounts/update-password" };
1214
yield return new object[] { HttpMethod.Put, "api/config" };
1315
yield return new object[] { HttpMethod.Get, "api/employee" };
1416
yield return new object[] { HttpMethod.Get, $"api/employee/{Guid.NewGuid()}" };
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using WebApi.Features.Accounts;
4+
5+
namespace Test.Api.ClassData
6+
{
7+
public class InvalidRegisterModels : IEnumerable<object[]>
8+
{
9+
public IEnumerator<object[]> GetEnumerator()
10+
{
11+
// error: UserName field is required
12+
yield return new object[]
13+
{
14+
new RegisterViewModel
15+
{
16+
UserName = "",
17+
Password = "valid_password",
18+
FullName = "Valid Name",
19+
CardNo = "valid_cardNo",
20+
}
21+
};
22+
23+
// error: Password field is required
24+
yield return new object[]
25+
{
26+
new RegisterViewModel
27+
{
28+
UserName = "valid_username",
29+
Password = "",
30+
FullName = "Valid Name",
31+
CardNo = "valid_cardNo",
32+
}
33+
};
34+
35+
// error: The Password must be at least 6 characters long.
36+
yield return new object[]
37+
{
38+
new RegisterViewModel
39+
{
40+
UserName = "valid_username",
41+
Password = "12345",
42+
FullName = "Valid Name",
43+
CardNo = "valid_cardNo",
44+
}
45+
};
46+
47+
// error: FullName field is required
48+
yield return new object[]
49+
{
50+
new RegisterViewModel
51+
{
52+
UserName = "valid_username",
53+
Password = "valid_password",
54+
FullName = "",
55+
CardNo = "valid_cardNo",
56+
}
57+
};
58+
59+
// error: CardNo field is required
60+
yield return new object[]
61+
{
62+
new RegisterViewModel
63+
{
64+
UserName = "valid_username",
65+
Password = "valid_password",
66+
FullName = "Valid Name",
67+
CardNo = "",
68+
}
69+
};
70+
71+
// error: UserName is already taken.
72+
yield return new object[]
73+
{
74+
new RegisterViewModel
75+
{
76+
UserName = "existing_username",
77+
Password = "valid_password",
78+
FullName = "Valid Name",
79+
CardNo = "valid_cardNo",
80+
}
81+
};
82+
83+
// error: Card No. is already in use
84+
yield return new object[]
85+
{
86+
new RegisterViewModel
87+
{
88+
UserName = "valid_username",
89+
Password = "valid_password",
90+
FullName = "Valid Name",
91+
CardNo = "existing_cardNo",
92+
}
93+
};
94+
}
95+
96+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
97+
}
98+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System.Linq;
2+
using System.Net;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Identity;
6+
using Microsoft.EntityFrameworkCore;
7+
using Test.Api.ClassData;
8+
using Test.Api.Models;
9+
using Test.Api.Utils;
10+
using WebApi.Constants;
11+
using WebApi.Entities;
12+
using WebApi.Features.Accounts;
13+
using WebApi.Features.Auth;
14+
using Xunit;
15+
16+
namespace Test.Api
17+
{
18+
public class AccountsTest : IClassFixture<TestServerFixture>
19+
{
20+
private const string API_URL = "api/accounts";
21+
private readonly TestServerFixture _fixture;
22+
23+
public AccountsTest(TestServerFixture fixture)
24+
{
25+
_fixture = fixture;
26+
27+
// Set up Default Auth as Admin
28+
var userCredentials = new LoginViewModel
29+
{
30+
UserName = DefaultAdmin.UserName,
31+
Password = DefaultAdmin.Password
32+
};
33+
AuthExtensions.SetupJwtAuth(_fixture, userCredentials).Wait();
34+
}
35+
36+
[Fact]
37+
public async Task GivenValidModel_WhenPostRegisterRequest_ThenReturnOk()
38+
{
39+
// Arrange
40+
var model = new EmployeeTestModel();
41+
42+
// Act
43+
var response = await _fixture.Client.PostAsJsonAsync($"{API_URL}/register", model);
44+
45+
// Assert
46+
response.EnsureSuccessStatusCode();
47+
48+
var updatedModel = await _fixture.Context.Employees.FirstAsync(m => m.FullName == model.FullName);
49+
Assert.Equal(updatedModel.FullName, model.FullName);
50+
Assert.Equal(updatedModel.CardNo, model.CardNo);
51+
Assert.Equal(updatedModel.Position, model.Position);
52+
53+
var assertAccount = await AuthExtensions.GetJwt(
54+
_fixture,
55+
new LoginViewModel
56+
{
57+
UserName = model.UserName,
58+
Password = model.Password
59+
}
60+
);
61+
Assert.NotEmpty(assertAccount);
62+
}
63+
64+
[Theory]
65+
[ClassData(typeof(InvalidRegisterModels))]
66+
public async Task GivenInvalidModels_WhenPostRegisterRequest_ThenReturnBadRequest(RegisterViewModel viewModel)
67+
{
68+
// Arrange
69+
if (viewModel.UserName == "existing_username")
70+
{
71+
var existingUserName = _fixture.Context.Users.Last().UserName;
72+
viewModel.UserName = existingUserName;
73+
}
74+
75+
if (viewModel.CardNo == "existing_cardNo")
76+
{
77+
var existingCardNo = _fixture.Context.Employees.Last().CardNo;
78+
viewModel.CardNo = existingCardNo;
79+
}
80+
81+
// Act
82+
var response = await _fixture.Client.PostAsJsonAsync($"{API_URL}/register", viewModel);
83+
84+
// Assert
85+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
86+
}
87+
}
88+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System.Linq;
2+
using System.Net.Http;
3+
using System.Threading.Tasks;
4+
using Newtonsoft.Json;
5+
using Test.Api.Utils;
6+
using WebApi.Constants;
7+
using WebApi.Features.Auth;
8+
using WebApi.Features.Config;
9+
using Xunit;
10+
11+
namespace Test.Api
12+
{
13+
public class ConfigTest : IClassFixture<TestServerFixture>
14+
{
15+
private const string API_URL = "api/config";
16+
private readonly TestServerFixture _fixture;
17+
18+
public ConfigTest(TestServerFixture fixture)
19+
{
20+
_fixture = fixture;
21+
22+
// Set up Default Auth as Admin
23+
var userCredentials = new LoginViewModel
24+
{
25+
UserName = DefaultAdmin.UserName,
26+
Password = DefaultAdmin.Password
27+
};
28+
AuthExtensions.SetupJwtAuth(_fixture, userCredentials).Wait();
29+
}
30+
31+
[Fact]
32+
public async Task GetDetails_ThenReturnOk()
33+
{
34+
// Act
35+
var response = await _fixture.Client.GetAsync(API_URL);
36+
var result = await response.Content.ReadAsStringAsync();
37+
var resultModel = JsonConvert.DeserializeObject<ConfigViewModel>(result);
38+
39+
// Assert
40+
response.EnsureSuccessStatusCode();
41+
42+
var updatedModel = _fixture.Context.Config.First();
43+
Assert.Equal(updatedModel.Id, resultModel.Id);
44+
Assert.Equal(updatedModel.TimeIn, resultModel.TimeIn);
45+
Assert.Equal(updatedModel.TimeOut, resultModel.TimeOut);
46+
Assert.Equal(updatedModel.GracePeriod, resultModel.GracePeriod);
47+
}
48+
49+
[Fact]
50+
public async Task PutRequest_ThenReturnOk()
51+
{
52+
// Arrange
53+
var model = _fixture.Context.Config.First();
54+
model.TimeIn = "09:30";
55+
model.TimeOut = "17:15";
56+
model.GracePeriod = "5";
57+
58+
// Act
59+
var response = await _fixture.Client.PutAsJsonAsync(API_URL, model);
60+
61+
// Assert
62+
response.EnsureSuccessStatusCode();
63+
64+
var updatedModel = _fixture.Context.Config.First();
65+
Assert.Equal(updatedModel.TimeIn, model.TimeIn);
66+
Assert.Equal(updatedModel.TimeOut, model.TimeOut);
67+
Assert.Equal(updatedModel.GracePeriod, model.GracePeriod);
68+
}
69+
70+
// TODO: Add time validation in `ConfigViewModel`
71+
}
72+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Net;
5+
using System.Net.Http;
6+
using System.Threading.Tasks;
7+
using Microsoft.EntityFrameworkCore;
8+
using Newtonsoft.Json;
9+
using Test.Api.Models;
10+
using Test.Api.Utils;
11+
using WebApi.Constants;
12+
using WebApi.Features.Auth;
13+
using WebApi.Features.Employees;
14+
using Xunit;
15+
16+
namespace Test.Api
17+
{
18+
public class EmployeeTest : IClassFixture<TestServerFixture>
19+
{
20+
private const string API_URL = "api/employee";
21+
private readonly TestServerFixture _fixture;
22+
23+
public EmployeeTest(TestServerFixture fixture)
24+
{
25+
_fixture = fixture;
26+
27+
// Set up Default Auth as Admin
28+
var userCredentials = new LoginViewModel
29+
{
30+
UserName = DefaultAdmin.UserName,
31+
Password = DefaultAdmin.Password
32+
};
33+
AuthExtensions.SetupJwtAuth(_fixture, userCredentials).Wait();
34+
}
35+
36+
[Fact]
37+
public async Task GetList_ThenReturnOk()
38+
{
39+
// Arrange
40+
var totalEmploeeFromDb = _fixture.Context.Employees.Count();
41+
42+
// Act
43+
var response = await _fixture.Client.GetAsync(API_URL);
44+
var result = await response.Content.ReadAsStringAsync();
45+
var resultModel = JsonConvert.DeserializeObject<ICollection<EmployeeViewModel>>(result);
46+
47+
// Assert
48+
response.EnsureSuccessStatusCode();
49+
50+
var resultCount = resultModel.Count();
51+
Assert.Equal(totalEmploeeFromDb, resultCount);
52+
}
53+
54+
[Fact]
55+
public async Task GetDetails_ThenReturnOk()
56+
{
57+
// Arrange
58+
var model = _fixture.Context.Employees.First();
59+
var employeeId = model.Id;
60+
61+
// Act
62+
var response = await _fixture.Client.GetAsync($"{API_URL}/{employeeId}");
63+
var result = await response.Content.ReadAsStringAsync();
64+
var resultModel = JsonConvert.DeserializeObject<EmployeeViewModel>(result);
65+
66+
// Assert
67+
response.EnsureSuccessStatusCode();
68+
Assert.Equal(model.FullName, resultModel.FullName);
69+
Assert.Equal(model.Position, resultModel.Position);
70+
Assert.Equal(model.CardNo, resultModel.CardNo);
71+
Assert.Equal(model.Status, resultModel.Status);
72+
Assert.Equal(model.IdentityId, resultModel.IdentityId);
73+
}
74+
75+
[Fact]
76+
public async Task GivenValidEmployee_WhenPutRequest_ThenReturnOkWithUpdatedModel()
77+
{
78+
// Arrange
79+
var testModel = new EmployeeTestModel();
80+
var model = _fixture.Context.Employees.Last();
81+
model.FullName = testModel.FullName;
82+
model.CardNo = testModel.CardNo;
83+
model.Position = testModel.Position;
84+
85+
// Act
86+
var response = await _fixture.Client.PutAsJsonAsync(API_URL, model);
87+
88+
// Assert
89+
response.EnsureSuccessStatusCode();
90+
91+
var updatedModel = _fixture.Context.Employees.Find(model.Id);
92+
Assert.Equal(model, updatedModel);
93+
}
94+
95+
[Theory]
96+
[InlineData("", "full_name", "card_no")]
97+
[InlineData("718cae62-3856-4620-bada-321cc66023f0", "", "card_no")]
98+
[InlineData("718cae62-3856-4620-bada-321cc66023f0", "full_name", "")]
99+
[InlineData("718cae62-3856-4620-bada-321cc66023f0", "full_name", "existing_card_no")]
100+
public async Task GivenInvalidEmployee_WhenPutRequest_ThenReturnBadRequest(string identityId, string fullName, string cardNo)
101+
{
102+
// Arrange
103+
var testModel = new EmployeeTestModel();
104+
var model = _fixture.Context.Employees.Last();
105+
106+
model.IdentityId = identityId ?? model.IdentityId;
107+
model.FullName = fullName ?? model.FullName;
108+
model.CardNo = cardNo ?? model.CardNo;
109+
110+
if(cardNo == "existing_card_no")
111+
{
112+
var existingCardNo = _fixture.Context.Employees.First().CardNo;
113+
model.CardNo = existingCardNo;
114+
}
115+
116+
// Act
117+
var response = await _fixture.Client.PutAsJsonAsync(API_URL, model);
118+
119+
// Assert
120+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)