From 24b059ea3df6cbeff339164f3e964db2b14d7a8e Mon Sep 17 00:00:00 2001 From: Aaron Po Date: Thu, 29 Jan 2026 20:28:50 -0500 Subject: [PATCH] Set up Reqnroll for BDD testing --- .gitignore | 2 + src/Core/API/API.Specs/API.Specs.csproj | 37 ++++++++++++++ .../API/API.Specs/Features/NotFound.feature | 10 ++++ src/Core/API/API.Specs/Steps/ApiSteps.cs | 51 +++++++++++++++++++ src/Core/API/API.Specs/reqnroll.json | 15 ++++++ 5 files changed, 115 insertions(+) create mode 100644 src/Core/API/API.Specs/API.Specs.csproj create mode 100644 src/Core/API/API.Specs/Features/NotFound.feature create mode 100644 src/Core/API/API.Specs/Steps/ApiSteps.cs create mode 100644 src/Core/API/API.Specs/reqnroll.json diff --git a/.gitignore b/.gitignore index ff8262c..ba1194e 100644 --- a/.gitignore +++ b/.gitignore @@ -480,3 +480,5 @@ FodyWeavers.xsd */data_source/other .fake .idea + +*.feature.cs \ No newline at end of file diff --git a/src/Core/API/API.Specs/API.Specs.csproj b/src/Core/API/API.Specs/API.Specs.csproj new file mode 100644 index 0000000..ba032cb --- /dev/null +++ b/src/Core/API/API.Specs/API.Specs.csproj @@ -0,0 +1,37 @@ + + + net10.0 + enable + enable + false + API.Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/API/API.Specs/Features/NotFound.feature b/src/Core/API/API.Specs/Features/NotFound.feature new file mode 100644 index 0000000..68806c8 --- /dev/null +++ b/src/Core/API/API.Specs/Features/NotFound.feature @@ -0,0 +1,10 @@ +Feature: NotFound API + As a client of the API + I want consistent 404 responses + So that consumers can handle missing routes + + Scenario: GET error 404 returns NotFound message + Given the API is running + When I GET "/error/404" + Then the response status code should be 404 + And the response JSON should have "message" equal "Route not found." diff --git a/src/Core/API/API.Specs/Steps/ApiSteps.cs b/src/Core/API/API.Specs/Steps/ApiSteps.cs new file mode 100644 index 0000000..a7fb6b3 --- /dev/null +++ b/src/Core/API/API.Specs/Steps/ApiSteps.cs @@ -0,0 +1,51 @@ +using System.Net; +using System.Net.Http.Json; +using Reqnroll; +using FluentAssertions; + +namespace API.Specs.Steps; + +[Binding] +public class ApiSteps +{ + private readonly TestApiFactory _factory; + private HttpClient? _client; + private HttpResponseMessage? _response; + + public ApiSteps() + { + _factory = new TestApiFactory(); + } + + [Given("the API is running")] + public void GivenTheApiIsRunning() + { + _client = _factory.CreateClient(); + } + + // No user service assumptions needed for 404 tests + + [When("I GET {string}")] + public async Task WhenIGet(string path) + { + _client.Should().NotBeNull("API client must be initialized"); + _response = await _client!.GetAsync(path); + } + + [Then("the response status code should be {int}")] + public void ThenStatusCodeShouldBe(int expected) + { + _response.Should().NotBeNull(); + ((int)_response!.StatusCode).Should().Be(expected); + } + + [Then("the response JSON should have {string} equal {string}")] + public async Task ThenResponseJsonShouldHaveFieldEqual(string field, string expected) + { + _response.Should().NotBeNull(); + var dict = await _response!.Content.ReadFromJsonAsync>(); + dict.Should().NotBeNull(); + dict!.TryGetValue(field, out var value).Should().BeTrue(); + (value?.ToString()).Should().Be(expected); + } +} diff --git a/src/Core/API/API.Specs/reqnroll.json b/src/Core/API/API.Specs/reqnroll.json new file mode 100644 index 0000000..2511d20 --- /dev/null +++ b/src/Core/API/API.Specs/reqnroll.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://raw.githubusercontent.com/reqnroll/Reqnroll/main/Reqnroll.Configuration/reqnroll.schema.json", + "language": { + "feature": "en-US" + }, + "bindingCulture": { + "name": "en-US" + }, + "trace": { + "level": "Verbose" + }, + "runtime": { + "stopAtFirstError": false + } +}