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
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ internal static IEndpointRouteBuilder MapAutocompleteEndpoints(this IEndpointRou
IOptions<SearchApiOptions> options,
HttpContext ctx) =>
{
if (string.IsNullOrWhiteSpace(q)) return Results.BadRequest();

var resolved = EndpointHelpers.Resolve(options.Value, ctx, "autocomplete/v1/", id, q);
var result = await sender.Send(new AutocompleteRequest(id, q ?? string.Empty, resolved.SelfUrl));
var result = await sender.Send(new AutocompleteRequest(id, q, resolved.SelfUrl));
if (result == null) return Results.NotFound();
return Results.Json(result, contentType: "application/ld+json");
});
Expand All @@ -26,8 +28,10 @@ internal static IEndpointRouteBuilder MapAutocompleteEndpoints(this IEndpointRou
IOptions<SearchApiOptions> options,
HttpContext ctx) =>
{
if (string.IsNullOrWhiteSpace(q)) return Results.BadRequest();

var resolved = EndpointHelpers.Resolve(options.Value, ctx, "autocomplete/v2/", id, q);
var result = await sender.Send(new AutocompleteV2Request(id, q ?? string.Empty, resolved.SelfUrl));
var result = await sender.Send(new AutocompleteV2Request(id, q, resolved.SelfUrl));
if (result == null) return Results.NotFound();
return Results.Json(result, contentType: "application/ld+json");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ internal static IEndpointRouteBuilder MapSearchEndpoints(this IEndpointRouteBuil
IOptions<SearchApiOptions> options,
HttpContext ctx) =>
{
if (string.IsNullOrWhiteSpace(q)) return Results.BadRequest();

var resolved = EndpointHelpers.Resolve(options.Value, ctx, "search/v1/", id, q);
var result = await sender.Send(new SearchRequest(id, q ?? string.Empty, resolved.SelfUrl, resolved.ResourceUrl));
var result = await sender.Send(new SearchRequest(id, q, resolved.SelfUrl, resolved.ResourceUrl));
if (result == null) return Results.NotFound();
result.Ignored = EndpointHelpers.GetIgnoredParams(ctx);
return Results.Json(result, contentType: "application/ld+json");
Expand All @@ -27,8 +29,10 @@ internal static IEndpointRouteBuilder MapSearchEndpoints(this IEndpointRouteBuil
IOptions<SearchApiOptions> options,
HttpContext ctx) =>
{
if (string.IsNullOrWhiteSpace(q)) return Results.BadRequest();

var resolved = EndpointHelpers.Resolve(options.Value, ctx, "search/v2/", id, q);
var result = await sender.Send(new SearchV2Request(id, q ?? string.Empty, resolved.SelfUrl, resolved.ResourceUrl));
var result = await sender.Send(new SearchV2Request(id, q, resolved.SelfUrl, resolved.ResourceUrl));
if (result == null) return Results.NotFound();
result.Ignored = EndpointHelpers.GetIgnoredParams(ctx);
return Results.Json(result, contentType: "application/ld+json");
Expand Down
29 changes: 21 additions & 8 deletions src/TextServices.Tests.E2E/BuildAndSearchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,11 @@ public async Task Search_KnownWord_ReturnsHits()
}

[Fact]
public async Task Search_EmptyQuery_ReturnsEmptyNotError()
public async Task Search_EmptyQuery_Returns400()
{
var id = await BuildFixtureAsync("e2e/search-empty");

var response = await ctx.SearchClient.GetAsync($"/search/v1/{id}?q=");
response.StatusCode.ShouldBe(HttpStatusCode.OK);

var body = JsonNode.Parse(await response.Content.ReadAsStringAsync())!;
body["resources"]!.AsArray().Count.ShouldBe(0);
// Query validation happens before the job is looked up, so no fixture is needed.
var response = await ctx.SearchClient.GetAsync("/search/v1/no/such/id?q=");
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
}

[Fact]
Expand All @@ -187,6 +183,15 @@ public async Task Search_UnknownId_Returns404()
response.StatusCode.ShouldBe(HttpStatusCode.NotFound);
}

[Fact]
public async Task Search_MissingQuery_Returns400EvenForUnknownId()
{
// Query validation happens before the job is looked up — an unknown id
// with a missing query returns 400, not 404.
var response = await ctx.SearchClient.GetAsync("/search/v2/no/such/id");
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
}

// -------------------------------------------------------------------------
// Autocomplete API
// -------------------------------------------------------------------------
Expand All @@ -204,6 +209,14 @@ public async Task Autocomplete_ShortQuery_ReturnsEmptyTermList()
body["terms"]!.AsArray().Count.ShouldBe(0);
}

[Fact]
public async Task Autocomplete_MissingQuery_Returns400()
{
// Query validation happens before the job is looked up, so no fixture is needed.
var response = await ctx.SearchClient.GetAsync("/autocomplete/v1/no/such/id");
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
}

[Fact]
public async Task Autocomplete_MatchingPrefix_ReturnsSuggestions()
{
Expand Down
Loading