From 9d460fb029f1296280af4936a7228d0bcdd67bf9 Mon Sep 17 00:00:00 2001 From: Priya Patil Date: Tue, 16 Jun 2026 20:13:52 +0530 Subject: [PATCH 1/3] Added optional Icon field to Goal model --- CommBank-Server/Models/Goal.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CommBank-Server/Models/Goal.cs b/CommBank-Server/Models/Goal.cs index 77ff1ad5..7a37e5bd 100644 --- a/CommBank-Server/Models/Goal.cs +++ b/CommBank-Server/Models/Goal.cs @@ -27,4 +27,7 @@ public class Goal [BsonRepresentation(BsonType.ObjectId)] public string? UserId { get; set; } + + // New field added for task + public string? Icon { get; set; } } \ No newline at end of file From 50c3a7a6c519ef818773af951333fd031ad9240d Mon Sep 17 00:00:00 2001 From: Priya Patil Date: Wed, 17 Jun 2026 12:40:28 +0530 Subject: [PATCH 2/3] Added GoalController unit tests for GetForUser route --- .gitignore | 1 + CommBank-Server/Controllers/GoalController.cs | 140 ++++++++---------- CommBank-Server/Secrets.json | 2 +- 3 files changed, 65 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index 67697151..e9fd182b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +Secrets.json # globs Makefile.in *.userprefs diff --git a/CommBank-Server/Controllers/GoalController.cs b/CommBank-Server/Controllers/GoalController.cs index 98271a5f..f08c12a0 100644 --- a/CommBank-Server/Controllers/GoalController.cs +++ b/CommBank-Server/Controllers/GoalController.cs @@ -1,102 +1,88 @@ -using Microsoft.AspNetCore.Mvc; -using CommBank.Services; +using Xunit; +using Moq; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; +using CommBank.Controllers; using CommBank.Models; +using CommBank.Services; -namespace CommBank.Controllers; - -[ApiController] -[Route("api/[controller]")] -public class GoalController : ControllerBase +namespace CommBank.Tests { - private readonly IGoalsService _goalsService; - private readonly IUsersService _usersService; - - public GoalController(IGoalsService goalsService, IUsersService usersService) + public class GoalControllerTests { - _goalsService = goalsService; - _usersService = usersService; - } - - [HttpGet] - public async Task> Get() => - await _goalsService.GetAsync(); + private readonly Mock _mockGoalsService; + private readonly Mock _mockUsersService; + private readonly GoalController _controller; - [HttpGet("{id:length(24)}")] - public async Task> Get(string id) - { - var goal = await _goalsService.GetAsync(id); - - if (goal is null) + public GoalControllerTests() { - return NotFound(); - } - - return goal; - } - - [HttpGet("User/{id:length(24)}")] - public async Task?> GetForUser(string id) => - await _goalsService.GetForUserAsync(id); + _mockGoalsService = new Mock(); + _mockUsersService = new Mock(); - [HttpPost] - public async Task Post(Goal newGoal) - { - await _goalsService.CreateAsync(newGoal); + _controller = new GoalController( + _mockGoalsService.Object, + _mockUsersService.Object + ); + } - if (newGoal.Id is not null && newGoal.UserId is not null) + [Fact] + public async Task GetForUser_ReturnsGoals_WhenUserExists() { - var user = await _usersService.GetAsync(newGoal.UserId); + // Arrange + var userId = "507f1f77bcf86cd799439011"; - if (user is not null && user.Id is not null) + var goals = new List { - if (user.GoalIds is not null) - { - user.GoalIds.Add(newGoal.Id); - } - else - { - user.GoalIds = new() - { - newGoal.Id - }; - } - - await _usersService.UpdateAsync(user.Id, user); - } - } + new Goal { Id = "1", UserId = userId }, + new Goal { Id = "2", UserId = userId } + }; - return CreatedAtAction(nameof(Get), new { id = newGoal.Id }, newGoal); - } + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(goals); - [HttpPut("{id:length(24)}")] - public async Task Update(string id, Goal updatedGoal) - { - var goal = await _goalsService.GetAsync(id); + // Act + var result = await _controller.GetForUser(userId); - if (goal is null) - { - return NotFound(); + // Assert + Assert.NotNull(result); + Assert.Equal(2, result.Count); } - updatedGoal.Id = goal.Id; + [Fact] + public async Task GetForUser_ReturnsEmptyList_WhenNoGoals() + { + // Arrange + var userId = "507f1f77bcf86cd799439011"; - await _goalsService.UpdateAsync(id, updatedGoal); + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(new List()); - return NoContent(); - } + // Act + var result = await _controller.GetForUser(userId); - [HttpDelete("{id:length(24)}")] - public async Task Delete(string id) - { - var goal = await _goalsService.GetAsync(id); + // Assert + Assert.NotNull(result); + Assert.Empty(result); + } - if (goal is null) + [Fact] + public async Task GetForUser_CallsServiceOnce() { - return NotFound(); - } + // Arrange + var userId = "507f1f77bcf86cd799439011"; + + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(new List()); - await _goalsService.RemoveAsync(id); + // Act + await _controller.GetForUser(userId); - return NoContent(); + // Assert + _mockGoalsService.Verify(s => s.GetForUserAsync(userId), Times.Once); + } } } \ No newline at end of file diff --git a/CommBank-Server/Secrets.json b/CommBank-Server/Secrets.json index 0e5bf949..0d55f273 100644 --- a/CommBank-Server/Secrets.json +++ b/CommBank-Server/Secrets.json @@ -1,5 +1,5 @@ { "ConnectionStrings": { - "CommBank": "{CONNECTION_STRING}" + "CommBank": "mongodb+srv://priya:priya%402718@namastenode.7yndxoo.mongodb.net/CommBank?retryWrites=true&w=majority" } } \ No newline at end of file From 699633cb0970b64f55b06cf6e2bcd8a171f2497c Mon Sep 17 00:00:00 2001 From: Priya Patil Date: Wed, 17 Jun 2026 13:04:43 +0530 Subject: [PATCH 3/3] Added GoalController unit tests --- .../Controllers/GoalControllerTests.cs | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 CommBank-Server/Controllers/GoalControllerTests.cs diff --git a/CommBank-Server/Controllers/GoalControllerTests.cs b/CommBank-Server/Controllers/GoalControllerTests.cs new file mode 100644 index 00000000..40b8140b --- /dev/null +++ b/CommBank-Server/Controllers/GoalControllerTests.cs @@ -0,0 +1,89 @@ +using Xunit; +using Moq; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; + +using CommBank.Controllers; +using CommBank.Models; +using CommBank.Services; + +namespace CommBank.Tests +{ + public class GoalControllerTests + { + private readonly Mock _mockGoalsService; + private readonly Mock _mockUsersService; + private readonly GoalController _controller; + + public GoalControllerTests() + { + _mockGoalsService = new Mock(); + _mockUsersService = new Mock(); + + _controller = new GoalController( + _mockGoalsService.Object, + _mockUsersService.Object + ); + } + + [Fact] + public async Task GetForUser_ReturnsGoals_WhenDataExists() + { + // Arrange + var userId = "507f1f77bcf86cd799439011"; + + var goals = new List + { + new Goal { Id = "1", UserId = userId }, + new Goal { Id = "2", UserId = userId } + }; + + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(goals); + + // Act + var result = await _controller.GetForUser(userId); + + // Assert + Assert.NotNull(result); + Assert.Equal(2, result.Count); + } + + [Fact] + public async Task GetForUser_ReturnsEmptyList_WhenNoGoals() + { + // Arrange + var userId = "507f1f77bcf86cd799439011"; + + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(new List()); + + // Act + var result = await _controller.GetForUser(userId); + + // Assert + Assert.NotNull(result); + Assert.Empty(result); + } + + [Fact] + public async Task GetForUser_ServiceCalledOnce() + { + // Arrange + var userId = "507f1f77bcf86cd799439011"; + + _mockGoalsService + .Setup(s => s.GetForUserAsync(userId)) + .ReturnsAsync(new List()); + + // Act + await _controller.GetForUser(userId); + + // Assert + _mockGoalsService.Verify(s => s.GetForUserAsync(userId), Times.Once); + } + } +} \ No newline at end of file