Skip to content

Commit 9e69a56

Browse files
committed
Added Log Integration test
- Updated endpoint tests - Added public endpoint test
1 parent d5aa869 commit 9e69a56

File tree

7 files changed

+278
-1
lines changed

7 files changed

+278
-1
lines changed

tests/Api/ClassData/AdminOnlyEndpoints.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ public IEnumerator<object[]> GetEnumerator()
1313
yield return new object[] { HttpMethod.Put, "api/accounts/update-password" };
1414
yield return new object[] { HttpMethod.Put, "api/config" };
1515
yield return new object[] { HttpMethod.Get, "api/employee" };
16+
yield return new object[] { HttpMethod.Put, "api/employee" };
1617
yield return new object[] { HttpMethod.Get, $"api/employee/{Guid.NewGuid()}" };
18+
yield return new object[] { HttpMethod.Put, "api/log" };
19+
yield return new object[] { HttpMethod.Get, $"api/log/{Guid.NewGuid()}" };
1720
}
1821

1922
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

tests/Api/ClassData/AuthorizedEnpoints.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public IEnumerator<object[]> GetEnumerator()
1616
yield return new object[] { HttpMethod.Get, "api/config" };
1717
yield return new object[] { HttpMethod.Put, "api/config" };
1818
yield return new object[] { HttpMethod.Get, "api/employee" };
19+
yield return new object[] { HttpMethod.Put, "api/employee" };
1920
yield return new object[] { HttpMethod.Get, $"api/employee/{Guid.NewGuid()}" };
2021
yield return new object[] { HttpMethod.Get, "api/log" };
2122
yield return new object[] { HttpMethod.Put, "api/log" };
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Net.Http;
5+
6+
namespace Test.Api.ClassData
7+
{
8+
public class PublicEndpoints : IEnumerable<object[]>
9+
{
10+
public IEnumerator<object[]> GetEnumerator()
11+
{
12+
yield return new object[] { HttpMethod.Post, "api/auth/login" };
13+
yield return new object[] { HttpMethod.Post, "api/log" };
14+
}
15+
16+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
17+
}
18+
}

tests/Api/IntegrationTests/AccountsTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ public async Task GivenAuthByEmployee_WhenPutChangePasswordRequest_ThenReturnOk(
163163

164164
// Act
165165
var request = new HttpRequestMessage(HttpMethod.Put, $"{API_URL}/change-password");
166-
// Send request as Employee
167166
request.Content = new StringContent(viewModel, Encoding.UTF8, "application/json");
168167

168+
// Send request as Employee
169169
await AuthExtensions.SetupRequestAuth(
170170
request,
171171
_fixture,

tests/Api/IntegrationTests/AuthTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,21 @@ public async Task GivenAuthAsEmployee_WhenRequestInAdminOnlyEndpoints_ThenReturn
133133
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
134134
}
135135

136+
[Theory]
137+
[ClassData(typeof(PublicEndpoints))]
138+
public async Task GivenPublicEndpoints_WhenRequest_ThenOkOrBadRequest(HttpMethod method, string url)
139+
{
140+
// Act
141+
var request = new HttpRequestMessage(method, url);
142+
request.Content = new StringContent("", Encoding.UTF8, "application/json");
143+
var response = await _fixture.Client.SendAsync(request);
144+
145+
// Assert
146+
if (method == HttpMethod.Get)
147+
response.EnsureSuccessStatusCode();
148+
else
149+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
150+
}
151+
136152
}
137153
}
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
using System;
2+
using System.Linq;
3+
using System.Net;
4+
using System.Net.Http;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Microsoft.EntityFrameworkCore;
8+
using Newtonsoft.Json;
9+
using Test.Api.Utils;
10+
using WebApi.Constants;
11+
using WebApi.Entities;
12+
using WebApi.Features.Auth;
13+
using WebApi.Features.Logs;
14+
using Xunit;
15+
16+
namespace Test.Api
17+
{
18+
public class LogTest : IClassFixture<TestServerFixture>
19+
{
20+
private const string API_URL = "api/log";
21+
private readonly TestServerFixture _fixture;
22+
23+
public LogTest(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 GivenAdminAuth_WhenGetRequest_ThenReturnOkWithAllLogs()
38+
{
39+
// Act
40+
var response = await _fixture.Client.GetAsync(API_URL);
41+
var result = await response.Content.ReadAsStringAsync();
42+
var resultModel = JsonConvert.DeserializeObject<LogListResponseModel>(result);
43+
44+
// Assert
45+
response.EnsureSuccessStatusCode();
46+
47+
var totalList = _fixture.Context.Logs.Count();
48+
Assert.Equal(totalList, resultModel.Meta.TotalItems);
49+
}
50+
51+
[Fact]
52+
public async Task GivenEmployeeAuth_WhenGetRequest_ThenReturnOkWithOwnLogs()
53+
{
54+
// Arrange
55+
var employeeAccount = _fixture.Context.Users.Last();
56+
var employeeDetails = _fixture.Context.Employees.Where(m => m.IdentityId == employeeAccount.Id).First();
57+
var admin = new LoginViewModel
58+
{
59+
UserName = employeeAccount.UserName,
60+
Password = DefaultAdmin.Password,
61+
};
62+
63+
// Act
64+
var request = new HttpRequestMessage(HttpMethod.Get, API_URL);
65+
await AuthExtensions.SetupRequestAuth(request, _fixture, admin);
66+
67+
var response = await _fixture.Client.SendAsync(request);
68+
var result = await response.Content.ReadAsStringAsync();
69+
var resultModel = JsonConvert.DeserializeObject<LogListResponseModel>(result);
70+
71+
// Assert
72+
response.EnsureSuccessStatusCode();
73+
74+
var totalList = _fixture.Context.Logs.Where(m => m.EmployeeId == employeeDetails.Id).Count();
75+
Assert.Equal(totalList, resultModel.Meta.TotalItems);
76+
}
77+
78+
[Fact]
79+
public async Task GivenAdminAuth_WhenGetDetail_ThenReturnOk()
80+
{
81+
// Arrange
82+
var model = _fixture.Context.Logs.MapToViewModel().First();
83+
84+
// Act
85+
var response = await _fixture.Client.GetAsync($"{API_URL}/{model.Id}");
86+
var result = await response.Content.ReadAsStringAsync();
87+
var resultModel = JsonConvert.DeserializeObject<LogViewModel>(result);
88+
89+
// Assert
90+
response.EnsureSuccessStatusCode();
91+
Assert.Equal(model.EmployeeId, resultModel.EmployeeId);
92+
Assert.Equal(model.FullName, resultModel.FullName);
93+
Assert.Equal(model.TimeIn, resultModel.TimeIn);
94+
Assert.Equal(model.TimeOut, resultModel.TimeOut);
95+
}
96+
97+
[Fact]
98+
public async Task GivenAdminAuth_WhenPutRequest_ThenReturnOk()
99+
{
100+
// Arrange
101+
var model = _fixture.Context.Logs.MapToViewModel().First();
102+
model.TimeIn = "02/04/2019 9:06:10 AM";
103+
model.TimeOut = "02/04/2019 5:44:10 PM";
104+
105+
// Act
106+
var response = await _fixture.Client.PutAsJsonAsync(API_URL, model);
107+
108+
// Assert
109+
response.EnsureSuccessStatusCode();
110+
111+
var updatedModel = _fixture.Context.Logs.Find(model.Id);
112+
Assert.Equal(LogExtensions.ToLocal(updatedModel.TimeIn), model.TimeIn.ToString());
113+
Assert.Equal(LogExtensions.ToLocal(updatedModel.TimeOut), model.TimeOut.ToString());
114+
}
115+
116+
[Theory]
117+
[InlineData("valid_id", "", "02/04/2019 5:44:10 PM")]
118+
[InlineData("valid_id", "invalid_date", "02/04/2019 5:44:10 PM")]
119+
[InlineData("invalid_id", "02/04/2019 9:06:10 AM", "")]
120+
[InlineData("valid_id", "02/04/2019 9:06:10 AM", "invalid_date")]
121+
public async Task GivenInvalidModels_WhenPutRequest_ThenReturnBadRequest(string id, string timeIn, string timeOut)
122+
{
123+
// Arrange
124+
var model = _fixture.Context.Logs.MapToViewModel().Last();
125+
model.Id = (id == "valid_id") ? model.Id: Guid.Empty;
126+
model.TimeIn = timeIn;
127+
model.TimeOut = timeOut;
128+
129+
// Act
130+
var response = await _fixture.Client.PutAsJsonAsync(API_URL, model);
131+
132+
// Assert
133+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
134+
}
135+
136+
[Fact]
137+
public async Task PostLog_ThenReturnOkWithTimeIn()
138+
{
139+
// Arrange
140+
var employee = _fixture.Context.Employees.Last();
141+
var viewModel = new LogInOutViewModel
142+
{
143+
CardNo = employee.CardNo,
144+
Password = DefaultAdmin.Password,
145+
};
146+
147+
// Act
148+
var response = await _fixture.Client.PostAsJsonAsync(API_URL, viewModel);
149+
150+
// Assert
151+
response.EnsureSuccessStatusCode();
152+
153+
var updatedLog = _fixture.Context.Logs.Where(m => m.EmployeeId == employee.Id).OrderByDescending(m => m.Created).First();
154+
Assert.NotNull(updatedLog.TimeIn);
155+
Assert.Null(updatedLog.TimeOut);
156+
}
157+
158+
[Fact]
159+
public async Task PostLogTwoTimes_ThenReturnOkWithTimeInAndTimeOut()
160+
{
161+
// Arrange
162+
var employee = _fixture.Context.Employees.ToList().ElementAtOrDefault(3);
163+
var viewModel = new LogInOutViewModel
164+
{
165+
CardNo = employee.CardNo,
166+
Password = DefaultAdmin.Password,
167+
};
168+
169+
// Act
170+
var timeInResponse = await _fixture.Client.PostAsJsonAsync(API_URL, viewModel);
171+
var timeOutResponse = await _fixture.Client.PostAsJsonAsync(API_URL, viewModel);
172+
173+
// Assert
174+
timeOutResponse.EnsureSuccessStatusCode();
175+
176+
var updatedLog = _fixture.Context.Logs.Where(m => m.EmployeeId == employee.Id).OrderByDescending(m => m.Created).First();
177+
Assert.NotNull(updatedLog.TimeIn);
178+
Assert.NotNull(updatedLog.TimeOut);
179+
}
180+
181+
[Fact]
182+
public async Task GivenInactiveEmployee_WhenPostLog_ThenReturnBadRequest()
183+
{
184+
// Arrange
185+
var employee = _fixture.Context.Employees.ToList().ElementAtOrDefault(4);
186+
187+
// Update the employee with inactive status
188+
employee.Status = Status.Inactive;
189+
_fixture.Context.Entry(employee).State = EntityState.Modified;
190+
await _fixture.Context.SaveChangesAsync();
191+
192+
var viewModel = new LogInOutViewModel
193+
{
194+
CardNo = employee.CardNo,
195+
Password = DefaultAdmin.Password,
196+
};
197+
198+
// Act
199+
var response = await _fixture.Client.PostAsJsonAsync(API_URL, viewModel);
200+
201+
// Assert
202+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
203+
}
204+
205+
[Theory]
206+
[InlineData("valid_cardNo", "")]
207+
[InlineData("valid_cardNo", "invalid_password")]
208+
[InlineData("invalid_cardNo", "valid_password")]
209+
[InlineData("", "valid_password")]
210+
public async Task GivenInvalidModels_WhenPostLog_ThenReturnBadRequest(string cardNo, string password)
211+
{
212+
// Arrange
213+
var employee = _fixture.Context.Employees.ToList().ElementAtOrDefault(4);
214+
var viewModel = new LogInOutViewModel
215+
{
216+
CardNo = (cardNo == "valid_cardNo") ? employee.CardNo : cardNo,
217+
Password = (password == "valid_password") ? DefaultAdmin.Password : password,
218+
};
219+
220+
// Act
221+
var response = await _fixture.Client.PostAsJsonAsync(API_URL, viewModel);
222+
223+
// Assert
224+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
225+
}
226+
}
227+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
using WebApi.Entities;
3+
using WebApi.Features.Logs;
4+
5+
namespace Test.Api
6+
{
7+
public class LogListResponseModel
8+
{
9+
public DateFilteredList Meta { get; set; }
10+
public ICollection<LogViewModel> Data { get; set; }
11+
}
12+
}

0 commit comments

Comments
 (0)