From 129a6c1cfefcd0b9fdf215a0d68ae979895f2fea Mon Sep 17 00:00:00 2001 From: Liam Lindsay Date: Tue, 28 Jul 2026 19:57:36 -0700 Subject: [PATCH 1/2] Initial commit for Copilot Traning --- .../src/Library.Console/CommonActions.cs | 5 +- .../src/Library.Console/ConsoleApp.cs | 59 ++++++++++++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs b/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs index 681f95c..7b102ed 100644 --- a/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs +++ b/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs @@ -9,5 +9,6 @@ public enum CommonActions SearchPatrons = 4, RenewPatronMembership = 8, ReturnLoanedBook = 16, - ExtendLoanedBook = 32 -} + ExtendLoanedBook = 32, + SearchBooks = 64 +} \ No newline at end of file diff --git a/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs b/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs index 9fc9750..8055c38 100644 --- a/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs +++ b/LabFiles/03-develop-code-features/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs @@ -1,7 +1,10 @@ -using Library.ApplicationCore; +using System; +using System.Linq; +using Library.ApplicationCore; using Library.ApplicationCore.Entities; using Library.ApplicationCore.Enums; using Library.Console; +using Library.Infrastructure.Data; public class ConsoleApp { @@ -16,13 +19,15 @@ public class ConsoleApp ILoanRepository _loanRepository; ILoanService _loanService; IPatronService _patronService; + JsonData _jsonData; - public ConsoleApp(ILoanService loanService, IPatronService patronService, IPatronRepository patronRepository, ILoanRepository loanRepository) + public ConsoleApp(ILoanService loanService, IPatronService patronService, IPatronRepository patronRepository, ILoanRepository loanRepository, JsonData jsonData) { _patronRepository = patronRepository; _loanRepository = loanRepository; _loanService = loanService; _patronService = patronService; + _jsonData = jsonData; } public async Task Run() @@ -139,6 +144,7 @@ static CommonActions ReadInputOptions(CommonActions options, out int optionNumbe "m" when options.HasFlag(CommonActions.RenewPatronMembership) => CommonActions.RenewPatronMembership, "e" when options.HasFlag(CommonActions.ExtendLoanedBook) => CommonActions.ExtendLoanedBook, "r" when options.HasFlag(CommonActions.ReturnLoanedBook) => CommonActions.ReturnLoanedBook, + "b" when options.HasFlag(CommonActions.SearchBooks) => CommonActions.SearchBooks, _ when int.TryParse(userInput, out optionNumber) => CommonActions.Select, _ => CommonActions.Repeat }; @@ -170,6 +176,10 @@ static void WriteInputOptions(CommonActions options) { Console.WriteLine(" - \"s\" for new search"); } + if (options.HasFlag(CommonActions.SearchBooks)) + { + Console.WriteLine(" - \"b\" to check for book availability"); + } if (options.HasFlag(CommonActions.Quit)) { Console.WriteLine(" - \"q\" to quit"); @@ -193,8 +203,9 @@ async Task PatronDetails() loanNumber++; } - CommonActions options = CommonActions.SearchPatrons | CommonActions.Quit | CommonActions.Select | CommonActions.RenewPatronMembership; + CommonActions options = CommonActions.SearchPatrons | CommonActions.Quit | CommonActions.Select | CommonActions.RenewPatronMembership | CommonActions.SearchBooks; CommonActions action = ReadInputOptions(options, out int selectedLoanNumber); + if (action == CommonActions.Select) { if (selectedLoanNumber >= 1 && selectedLoanNumber <= selectedPatronDetails.Loans.Count()) @@ -225,10 +236,52 @@ async Task PatronDetails() selectedPatronDetails = (await _patronRepository.GetPatron(selectedPatronDetails.Id))!; return ConsoleState.PatronDetails; } + else if (action == CommonActions.SearchBooks) + { + return await SearchBooks(); + } throw new InvalidOperationException("An input option is not handled."); } + async Task SearchBooks() + { + string? bookTitle = null; + while (string.IsNullOrWhiteSpace(bookTitle)) + { + Console.Write("Enter a book title to search for: "); + bookTitle = Console.ReadLine(); + } + + await _jsonData.EnsureDataLoaded(); + + var book = _jsonData.Books!.FirstOrDefault(b => string.Equals(b.Title, bookTitle, StringComparison.OrdinalIgnoreCase)); + if (book == null) + { + Console.WriteLine($"No book found with the title \"{bookTitle}\"."); + return ConsoleState.PatronDetails; + } + + var bookItem = _jsonData.BookItems!.FirstOrDefault(bi => bi.BookId == book.Id); + if (bookItem == null) + { + Console.WriteLine($"No book item found for the title \"{book.Title}\"."); + return ConsoleState.PatronDetails; + } + + var loan = _jsonData.Loans!.FirstOrDefault(l => l.BookItemId == bookItem.Id && l.ReturnDate == null); + if (loan == null) + { + Console.WriteLine($"\"{book.Title}\" is available for loan."); + } + else + { + Console.WriteLine($"\"{book.Title}\" is on loan to another patron. The return due date is {loan.DueDate}."); + } + + return ConsoleState.PatronDetails; + } + async Task LoanDetails() { Console.WriteLine($"Book title: {selectedLoanDetails.BookItem!.Book!.Title}"); From f76f8cce0de7c53d0917a5454369a79ae439f6d6 Mon Sep 17 00:00:00 2001 From: Liam Lindsay Date: Wed, 29 Jul 2026 16:57:37 -0700 Subject: [PATCH 2/2] Unit test generation with Github Copilot --- .../JsonLoanRepository/GetLoan.cs | 64 +++++++++++++++++++ .../tests/UnitTests/UnitTests.csproj | 15 +++++ 2 files changed, 79 insertions(+) create mode 100644 LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/Infrastructure/JsonLoanRepository/GetLoan.cs diff --git a/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/Infrastructure/JsonLoanRepository/GetLoan.cs b/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/Infrastructure/JsonLoanRepository/GetLoan.cs new file mode 100644 index 0000000..1514e94 --- /dev/null +++ b/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/Infrastructure/JsonLoanRepository/GetLoan.cs @@ -0,0 +1,64 @@ +using NSubstitute; +using Library.ApplicationCore; +using Library.ApplicationCore.Entities; +using Library.Infrastructure.Data; +using Microsoft.Extensions.Configuration; +using Xunit; + +namespace UnitTests.Infrastructure.JsonLoanRepositoryTests; + +public class GetLoanTest +{ + private readonly ILoanRepository _mockLoanRepository; + private readonly JsonLoanRepository _jsonLoanRepository; + private readonly IConfiguration _configuration; + private readonly JsonData _jsonData; + + public GetLoanTest() + { + _mockLoanRepository = Substitute.For(); + _configuration = new ConfigurationBuilder().Build(); + _jsonData = new JsonData(_configuration); + _jsonLoanRepository = new JsonLoanRepository(_jsonData); + } + + [Fact(DisplayName = "JsonLoanRepository.GetLoan: Returns loan when loan ID is found")] + public async Task GetLoan_ReturnsLoanWhenLoanIdIsFound() + { + // Arrange + var loanId = 1; // Use a loan ID that exists in the Loans.json file + var expectedLoan = new Loan + { + Id = loanId, + BookItemId = 17, + PatronId = 22, + LoanDate = DateTime.Parse("2023-12-08T00:40:43.1808862"), + DueDate = DateTime.Parse("2023-12-22T00:40:43.1808862"), + ReturnDate = null + }; + + _mockLoanRepository.GetLoan(loanId).Returns(expectedLoan); + + // Act + var actualLoan = await _jsonLoanRepository.GetLoan(loanId); + + // Assert + Assert.NotNull(actualLoan); + Assert.Equal(expectedLoan.Id, actualLoan?.Id); + } + + [Fact(DisplayName = "JsonLoanRepository.GetLoan: Returns null when loan ID is not found")] + public async Task GetLoan_ReturnsNullWhenLoanIdIsNotFound() + { + // Arrange + var loanId = 999; // Use a loan ID that does not exist in the Loans.json file + + _mockLoanRepository.GetLoan(loanId).Returns((Loan?)null); + + // Act + var actualLoan = await _jsonLoanRepository.GetLoan(loanId); + + // Assert + Assert.Null(actualLoan); + } +} \ No newline at end of file diff --git a/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/UnitTests.csproj b/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/UnitTests.csproj index a156d8f..2e9a0c9 100644 --- a/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/UnitTests.csproj +++ b/LabFiles/04-develop-unit-tests-xunit/AccelerateDevGHCopilot/tests/UnitTests/UnitTests.csproj @@ -23,6 +23,21 @@ + + + + + + Json\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + + + + Json\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest +