Skip to content
Open
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
@@ -0,0 +1,55 @@
using System.Net;
using System.Text;
using Azure.Search.Documents.Indexes.Models;
using Xunit;

namespace AzureSearchEmulator.IntegrationTests;

/// <summary>
/// Azure accepts a document batch on both <c>docs/search.index</c> and <c>docs/index</c>; the
/// Go SDK posts to the latter. Both spellings, in both the path and OData-key forms, must reach
/// the same handler.
/// </summary>
public class DocumentIndexRouteIntegrationTests(EmulatorFactory factory)
: IClassFixture<EmulatorFactory>
{
[Theory]
[InlineData("indexes/{0}/docs/index")]
[InlineData("indexes('{0}')/docs/index")]
[InlineData("indexes/{0}/docs/search.index")]
public async Task IndexDocuments_AcceptsBatchOnEitherRoute(string routeFormat)
{
var indexName = "docs-index-route-" + Guid.NewGuid().ToString("N")[..8];
var cancellationToken = TestContext.Current.CancellationToken;

var indexClient = factory.CreateSearchIndexClient();
await indexClient.CreateIndexAsync(
new SearchIndex(indexName)
{
Fields =
{
new SearchField("id", SearchFieldDataType.String) { IsKey = true },
new SearchField("name", SearchFieldDataType.String) { IsSearchable = true },
}
},
cancellationToken);

using var http = factory.CreateHttpClient();

var response = await http.PostAsync(
string.Format(routeFormat, indexName) + "?api-version=2024-07-01",
new StringContent(
"""{ "value": [ { "@search.action": "upload", "id": "1", "name": "hello" } ] }""",
Encoding.UTF8,
"application/json"),
cancellationToken);

Assert.Equal(HttpStatusCode.OK, response.StatusCode);

var searchClient = factory.CreateSearchClient(indexName);
var document = await searchClient.GetDocumentAsync<Dictionary<string, object>>("1", cancellationToken: cancellationToken);
Assert.Equal("hello", document.Value["name"].ToString());

await indexClient.DeleteIndexAsync(indexName, cancellationToken);
}
}
6 changes: 6 additions & 0 deletions AzureSearchEmulator/Controllers/DocumentIndexingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ public class DocumentIndexingController(
/// </summary>
private const int MaxLoggedBodyLength = 4096;

/// <remarks>
/// Azure accepts both <c>docs/search.index</c> and the shorter <c>docs/index</c> for a batch;
/// the Go and Java SDKs post to the latter.
/// </remarks>
[HttpPost]
[Route("indexes({indexKey})/docs/search.index")]
[Route("indexes/{indexKey}/docs/search.index")]
[Route("indexes({indexKey})/docs/index")]
[Route("indexes/{indexKey}/docs/index")]
public async Task<IActionResult> IndexDocuments(string indexKey)
{
// Strip quotes that may be captured from OData-style URLs
Expand Down