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
8 changes: 4 additions & 4 deletions api.tests/Notes/GetNotesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public async Task GetNoteByIdSuccess()
Assert.That(noteResult.Status, Is.EqualTo("success"));
Assert.That(noteResult.Data, Is.Not.Null);
Assert.That(noteResult.Data.Id, Is.EqualTo(noteId));
Assert.That(noteResult.Data.Title, Is.EqualTo("Title Note 1"));
Assert.That(noteResult.Data.Title, Is.EqualTo("Name Note 1"));
Assert.That(noteResult.Data.Content, Is.EqualTo("note1note1 note1 note1 content"));
}

Expand All @@ -88,7 +88,7 @@ public async Task TeacherGetNotesOnAStudentSuccess()
{
await AuthenticateAsTeacherAsync();

var userId = 2; // student user id to get notes for
var userId = 1; // student user id to get notes for
var getNotesResponse = await _client.GetAsync($"/users/{userId}/notes");

Assert.That(getNotesResponse.IsSuccessStatusCode, Is.True);
Expand All @@ -101,15 +101,15 @@ public async Task TeacherGetNotesOnAStudentSuccess()
Assert.That(notesResult.Status, Is.EqualTo("success"));
Assert.That(notesResult.Data, Is.Not.Null);
Assert.That(notesResult.Data.Notes, Is.Not.Empty);
Assert.That(notesResult.Data.Notes.Count, Is.EqualTo(1));
Assert.That(notesResult.Data.Notes.Count, Is.EqualTo(4));
}

[Test]
public async Task TeacherGetNotesOnStudentWithNoNotesSuccess()
{
await AuthenticateAsTeacherAsync();

var userId = 5; // student user id to get notes for but user has no notes
var userId = 3; // student user id to get notes for but user has no notes
var getNotesResponse = await _client.GetAsync($"/users/{userId}/notes");

Assert.That(getNotesResponse.IsSuccessStatusCode, Is.True);
Expand Down
6 changes: 3 additions & 3 deletions api.tests/UserEndpointTests/GetUserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public async Task GetFilteredUsersByFirstNameTest()
[Test]
public async Task GetFilteredUsersByLastNameTest()
{
var getUsersResponse = await _client.GetAsync($"users?searchTerm=Jackson");
var getUsersResponse = await _client.GetAsync($"users?searchTerm=jordan");
var jsonResponse = await getUsersResponse.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ResponseDTO<UsersSuccessDTO>>(jsonResponse);

Expand All @@ -94,7 +94,7 @@ public async Task GetFilteredUsersTestFails()
[Test]
public async Task GetFilteredUsersByFullNameTest()
{
var getUsersResponse = await _client.GetAsync($"users?searchTerm=Michael%20Jackson");
var getUsersResponse = await _client.GetAsync($"users?searchTerm=Michael%20Jordan");
var jsonResponse = await getUsersResponse.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ResponseDTO<UsersSuccessDTO>>(jsonResponse);

Expand All @@ -108,7 +108,7 @@ public async Task GetFilteredUsersByLetterTest()
var jsonResponse = await getUsersResponse.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ResponseDTO<UsersSuccessDTO>>(jsonResponse);

Assert.That(result.Data.Users.Count, Is.EqualTo(3));
Assert.That(result.Data.Users.Count, Is.EqualTo(2));
}

}
6 changes: 3 additions & 3 deletions api.tests/UserEndpointTests/RegistrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public void TearDown()
[Test]
public async Task RegisterUserExistsTest()
{
const string email = "test1@test1";
const string password = "Test1test1%";
const string username = "TestTestTest";
const string email = "test2@test2";
const string password = "Test2test2%";
const string username = "test2@test2";

var newUser = new RegisterRequestDTO
{
Expand Down
2 changes: 1 addition & 1 deletion exercise.wwwapi/DTOs/GetObjects/UsersSuccessDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ namespace exercise.wwwapi.DTOs.GetUsers;
public class UsersSuccessDTO
{
[JsonPropertyName("users")]
public List<UserDTO> Users { get; set; } = [];
public List<UserDTO> Users { get; set; } = new List<UserDTO>();
}
2 changes: 1 addition & 1 deletion exercise.wwwapi/DTOs/Notes/NotesResponseDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
{
public class NotesResponseDTO
{
public List<NoteDTO> Notes { get; set; }
public List<NoteDTO> Notes { get; set; } = new List<NoteDTO>();
}
}
1 change: 0 additions & 1 deletion exercise.wwwapi/DTOs/UpdateUser/UpdateUserRequestDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public class UpdateUserRequestDTO
[JsonPropertyName("lastName")]
public string? LastName { get; set; }

[JsonPropertyName("bio")]
public string? Bio { get; set; }

[JsonPropertyName("github")]
Expand Down
1 change: 0 additions & 1 deletion exercise.wwwapi/DTOs/Users/PostUserDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace exercise.wwwapi.DTOs.Users
{
public class PostUserDTO
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
Expand Down
18 changes: 9 additions & 9 deletions exercise.wwwapi/Endpoints/NoteEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ private static async Task<IResult> GetAllNotesForUser(IRepository<User> userRepo
{
noteResponse.Add(NoteFactory.GetNoteDTO(note));
}
*/

var response = new ResponseDTO<NotesResponseDTO>
var responseObject = new ResponseDTO<NotesResponseDTO>
{
Status = "success",
Data = new NotesResponseDTO
{
Notes = noteResponse
Notes = result.ToList()
}
};
*/

return TypedResults.Ok(result);
return TypedResults.Ok(responseObject);
}

[ProducesResponseType(StatusCodes.Status200OK)]
Expand Down Expand Up @@ -154,16 +154,16 @@ private static async Task<IResult> GetNoteById(IRepository<Note> noteRepository,
{
return TypedResults.NotFound();
}
/*
var response = new ResponseDTO<NoteDTO>

var responseObject = new ResponseDTO<NoteDTO>
{
Status = "success",
Data = NoteFactory.GetNoteDTO(note)
Data = NoteFactory.GetNoteDTO(response)
};
*/

var result = new GetNoteDTO(response);

return TypedResults.Ok(result);
return TypedResults.Ok(responseObject);
}

[ProducesResponseType(StatusCodes.Status200OK)]
Expand Down
59 changes: 48 additions & 11 deletions exercise.wwwapi/Endpoints/UserEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,49 @@ private static async Task<IResult> GetUsers(IRepository<User> userRepository, st

if (!string.IsNullOrWhiteSpace(searchTerm))
{
var terms = searchTerm
.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Select(t => t.ToLowerInvariant())
.ToArray();

results = results.Where(u =>
$"{u.FirstName} {u.LastName}".Contains(searchTerm, StringComparison.OrdinalIgnoreCase))
.ToList();
{
var first = u.FirstName?.ToLowerInvariant() ?? "";
var last = u.LastName?.ToLowerInvariant() ?? "";
var full = (first + " " + last).Trim();

// All search terms must be present in either first, last, or full name (order-insensitive)
return terms.All(term =>
first.Contains(term) ||
last.Contains(term) ||
full.Contains(term)
);
}).ToList();
}
var userRole = claimPrincipal.Role();
var authorizedAsTeacher = AuthorizeTeacher(claimPrincipal);


var userData = new UsersSuccessDTO
{
Users = results.Select(user => authorizedAsTeacher
? UserFactory.GetUserDTO(user, PrivilegeLevel.Teacher) //if teacher loads students, also load notes for students.
: UserFactory.GetUserDTO(user, PrivilegeLevel.Student))
.ToList()
};

var response = new ResponseDTO<UsersSuccessDTO>
{
Status = "success",
Data = userData
};

var response = results.Select(u => new UserDTO(u)).ToList();
return TypedResults.Ok(response);
}

[ProducesResponseType(StatusCodes.Status200OK)]
private static async Task<IResult> GetUsersByCohort(IRepository<Cohort> repository, int course_id, ClaimsPrincipal claimsPrincipal)
private static async Task<IResult> GetUsersByCohort(IRepository<Cohort> repository, int cohort_id, ClaimsPrincipal claimsPrincipal)
{
var response = await repository.GetByIdWithIncludes(a => a.Include(p => p.CohortCourses).ThenInclude(b => b.UserCCs).ThenInclude(a => a.User).ThenInclude(u => u.Notes), course_id);
var response = await repository.GetByIdWithIncludes(a => a.Include(p => p.CohortCourses).ThenInclude(b => b.UserCCs).ThenInclude(a => a.User).ThenInclude(u => u.Notes), cohort_id);
var results = response.CohortCourses.SelectMany(a => a.UserCCs).Select(a => a.User).ToList();
var dto_results = results.Select(a => new UserDTO(a));

Expand Down Expand Up @@ -102,13 +128,23 @@ private static async Task<IResult> Register(PostUserDTO request, IRepository<Use
failureDto.PasswordErrors.Add(error.ErrorMessage);
}

var failResponse = new ResponseDTO<RegisterFailureDTO> { Status = "fail", Data = failureDto };
var failResponse = new ResponseDTO<RegisterFailureDTO> { Status = "conflict", Data = failureDto };
return Results.BadRequest(failResponse);
}


var response = await userRepository.GetWithIncludes(x => x.Where(u => u.Email == request.Email)); // uses where-statement to filter data before fetching
if (response.Count == 1)
{
return Results.Conflict(new Payload<object>
{
Status = "fail",
Data = "User already exists"
});
}






var passwordHash = BCrypt.Net.BCrypt.HashPassword(request.Password);

Expand All @@ -130,7 +166,7 @@ private static async Task<IResult> Register(PostUserDTO request, IRepository<Use
userRepository.Insert(user);
await userRepository.SaveAsync();

var response = new ResponseDTO<RegisterSuccessDTO>
var responseObject = new ResponseDTO<RegisterSuccessDTO>
{
Status = "success",
Data = new RegisterSuccessDTO
Expand All @@ -149,8 +185,9 @@ private static async Task<IResult> Register(PostUserDTO request, IRepository<Use
}
}
};


return Results.Ok(response);
return Results.Ok(responseObject);
}

[ProducesResponseType(StatusCodes.Status200OK)]
Expand Down