Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions exercise.tests/Helpers/UserTestCases.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using NUnit.Framework;
using System.Collections.Generic;

namespace exercise.tests.Helpers
{
public static class UserTestCases
{
public static IEnumerable<TestCaseData> ValidRegisterCases()
{
yield return new TestCaseData("validuser", "valid@email.com", "ValidPass1!");
yield return new TestCaseData("user-name", "user1@example.com", "SecurePass9#");
yield return new TestCaseData("user1name", "user2@example.com", "StrongPass$1");
}

public static IEnumerable<TestCaseData> InvalidRegisterCases()
{
yield return new TestCaseData("ThisIsWayTooLong123ThisIsWayTooLong123ThisIsWayTooLong123", "valid@email.com", "ValidPass1!").SetName("Invalid: Username too long (register)");
yield return new TestCaseData("", "valid@email.com", "ValidPass1!").SetName("Invalid: Username too short (register)");
yield return new TestCaseData("validuser", "plainaddress", "ValidPass1!").SetName("Invalid: Invalid email format (register)");
yield return new TestCaseData("validuser", "user@domain.c", "ValidPass1!").SetName("Invalid: Invalid email domain (register)");
yield return new TestCaseData("validuser", "valid@email.com", "short1!").SetName("Invalid: Password too short (register)");
yield return new TestCaseData("validuser", "valid@email.com", "alllowercase1!").SetName("Invalid: Missing uppercase (register)");
yield return new TestCaseData("validuser", "valid@email.com", "NoNumber!").SetName("Invalid: Missing number (register)");
yield return new TestCaseData("validuser", "valid@email.com", "NoSpecialChar1").SetName("Invalid: Missing special character (register)");
}

public static IEnumerable<TestCaseData> ValidLoginCases()
{
yield return new TestCaseData("oyvind.perez1@example.com", "SuperHash!4");
//needs valid email password combinations
//yield return new TestCaseData("nigel.nowak2@example.com", "StrongPass$1");
//yield return new TestCaseData("nigel.nowak2@example.com", "ValidPass1!");
}

public static IEnumerable<TestCaseData> InvalidLoginCases()
{
yield return new TestCaseData("valid@email.com", "short1!").SetName("Invalid: Password too short (login)");
yield return new TestCaseData("valid@email.com", "alllowercase1!").SetName("Invalid: Missing uppercase (login)");
yield return new TestCaseData("valid@email.com", "NoNumber!").SetName("Invalid: Missing number (login)");
yield return new TestCaseData("valid@email.com", "NoSpecialChar1").SetName("Invalid: Missing special character (login)");
yield return new TestCaseData("plainaddress", "ValidPass1!").SetName("Invalid: Invalid email format (login)");
yield return new TestCaseData("user@domain.c", "ValidPass1!").SetName("Invalid: Invalid email domain (login)");
}
}
}
53 changes: 25 additions & 28 deletions exercise.tests/IntegrationTests/UserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using exercise.tests.Helpers;

namespace exercise.tests.IntegrationTests
{
Expand All @@ -31,18 +32,21 @@ public void TearDown()
}

// ad test cases for approved usernames, emails
[Test]
public async Task Register_success()
[Test, TestCaseSource(typeof(UserTestCases), nameof(UserTestCases.ValidRegisterCases))]
public async Task Register_success(string username, string email, string password)
{
var uniqueId = DateTime.UtcNow.ToString("yyMMddHHmmssffff");
RegisterRequestDTO body = new RegisterRequestDTO {
email= $"myemailVery{uniqueId}@gmail.com",

string uniqueUsername = username.Length > 0 ? username + uniqueId : "";

RegisterRequestDTO body = new RegisterRequestDTO {
email = $"{uniqueId}{email}",
firstName = "Ole",
lastName = "Petterson",
bio = "Min bio er vakker",
githubUsername = $"ole-gmailpersotn{uniqueId}",
username= $"ole-perrston{uniqueId}",
password = "someR21!password"
githubUsername = uniqueUsername,
username = uniqueUsername,
password = password
};
var json = JsonSerializer.Serialize(body);
var requestBody = new StringContent(json, Encoding.UTF8, "application/json");
Expand All @@ -63,28 +67,22 @@ public async Task Register_success()
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}

// Uncomment these when email/username validation has been implemented in the endpoint
//[TestCase("validuser", "plainaddress", "ValidPass1!")] // Invalid email format
//[TestCase("validuser", "user@domain.c", "ValidPass1!")] // Invalid email domain
//[TestCase("ThisIsWayTooLong123", "valid@email.com", "ValidPass1!")] // Username too long
//[TestCase("", "valid@email.com", "ValidPass1!")] // Username too short, change logic so it doesnt add uniqueid to username
[TestCase("validuser", "valid@email.com", "short1!")] // Password too short
[TestCase("validuser", "valid@email.com", "alllowercase1!")] // Missing uppercase
[TestCase("validuser", "valid@email.com", "NoNumber!")] // Missing number
[TestCase("validuser", "valid@email.com", "NoSpecialChar1")] // Missing special character
[Test, TestCaseSource(typeof(UserTestCases), nameof(UserTestCases.InvalidRegisterCases))]
public async Task Register_Failure(string username, string email, string password)
{
var uniqueId = DateTime.UtcNow.ToString("yyMMddHHmmssffff");
string firstName = "Ole";
string lastName = "Petterson";

string uniqueUsername = username.Length > 0 ? username + uniqueId : "";
RegisterRequestDTO body = new RegisterRequestDTO
{
email = $"myemailVery{uniqueId}@gmail.com",
email = $"{uniqueId}{email}",
firstName = firstName,
lastName = lastName,
bio = "Min bio er vakker",
githubUsername = $"{username}{uniqueId}",
username = $"{username}{uniqueId}",
githubUsername = uniqueUsername,
username =uniqueUsername,
password = password
};

Expand All @@ -108,14 +106,14 @@ public async Task Register_Failure(string username, string email, string passwor
}


[Test]
public async Task Login_success()
[Test, TestCaseSource(typeof(UserTestCases), nameof(UserTestCases.ValidLoginCases))]
public async Task Login_success(string email, string password)
{
var uniqueId = DateTime.UtcNow.ToString("yyMMddHHmmssffff");
RegisterRequestDTO body = new RegisterRequestDTO
{
email = "oyvind.perez1@example.com",
password = "SuperHash!4"
email = email,
password = password
};
var json = JsonSerializer.Serialize(body);
var requestBody = new StringContent(json, Encoding.UTF8, "application/json");
Expand All @@ -139,16 +137,13 @@ public async Task Login_success()
Assert.That(message["data"]["token"], Is.Not.Null);
}

[TestCase("oyvind.perez1@example.com", "short1!")] // Password too short
[TestCase("oyvind.perez1@example.com", "alllowercase1!")] // Missing uppercase
[TestCase("oyvind.perez1@example.com", "NoNumber!")] // Missing number
[TestCase("oyvind.perez1@example.com", "NoSpecialChar1")] // Missing special character
[Test, TestCaseSource(typeof(UserTestCases), nameof(UserTestCases.InvalidLoginCases))]
public async Task Login_failure(string email, string password)
{
var uniqueId = DateTime.UtcNow.ToString("yyMMddHHmmssffff");
LoginRequestDTO body = new LoginRequestDTO
{
email = email,
email = $"{uniqueId}{email}",
password = password
};

Expand All @@ -170,8 +165,10 @@ public async Task Login_failure(string email, string password)
// Assert
Assert.That(response.StatusCode, Is.Not.EqualTo(HttpStatusCode.OK));
Assert.That(message, Is.Not.Null);

Assert.That(message["message"], Is.Not.Null);
Assert.That(message["message"]!.GetValue<string>(), Is.EqualTo("Invalid email and/or password provided"));

}
}
}
2 changes: 1 addition & 1 deletion exercise.tests/IntegrationTests/ValidationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public async Task ValidateEmailExists(string input, string expectedMessage, Http
}

Console.WriteLine("Message: " + message);
Assert.That(message?.ToString(), Is.EqualTo(expectedMessage));
Assert.That(message?["message"]?.GetValue<string>(), Is.EqualTo(expectedMessage));
Assert.That(response.StatusCode, Is.EqualTo(expectedStatusCode));
}
}
Expand Down
22 changes: 18 additions & 4 deletions exercise.wwwapi/Endpoints/UserEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,23 @@ private static async Task<IResult> GetUsers(IRepository<User> service, string? f
[ProducesResponseType(StatusCodes.Status409Conflict)]
private static IResult Register(RegisterRequestDTO request, IRepository<User> service, IMapper mapper)
{
//user exists
if (service.GetAll().Where(u => u.Email == request.email).Any()) return Results.Conflict(new ResponseDTO<Object>() { Message = "Fail" });

// syntax checks
// check valid password
string validationResult = Validator.Password(request.password);
if (validationResult != "Accepted") return TypedResults.BadRequest(new ResponseDTO<Object>() { Message = validationResult });
// check valid email
string emailValidation = Validator.Email(request.email);
if (emailValidation != "Accepted") return TypedResults.BadRequest(new ResponseDTO<Object>() { Message = emailValidation });
// check valid username
string usernameValidation = Validator.Username(request.username);
if (usernameValidation != "Accepted") return TypedResults.BadRequest(new ResponseDTO<Object>() { Message = usernameValidation });

// ecxist checks
// check if email is in database
var emailExists = service.GetAllFiltered(q => q.Email == request.email);
if (emailExists.Count() != 0) return Results.Conflict(new ResponseDTO<Object>() { Message = "Fail" });


string passwordHash = BCrypt.Net.BCrypt.HashPassword(request.password);

Expand Down Expand Up @@ -96,9 +107,12 @@ private static IResult Login(LoginRequestDTO request, IRepository<User> service,
string validationResult = Validator.Password(request.password);
if (validationResult != "Accepted") return TypedResults.BadRequest(new ResponseDTO<string>() { Message = "Invalid email and/or password provided" });

//email doesn't exist, should probably be 404 user not found, but should maybe just say invalid email or password
//check if email is in database
var emailExists = service.GetAllFiltered(q => q.Email == request.email);
if (emailExists.Count() == 0) return TypedResults.BadRequest(new ResponseDTO<Object>() { Message = "Invalid email and/or password provided"});


//user doesn't exist, should probably be 404 user not found, but should maybe just say invalid email or password
if (!service.GetAll().Where(u => u.Email == request.email).Any()) return Results.BadRequest(new ResponseDTO<Object>() { Message = "Invalid email and/or password provided"});

User user = service.GetAll().FirstOrDefault(u => u.Email == request.email)!;

Expand Down