diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Utils/SearchClientExtensions.cs b/clients/algoliasearch-client-csharp/algoliasearch/Utils/SearchClientExtensions.cs index c9ba2b3fd0a..03c2b6813bf 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Utils/SearchClientExtensions.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Utils/SearchClientExtensions.cs @@ -176,6 +176,18 @@ public partial interface ISearchClient /// List SaveObjects(string indexName, IEnumerable objects, bool waitForTasks = false, int batchSize = 1000, RequestOptions options = null, CancellationToken cancellationToken = default) where T : class; + /// + /// Helper: Saves the given array of objects in the given index. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objects in it. + /// + /// The index in which to perform the request. + /// The list of `objects` to store in the given Algolia `indexName`. + /// Add extra http header or query parameters to Algolia. + /// Cancellation Token to cancel the request. + /// + Task> SaveObjectsAsync(string indexName, IEnumerable objects, RequestOptions options, CancellationToken cancellationToken = default) where T : class; + /// + List SaveObjects(string indexName, IEnumerable objects, RequestOptions options, CancellationToken cancellationToken = default) where T : class; + /// /// Helper: Deletes every records for the given objectIDs. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objectIDs in it. /// @@ -598,6 +610,19 @@ public List SaveObjects(string indexName, IEnumerable objec CancellationToken cancellationToken = default) where T : class => AsyncHelper.RunSync(() => SaveObjectsAsync(indexName, objects, waitForTasks, batchSize, options, cancellationToken)); + /// + public async Task> SaveObjectsAsync(string indexName, IEnumerable objects, + RequestOptions options, + CancellationToken cancellationToken = default) where T : class + { + return await SaveObjectsAsync(indexName, objects, false, 1000, options, cancellationToken).ConfigureAwait(false); + } + + /// + public List SaveObjects(string indexName, IEnumerable objects, RequestOptions options, + CancellationToken cancellationToken = default) where T : class => + AsyncHelper.RunSync(() => SaveObjectsAsync(indexName, objects, options, cancellationToken)); + /// public async Task> DeleteObjectsAsync(string indexName, IEnumerable objectIDs, bool waitForTasks = false, diff --git a/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCTSGenerator.java b/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCTSGenerator.java index fc6886e2cdf..4df0bfa9860 100644 --- a/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCTSGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCTSGenerator.java @@ -100,6 +100,7 @@ protected Builder addMustacheLambdas() { lambdas.put("escapeDollar", new EscapeDollarLambda()); lambdas.put("escapeQuotes", new EscapeQuotesLambda()); lambdas.put("escapeSlash", new EscapeSlashLambda()); + lambdas.put("escapeJSON", new EscapeJSONLambda()); lambdas.put("replaceBacktick", new ReplaceBacktickLambda()); return lambdas; diff --git a/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeJSONLambda.java b/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeJSONLambda.java new file mode 100644 index 00000000000..8e2c5a4325c --- /dev/null +++ b/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeJSONLambda.java @@ -0,0 +1,15 @@ +package com.algolia.codegen.cts.lambda; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; +import java.io.IOException; +import java.io.Writer; + +public class EscapeJSONLambda implements Mustache.Lambda { + + @Override + public void execute(Template.Fragment fragment, Writer writer) throws IOException { + String text = fragment.execute(); + writer.write(text.replace("\\", "\\\\").replace("\"", "\\\"")); + } +} diff --git a/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeQuotesLambda.java b/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeQuotesLambda.java index 439a3b46a86..57537f1ce6e 100644 --- a/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeQuotesLambda.java +++ b/generators/src/main/java/com/algolia/codegen/cts/lambda/EscapeQuotesLambda.java @@ -10,6 +10,7 @@ public class EscapeQuotesLambda implements Mustache.Lambda { @Override public void execute(Template.Fragment fragment, Writer writer) throws IOException { String text = fragment.execute(); - writer.write(text.replace("\"", "\\\"")); + // replaces all occurrences of " that are not preceded by a backslash with \" + writer.write(text.replaceAll("(? traverseParams( } testOutput.put("key", paramName); - testOutput.put("useAnonymousKey", !paramName.matches("(.*)_[0-9]$") && depth != 0); + testOutput.put("useAnonymousKey", !paramName.matches("(.*)_[0-9]+$") && depth != 0); testOutput.put("parent", parent); testOutput.put("isRoot", "".equals(parent)); testOutput.put("objectName", getObjectNameForLanguage(baseType)); @@ -191,7 +191,7 @@ private Map traverseParams( private Map traverseParamsWithoutSpec(String paramName, Object param, String parent, int depth) throws CTSException { Map testOutput = createDefaultOutput(); testOutput.put("key", paramName); - testOutput.put("useAnonymousKey", !paramName.matches("(.*)_[0-9]$") && depth != 0); + testOutput.put("useAnonymousKey", !paramName.matches("(.*)_[0-9]+$") && depth != 0); testOutput.put("parent", parent); testOutput.put("isRoot", "".equals(parent)); // try to infer the type @@ -326,7 +326,7 @@ private void handleModel( } else { while (current.getItems() != null) { current = current.getItems(); - typeName += "Of" + getTypeName(current); + typeName += "Of" + Helpers.capitalize(getTypeName(current)); isList = true; } } @@ -492,11 +492,16 @@ private void handlePrimitive(Object param, Map testOutput, IJson } private String getTypeName(IJsonSchemaValidationProperties param) { + String typeName = param.getDataType(); if (param instanceof CodegenModel parameter) { - return parameter.classname; + typeName = parameter.classname; } - return param.getDataType(); + if (language.equals("scala") && typeName.equals("List")) { + typeName = "Seq"; + } + + return typeName; } private boolean isString(IJsonSchemaValidationProperties param) { @@ -592,6 +597,8 @@ private String inferDataType(Object param, CodegenParameter spec, Map models, Map } } stepOut.put("match", paramsType.enhanceParameter(step.expected.match)); + } else if (!step.type.equals("createClient")) { + stepOut.put("useEchoRequester", false); } steps.add(stepOut); } diff --git a/playground/javascript/node/search.ts b/playground/javascript/node/search.ts index 5dccd08cc2f..fd0bc7d1b37 100644 --- a/playground/javascript/node/search.ts +++ b/playground/javascript/node/search.ts @@ -17,15 +17,13 @@ console.log('version', apiClientVersion, 'requests', requests); async function testSearch() { try { - const res = await client.search({ - requests: - [ - { indexName: 'foo', hitsPerPage: 2 } - ] - }); - - // @ts-ignore - console.log(`[OK]`, res.results[0].hits); + const req = await client.setSettings({ + indexName: 'theIndexName', + indexSettings: { distinct: true }, + }) + + + console.log(`[OK]`, req); } catch (e: any) { // Instance of if (e instanceof ApiError) { diff --git a/scripts/cts/testServer/algoliaMock.ts b/scripts/cts/testServer/algoliaMock.ts new file mode 100644 index 00000000000..09ece03e807 --- /dev/null +++ b/scripts/cts/testServer/algoliaMock.ts @@ -0,0 +1,24 @@ +import type { Server } from 'http'; + +import type { Express, Request, Response } from 'express'; + +import { setupServer } from './index.ts'; + +// Checks that the client sends a different API key after the first request. +function addRoutes(app: Express): void { + app.post('/1/indexes/:indexName/batch', (req: Request, res: Response) => { + res.json({ + taskID: 333, + objectIDs: ['1', '2'], + }); + }); + app.get('/1/indexes/:indexName/task/:taskID', (req, res) => { + res.json({ + status: 'published', + }); + }); +} + +export function algoliaMockServer(): Promise { + return setupServer('algoliaMock', 6686, addRoutes); +} diff --git a/scripts/cts/testServer/index.ts b/scripts/cts/testServer/index.ts index 26f81212ddf..6f4ec3d1f23 100644 --- a/scripts/cts/testServer/index.ts +++ b/scripts/cts/testServer/index.ts @@ -7,6 +7,7 @@ import { createSpinner } from '../../spinners.ts'; import type { CTSType } from '../runCts.ts'; import { expect } from 'chai'; +import { algoliaMockServer } from './algoliaMock.ts'; import { apiKeyServer } from './apiKey.ts'; import { benchmarkServer } from './benchmark.ts'; import { chunkWrapperServer } from './chunkWrapper.ts'; @@ -31,6 +32,7 @@ export async function startTestServer(suites: Record): Promise chunkWrapperServer(), waitForApiKeyServer(), apiKeyServer(), + algoliaMockServer(), ); } if (suites.benchmark) { diff --git a/templates/csharp/tests/generateInnerParams.mustache b/templates/csharp/tests/generateInnerParams.mustache index f5ee0ae3080..3cd63690f96 100644 --- a/templates/csharp/tests/generateInnerParams.mustache +++ b/templates/csharp/tests/generateInnerParams.mustache @@ -5,7 +5,7 @@ {{{value}}} {{/isVerbatim}} {{#isString}} - "{{#lambda.escapeQuotes}}{{#lambda.escapeSlash}}{{{value}}}{{/lambda.escapeSlash}}{{/lambda.escapeQuotes}}" + "{{#lambda.escapeJSON}}{{{value}}}{{/lambda.escapeJSON}}" {{/isString}} {{#isInteger}} {{{value}}} diff --git a/templates/csharp/tests/requests/requests.mustache b/templates/csharp/tests/requests/requests.mustache index 835ca835c68..aaaa4e72c9c 100644 --- a/templates/csharp/tests/requests/requests.mustache +++ b/templates/csharp/tests/requests/requests.mustache @@ -46,7 +46,7 @@ private readonly {{client}} client; Assert.Equal("{{{path}}}",req.Path); Assert.Equal("{{{method}}}",req.Method.ToString()); {{#body}} - JsonAssert.EqualOverrideDefault("{{#lambda.escapeQuotes}}{{{body}}}{{/lambda.escapeQuotes}}", req.Body, new JsonDiffConfig(false)); + JsonAssert.EqualOverrideDefault("{{#lambda.escapeJSON}}{{{body}}}{{/lambda.escapeJSON}}", req.Body, new JsonDiffConfig(false)); {{/body}} {{^body}} {{#assertNullBody}} diff --git a/templates/dart/tests/param_value.mustache b/templates/dart/tests/param_value.mustache index edaefdca86e..9fadc305476 100644 --- a/templates/dart/tests/param_value.mustache +++ b/templates/dart/tests/param_value.mustache @@ -1,6 +1,6 @@ {{#isNull}}empty(){{/isNull}} {{#isVerbatim}}{{{value}}}{{/isVerbatim}} -{{#isString}}"{{#lambda.escapeDollar}}{{{value}}}{{/lambda.escapeDollar}}"{{/isString}} +{{#isString}}"{{#lambda.escapeQuotes}}{{#lambda.escapeDollar}}{{{value}}}{{/lambda.escapeDollar}}{{/lambda.escapeQuotes}}"{{/isString}} {{#isNumber}}{{{value}}}{{/isNumber}} {{#isBoolean}}{{{value}}}{{/isBoolean}} {{#isEnum}}{{{objectName}}}.fromJson("{{value}}"){{/isEnum}} diff --git a/templates/dart/tests/requests/requests.mustache b/templates/dart/tests/requests/requests.mustache index 6d795d6c022..36abb6e3fca 100644 --- a/templates/dart/tests/requests/requests.mustache +++ b/templates/dart/tests/requests/requests.mustache @@ -53,7 +53,7 @@ void main() { expectParams(request.queryParameters, """{{{.}}}"""); {{/queryParameters}} {{#body}} - expectBody(request.body, """{{{.}}}"""); + expectBody(request.body, """{{#lambda.escapeSlash}}{{{.}}}{{/lambda.escapeSlash}}"""); {{/body}} {{^body}} {{#assertNullBody}} diff --git a/templates/go/api.mustache b/templates/go/api.mustache index 168ab83d0fa..df16992debd 100644 --- a/templates/go/api.mustache +++ b/templates/go/api.mustache @@ -571,4 +571,4 @@ func (c *APIClient) {{nickname}}({{#hasParams}}r {{#structPrefix}}{{&classname}} {{#isSearchClient}} {{> search_helpers}} -{{/isSearchClient}} +{{/isSearchClient}} \ No newline at end of file diff --git a/templates/go/search_helpers.mustache b/templates/go/search_helpers.mustache index 9c529f14e99..03fc060b264 100644 --- a/templates/go/search_helpers.mustache +++ b/templates/go/search_helpers.mustache @@ -1,5 +1,6 @@ func CreateIterable[T any](execute func(*T, error) (*T, error), validate func(*T, error) (bool, error), opts ...IterableOption) (*T, error) { conf := config{ + headerParams: map[string]string{}, maxRetries: -1, timeout: func(count int) time.Duration { return 0 * time.Millisecond @@ -204,7 +205,7 @@ func (c *APIClient) WaitForApiKey( operation ApiKeyOperation, opts ...WaitForApiKeyOption, ) (*GetApiKeyResponse, error) { - conf := config{} + conf := config{headerParams: map[string]string{}} for _, opt := range opts { opt.apply(&conf) @@ -572,6 +573,7 @@ Helper: Replaces object content of all the given objects according to their resp */ func (c *APIClient) PartialUpdateObjects(indexName string, objects []map[string]any, opts ...PartialUpdateObjectsOption) ([]BatchResponse, error) { conf := config{ + headerParams: map[string]string{}, createIfNotExists: true, } @@ -602,6 +604,7 @@ ChunkedBatch chunks the given `objects` list in subset of 1000 elements max in o */ func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, action Action, opts ...ChunkedBatchOption) ([]BatchResponse, error) { conf := config{ + headerParams: map[string]string{}, waitForTasks: false, batchSize: 1000, } @@ -653,6 +656,7 @@ func (c *APIClient) ReplaceAllObjects(indexName string, objects []map[string]any tmpIndexName := fmt.Sprintf("%s_tmp_%d", indexName, time.Now().UnixNano()) conf := config{ + headerParams: map[string]string{}, scopes: []ScopeType{SCOPE_TYPE_SETTINGS, SCOPE_TYPE_RULES, SCOPE_TYPE_SYNONYMS}, } diff --git a/templates/go/tests/generateInnerParams.mustache b/templates/go/tests/generateInnerParams.mustache index 5a2879d967f..7a4ff09f866 100644 --- a/templates/go/tests/generateInnerParams.mustache +++ b/templates/go/tests/generateInnerParams.mustache @@ -1,3 +1,3 @@ -{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isHelper}}{{#goFunctionalParam}}{{clientPrefix}}.With{{#lambda.pascalcase}}{{key}}{{/lambda.pascalcase}}({{/goFunctionalParam}}{{/isHelper}}{{#isNull}}{{#inClientTest}}tests.ZeroValue[{{#isNullObject}}*{{clientPrefix}}.{{/isNullObject}}{{objectName}}](){{/inClientTest}}{{^inClientTest}}nil{{/inClientTest}}{{/isNull}}{{#isString}}"{{{value}}}"{{/isString}}{{#isInteger}}{{{value}}}{{/isInteger}}{{#isLong}}{{{value}}}{{/isLong}}{{#isDouble}}{{{value}}}{{/isDouble}}{{#isBoolean}}{{{value}}}{{/isBoolean}}{{#isEnum}}{{clientPrefix}}.{{objectName}}("{{{value}}}"){{/isEnum}}{{#isArray}} +{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isHelper}}{{#goFunctionalParam}}{{clientPrefix}}.With{{#lambda.pascalcase}}{{key}}{{/lambda.pascalcase}}({{/goFunctionalParam}}{{/isHelper}}{{#isNull}}{{#inClientTest}}tests.ZeroValue[{{#isNullObject}}*{{clientPrefix}}.{{/isNullObject}}{{objectName}}](){{/inClientTest}}{{^inClientTest}}nil{{/inClientTest}}{{/isNull}}{{#isString}}"{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}"{{/isString}}{{#isInteger}}{{{value}}}{{/isInteger}}{{#isLong}}{{{value}}}{{/isLong}}{{#isDouble}}{{{value}}}{{/isDouble}}{{#isBoolean}}{{{value}}}{{/isBoolean}}{{#isEnum}}{{clientPrefix}}.{{objectName}}("{{{value}}}"){{/isEnum}}{{#isArray}} {{> tests/arrayType}}{{^value.isEmpty}}{ {{#value}}{{#isObject}}*{{/isObject}}{{#oneOfModel}}{{^isObject}}*{{/isObject}}{{/oneOfModel}}{{> tests/generateParams}},{{/value}} }{{/value.isEmpty}}{{/isArray}}{{#isObject}} {{clientPrefix}}.NewEmpty{{objectName}}(){{#value}}{{#isAdditionalProperty}}.SetAdditionalProperty("{{{key}}}", {{> tests/generateParams}}){{/isAdditionalProperty}}{{^isAdditionalProperty}}.Set{{#lambda.pascalcase}}{{{key}}}{{/lambda.pascalcase}}({{> tests/generateParams}}){{/isAdditionalProperty}}{{/value}}{{/isObject}}{{#isFreeFormObject}}{{#isAnyType}}map[string]any{ {{#value}}{{#entrySet}}"{{{key}}}": "{{{value}}}",{{/entrySet}}{{/value}} }{{/isAnyType}}{{^isAnyType}}{{> tests/mapType}}{ {{#value}}"{{{key}}}": {{#oneOfModel}}{{^isObject}}*{{/isObject}}{{/oneOfModel}}{{#isObject}}*{{/isObject}}{{> tests/generateParams}},{{/value}} }{{/isAnyType}}{{/isFreeFormObject}}{{#isHelper}}{{#goFunctionalParam}}){{/goFunctionalParam}}{{/isHelper}} \ No newline at end of file diff --git a/templates/go/tests/method.mustache b/templates/go/tests/method.mustache index 6edb2abdcd2..d2819805aef 100644 --- a/templates/go/tests/method.mustache +++ b/templates/go/tests/method.mustache @@ -1,14 +1,2 @@ client.{{#lambda.titlecase}}{{method}}{{/lambda.titlecase}}({{#hasParams}}{{^isHelper}}client.NewApi{{#lambda.titlecase}}{{method}}{{/lambda.titlecase}}Request({{/isHelper}} - {{#parametersWithDataType}}{{#required}}{{> tests/generateParams}},{{/required}}{{/parametersWithDataType}} -{{^isHelper}}){{#parametersWithDataType}}{{^required}}.With{{#lambda.pascalcase}}{{{key}}}{{/lambda.pascalcase}}({{> tests/generateParams}}){{/required}}{{/parametersWithDataType}}{{/isHelper}}{{#isHelper}}{{#parametersWithDataType}}{{^required}}{{> tests/generateParams}},{{/required}}{{/parametersWithDataType}}{{/isHelper}}{{/hasParams}}{{#requestOptions}}{{#hasParams}},{{/hasParams}} -{{#queryParameters.parametersWithDataType}}{{clientPrefix}}.WithQueryParam("{{{key}}}", {{> tests/generateInnerParams}}),{{/queryParameters.parametersWithDataType}}{{#headers.parametersWithDataType}}{{clientPrefix}}.WithHeaderParam("{{{key}}}", {{> tests/generateInnerParams}}),{{/headers.parametersWithDataType}} -{{#timeouts.read}} -{{clientPrefix}}.WithReadTimeout({{.}} * time.Millisecond), -{{/timeouts.read}} -{{#timeouts.write}} -{{clientPrefix}}.WithWriteTimeout({{.}} * time.Millisecond), -{{/timeouts.write}} -{{#timeouts.connect}} -{{clientPrefix}}.WithConnectTimeout({{.}} * time.Millisecond), -{{/timeouts.connect}} -{{/requestOptions}}) \ No newline at end of file + {{#parametersWithDataType}}{{#required}}{{> tests/generateParams}},{{/required}}{{/parametersWithDataType}} {{^isHelper}}){{#parametersWithDataType}}{{^required}}.With{{#lambda.pascalcase}}{{{key}}}{{/lambda.pascalcase}}({{> tests/generateParams}}){{#-last}},{{/-last}}{{/required}}{{/parametersWithDataType}}{{/isHelper}}{{#isHelper}}{{#parametersWithDataType}}{{^required}}{{> tests/generateParams}},{{/required}}{{/parametersWithDataType}}{{/isHelper}}{{/hasParams}}{{#requestOptions}}{{#queryParameters.parametersWithDataType}}{{clientPrefix}}.WithQueryParam("{{{key}}}", {{> tests/generateInnerParams}}),{{/queryParameters.parametersWithDataType}}{{#headers.parametersWithDataType}}{{clientPrefix}}.WithHeaderParam("{{{key}}}", {{> tests/generateInnerParams}}),{{/headers.parametersWithDataType}} {{#timeouts.read}} ,{{clientPrefix}}.WithReadTimeout({{.}} * time.Millisecond), {{/timeouts.read}} {{#timeouts.write}} ,{{clientPrefix}}.WithWriteTimeout({{.}} * time.Millisecond), {{/timeouts.write}} {{#timeouts.connect}} ,{{clientPrefix}}.WithConnectTimeout({{.}} * time.Millisecond), {{/timeouts.connect}} {{/requestOptions}}) \ No newline at end of file diff --git a/templates/java/api_helpers.mustache b/templates/java/api_helpers.mustache index b2ef12fa2cc..86f93b7ea50 100644 --- a/templates/java/api_helpers.mustache +++ b/templates/java/api_helpers.mustache @@ -1026,7 +1026,7 @@ public ReplaceAllObjectsResponse replaceAllObjects( public String generateSecuredApiKey(@Nonnull String parentApiKey, @Nonnull SecuredApiKeyRestrictions restrictions) throws Exception { Map restrictionsMap = new HashMap<>(); if (restrictions.getFilters() != null) restrictionsMap.put("filters", StringUtils.paramToString(restrictions.getFilters())); - if (restrictions.getValidUntil() != 0) restrictionsMap.put("validUntil", StringUtils.paramToString(restrictions.getValidUntil())); + if (restrictions.getValidUntil() != null && restrictions.getValidUntil() != 0) restrictionsMap.put("validUntil", StringUtils.paramToString(restrictions.getValidUntil())); if (restrictions.getRestrictIndices() != null) restrictionsMap.put( "restrictIndices", StringUtils.paramToString(restrictions.getRestrictIndices()) diff --git a/templates/java/tests/generateInnerParams.mustache b/templates/java/tests/generateInnerParams.mustache index a6f9604b419..81796c232b2 100644 --- a/templates/java/tests/generateInnerParams.mustache +++ b/templates/java/tests/generateInnerParams.mustache @@ -5,7 +5,7 @@ {{{value}}} {{/isVerbatim}} {{#isString}} - "{{#lambda.escapeQuotes}}{{#lambda.escapeSlash}}{{{value}}}{{/lambda.escapeSlash}}{{/lambda.escapeQuotes}}" + "{{#lambda.escapeJSON}}{{{value}}}{{/lambda.escapeJSON}}" {{/isString}} {{#isInteger}} {{{value}}} diff --git a/templates/java/tests/generateParams.mustache b/templates/java/tests/generateParams.mustache index 6ee9804264e..ca2daa1d5db 100644 --- a/templates/java/tests/generateParams.mustache +++ b/templates/java/tests/generateParams.mustache @@ -1 +1 @@ -{{#oneOfModel}}{{^hasWrapper}}{{> tests/generateInnerParams}}{{/hasWrapper}}{{#hasWrapper}}{{{parentClassName}}}.of{{#x-one-of-explicit-name}}{{{type}}}{{/x-one-of-explicit-name}}({{> tests/generateInnerParams}}){{/hasWrapper}}{{/oneOfModel}}{{^oneOfModel}}{{> tests/generateInnerParams}}{{/oneOfModel}} \ No newline at end of file +{{#oneOfModel}}{{^hasWrapper}}{{> tests/generateInnerParams}}{{/hasWrapper}}{{#hasWrapper}}{{{parentClassName}}}.of{{#lambda.pascalcase}}{{#x-one-of-explicit-name}}{{{type}}}{{/x-one-of-explicit-name}}{{/lambda.pascalcase}}({{> tests/generateInnerParams}}){{/hasWrapper}}{{/oneOfModel}}{{^oneOfModel}}{{> tests/generateInnerParams}}{{/oneOfModel}} \ No newline at end of file diff --git a/templates/java/tests/requests/requests.mustache b/templates/java/tests/requests/requests.mustache index 90e6d265ad2..f04b4de1bee 100644 --- a/templates/java/tests/requests/requests.mustache +++ b/templates/java/tests/requests/requests.mustache @@ -55,7 +55,7 @@ class {{client}}RequestsTests { assertEquals("{{{path}}}", req.path); assertEquals("{{{method}}}", req.method); {{#body}} - assertDoesNotThrow(() -> JSONAssert.assertEquals("{{#lambda.escapeQuotes}}{{{body}}}{{/lambda.escapeQuotes}}", req.body, JSONCompareMode.STRICT)); + assertDoesNotThrow(() -> JSONAssert.assertEquals("{{#lambda.escapeJSON}}{{{body}}}{{/lambda.escapeJSON}}", req.body, JSONCompareMode.STRICT)); {{/body}} {{^body}} {{#assertNullBody}} diff --git a/templates/kotlin/tests/param_value.mustache b/templates/kotlin/tests/param_value.mustache index 59eff2c2108..a8c0b12c5e5 100644 --- a/templates/kotlin/tests/param_value.mustache +++ b/templates/kotlin/tests/param_value.mustache @@ -1 +1 @@ -{{#isNull}}empty(){{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}{{#oneOfModel}}{{{parentClassName}}}.of("{{{value}}}"){{/oneOfModel}}{{^oneOfModel}}"{{#lambda.escapeQuotes}}{{#lambda.escapeSlash}}{{{value}}}{{/lambda.escapeSlash}}{{/lambda.escapeQuotes}}"{{/oneOfModel}}{{/isString}}{{#isInteger}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isInteger}}{{#isLong}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}L){{/oneOfModel}}{{^oneOfModel}}{{{value}}}L{{/oneOfModel}}{{/isLong}}{{#isDouble}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isDouble}}{{#isBoolean}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isBoolean}}{{#isEnum}}{{{objectName}}}.entries.first { it.value == "{{{value}}}" }{{/isEnum}}{{#isArray}}{{> tests/param_list}}{{/isArray}}{{#isObject}}{{> tests/param_object}}{{/isObject}}{{#isFreeFormObject}}{{#isSimpleObject}}{{> tests/param_json_object}}{{/isSimpleObject}}{{^isSimpleObject}}{{#isAnyType}}{{> tests/param_json_any}}{{/isAnyType}}{{^isAnyType}}{{> tests/param_map}}{{/isAnyType}}{{/isSimpleObject}}{{/isFreeFormObject}} \ No newline at end of file +{{#isNull}}empty(){{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}{{#oneOfModel}}{{{parentClassName}}}.of("{{{value}}}"){{/oneOfModel}}{{^oneOfModel}}"{{#lambda.escapeJSON}}{{{value}}}{{/lambda.escapeJSON}}"{{/oneOfModel}}{{/isString}}{{#isInteger}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isInteger}}{{#isLong}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}L){{/oneOfModel}}{{^oneOfModel}}{{{value}}}L{{/oneOfModel}}{{/isLong}}{{#isDouble}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isDouble}}{{#isBoolean}}{{#oneOfModel}}{{{parentClassName}}}.of({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isBoolean}}{{#isEnum}}{{{objectName}}}.entries.first { it.value == "{{{value}}}" }{{/isEnum}}{{#isArray}}{{> tests/param_list}}{{/isArray}}{{#isObject}}{{> tests/param_object}}{{/isObject}}{{#isFreeFormObject}}{{#isSimpleObject}}{{> tests/param_json_object}}{{/isSimpleObject}}{{^isSimpleObject}}{{#isAnyType}}{{> tests/param_json_any}}{{/isAnyType}}{{^isAnyType}}{{> tests/param_map}}{{/isAnyType}}{{/isSimpleObject}}{{/isFreeFormObject}} \ No newline at end of file diff --git a/templates/php/tests/generateParams.mustache b/templates/php/tests/generateParams.mustache index eae982d3916..392c15af04e 100644 --- a/templates/php/tests/generateParams.mustache +++ b/templates/php/tests/generateParams.mustache @@ -6,7 +6,7 @@ {{{value}}} {{/isVerbatim}} {{#isString}} - "{{#lambda.escapeSlash}}{{{value}}}{{/lambda.escapeSlash}}", + "{{#lambda.escapeJSON}}{{{value}}}{{/lambda.escapeJSON}}", {{/isString}} {{#isEnum}} "{{{value}}}", diff --git a/templates/python/tests/client/tests.mustache b/templates/python/tests/client/tests.mustache index 9424b53b2c0..61d8bf2cad3 100644 --- a/templates/python/tests/client/tests.mustache +++ b/templates/python/tests/client/tests.mustache @@ -19,7 +19,7 @@ {{#times}}for _ in range(0, {{.}}): {{/times}}{{#dynamicTemplate}}{{/dynamicTemplate}} {{#testUserAgent}} - regex_user_agent = compile("{{#lambda.escapeSlash}}{{{match.value}}}{{/lambda.escapeSlash}}") + regex_user_agent = compile("{{#lambda.escapeJSON}}{{{match.value}}}{{/lambda.escapeJSON}}") assert regex_user_agent.match(_req.headers.get("user-agent")) is not None {{/testUserAgent}} {{#testTimeouts}} diff --git a/templates/python/tests/generateInnerParams.mustache b/templates/python/tests/generateInnerParams.mustache index d474216df2f..c435f617575 100644 --- a/templates/python/tests/generateInnerParams.mustache +++ b/templates/python/tests/generateInnerParams.mustache @@ -1 +1 @@ -{{#isNull}} None {{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}} "{{#lambda.escapeSlash}}{{{value}}}{{/lambda.escapeSlash}}" {{/isString}} {{#isInteger}} {{{value}}} {{/isInteger}} {{#isLong}} {{{value}}} {{/isLong}} {{#isDouble}} {{{value}}} {{/isDouble}} {{#isBoolean}} {{#lambda.titlecase}}{{{value}}}{{/lambda.titlecase}} {{/isBoolean}} {{#isEnum}} "{{{value}}}" {{/isEnum}} {{#isArray}} [ {{#value}}{{> tests/generateParams}}{{/value}} ] {{/isArray}} {{#isObject}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isObject}} {{#isFreeFormObject}} {{#isAnyType}} { {{#value}}{{#entrySet}}"{{{key}}}":"{{{value}}}"{{^-last}},{{/-last}}{{/entrySet}}{{/value}} } {{/isAnyType}} {{^isAnyType}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isAnyType}} {{/isFreeFormObject}} \ No newline at end of file +{{#isNull}} None {{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}} "{{#lambda.escapeJSON}}{{{value}}}{{/lambda.escapeJSON}}" {{/isString}} {{#isInteger}} {{{value}}} {{/isInteger}} {{#isLong}} {{{value}}} {{/isLong}} {{#isDouble}} {{{value}}} {{/isDouble}} {{#isBoolean}} {{#lambda.titlecase}}{{{value}}}{{/lambda.titlecase}} {{/isBoolean}} {{#isEnum}} "{{{value}}}" {{/isEnum}} {{#isArray}} [ {{#value}}{{> tests/generateParams}}{{/value}} ] {{/isArray}} {{#isObject}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isObject}} {{#isFreeFormObject}} {{#isAnyType}} { {{#value}}{{#entrySet}}"{{{key}}}":"{{{value}}}"{{^-last}},{{/-last}}{{/entrySet}}{{/value}} } {{/isAnyType}} {{^isAnyType}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isAnyType}} {{/isFreeFormObject}} \ No newline at end of file diff --git a/templates/python/tests/method.mustache b/templates/python/tests/method.mustache index e776b9f1119..ee3c2df46d2 100644 --- a/templates/python/tests/method.mustache +++ b/templates/python/tests/method.mustache @@ -1 +1 @@ -{{^isSyncClient}}await {{/isSyncClient}}_client.{{#lambda.snakecase}}{{{method}}}{{/lambda.snakecase}}{{#useEchoRequester}}_with_http_info{{/useEchoRequester}}({{#parametersWithDataType}}{{> tests/generateParams}}{{/parametersWithDataType}}{{#hasRequestOptions}} request_options={ {{#requestOptions.headers.parameters}}"headers":loads("""{{{.}}}"""),{{/requestOptions.headers.parameters}}{{#requestOptions.queryParameters.parameters}}"query_parameters":loads("""{{{.}}}"""),{{/requestOptions.queryParameters.parameters}}{{#requestOptions.timeouts.parameters}}"timeouts":loads("""{{{.}}}"""),{{/requestOptions.timeouts.parameters}} }{{/hasRequestOptions}}) \ No newline at end of file +{{^isSyncClient}}await {{/isSyncClient}}_client.{{#lambda.snakecase}}{{{method}}}{{/lambda.snakecase}}{{^isHelper}}{{#useEchoRequester}}_with_http_info{{/useEchoRequester}}{{/isHelper}}({{#parametersWithDataType}}{{> tests/generateParams}}{{/parametersWithDataType}}{{#hasRequestOptions}} request_options={ {{#requestOptions.headers.parameters}}"headers":loads("""{{{.}}}"""),{{/requestOptions.headers.parameters}}{{#requestOptions.queryParameters.parameters}}"query_parameters":loads("""{{{.}}}"""),{{/requestOptions.queryParameters.parameters}}{{#requestOptions.timeouts.parameters}}"timeouts":loads("""{{{.}}}"""),{{/requestOptions.timeouts.parameters}} }{{/hasRequestOptions}}) \ No newline at end of file diff --git a/templates/python/tests/requests/requests.mustache b/templates/python/tests/requests/requests.mustache index bbc00eba9ab..6136783dd95 100644 --- a/templates/python/tests/requests/requests.mustache +++ b/templates/python/tests/requests/requests.mustache @@ -30,7 +30,7 @@ class Test{{#lambda.pascalcase}}{{{client}}}{{/lambda.pascalcase}}{{#isSyncClien assert _req.query_parameters.items() == {{#queryParameters}}{{{.}}}{{/queryParameters}}{{^queryParameters}}{}{{/queryParameters}}.items() assert _req.headers.items() >= {{#headers}}{{{.}}}{{/headers}}{{^headers}}{}{{/headers}}.items() {{#body}} - assert loads(_req.data) == loads("""{{{.}}}""") + assert loads(_req.data) == loads("""{{#lambda.escapeSlash}}{{{.}}}{{/lambda.escapeSlash}}""") {{/body}} {{^body}} {{#assertNullBody}} diff --git a/templates/ruby/tests/generateInnerParams.mustache b/templates/ruby/tests/generateInnerParams.mustache index baa4d75522c..4616d52da67 100644 --- a/templates/ruby/tests/generateInnerParams.mustache +++ b/templates/ruby/tests/generateInnerParams.mustache @@ -1 +1 @@ -{{#isNull}}nil {{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}"{{{value}}}" {{/isString}}{{#isInteger}}{{{value}}} {{/isInteger}}{{#isLong}}{{{value}}} {{/isLong}}{{#isDouble}}{{{value}}} {{/isDouble}}{{#isBoolean}}{{{value}}} {{/isBoolean}} {{#isEnum}}'{{{value}}}' {{/isEnum}}{{#isArray}} [ {{#value}}{{> tests/generateParams}}{{/value}} ] {{/isArray}}{{#isObject}} Algolia::{{{modelModule}}}::{{{objectName}}}.new({{#value}}{{> tests/generateParams}}{{/value}}) {{/isObject}}{{#isFreeFormObject}} {{#isAnyType}} { {{#value}}{{#entrySet}}'{{{key}}}':"{{{value}}}"{{^-last}},{{/-last}}{{/entrySet}}{{/value}} } {{/isAnyType}} {{^isAnyType}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isAnyType}} {{/isFreeFormObject}} \ No newline at end of file +{{#isNull}}nil {{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}"{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}" {{/isString}}{{#isInteger}}{{{value}}} {{/isInteger}}{{#isLong}}{{{value}}} {{/isLong}}{{#isDouble}}{{{value}}} {{/isDouble}}{{#isBoolean}}{{{value}}} {{/isBoolean}} {{#isEnum}}'{{{value}}}' {{/isEnum}}{{#isArray}} [ {{#value}}{{> tests/generateParams}}{{/value}} ] {{/isArray}}{{#isObject}} Algolia::{{{modelModule}}}::{{{objectName}}}.new({{#value}}{{> tests/generateParams}}{{/value}}) {{/isObject}}{{#isFreeFormObject}} {{#isAnyType}} { {{#value}}{{#entrySet}}'{{{key}}}':"{{{value}}}"{{^-last}},{{/-last}}{{/entrySet}}{{/value}} } {{/isAnyType}} {{^isAnyType}} { {{#value}}{{> tests/generateParams}}{{/value}} } {{/isAnyType}} {{/isFreeFormObject}} \ No newline at end of file diff --git a/templates/ruby/tests/method.mustache b/templates/ruby/tests/method.mustache index d400d9f3d73..5db383086d3 100644 --- a/templates/ruby/tests/method.mustache +++ b/templates/ruby/tests/method.mustache @@ -1 +1 @@ -client.{{#lambda.snakecase}}{{method}}{{/lambda.snakecase}}{{#useEchoRequester}}_with_http_info{{/useEchoRequester}}{{#returnsBoolean}}?{{/returnsBoolean}}({{#parametersWithDataType}}{{> tests/generateParams}}{{/parametersWithDataType}}{{#hasRequestOptions}}{ {{#requestOptions.headers.parameters}}:header_params => JSON.parse('{{{.}}}', :symbolize_names => true),{{/requestOptions.headers.parameters}}{{#requestOptions.queryParameters.parameters}}:query_params => JSON.parse('{{{.}}}', :symbolize_names => true),{{/requestOptions.queryParameters.parameters}}{{#requestOptions.timeouts.connect}}:connect_timeout => {{{.}}},{{/requestOptions.timeouts.connect}}{{#requestOptions.timeouts.write}}:timeout => {{{.}}},{{/requestOptions.timeouts.write}} }{{/hasRequestOptions}}) \ No newline at end of file +client.{{#lambda.snakecase}}{{method}}{{/lambda.snakecase}}{{^isHelper}}{{#useEchoRequester}}_with_http_info{{/useEchoRequester}}{{/isHelper}}{{#returnsBoolean}}?{{/returnsBoolean}}({{#parametersWithDataType}}{{> tests/generateParams}}{{/parametersWithDataType}}{{#hasRequestOptions}}{ {{#requestOptions.headers.parameters}}:header_params => JSON.parse('{{{.}}}', :symbolize_names => true),{{/requestOptions.headers.parameters}}{{#requestOptions.queryParameters.parameters}}:query_params => JSON.parse('{{{.}}}', :symbolize_names => true),{{/requestOptions.queryParameters.parameters}}{{#requestOptions.timeouts.connect}}:connect_timeout => {{{.}}},{{/requestOptions.timeouts.connect}}{{#requestOptions.timeouts.write}}:timeout => {{{.}}},{{/requestOptions.timeouts.write}} }{{/hasRequestOptions}}) \ No newline at end of file diff --git a/templates/scala/tests/param_list.mustache b/templates/scala/tests/param_list.mustache index 7d92dc9e49e..157f4f714d5 100644 --- a/templates/scala/tests/param_list.mustache +++ b/templates/scala/tests/param_list.mustache @@ -1 +1 @@ -{{#oneOfModel}}{{{parentClassName}}}{{#x-one-of-explicit-name}}{{{type}}}{{/x-one-of-explicit-name}}(Seq({{#value}}{{> tests/param_value}}{{^-last}},{{/-last}}{{/value}})){{/oneOfModel}}{{^oneOfModel}}Seq({{#value}}{{> tests/param_value}}{{^-last}},{{/-last}}{{/value}}){{/oneOfModel}} \ No newline at end of file +{{#oneOfModel}}{{^x-one-of-explicit-name}}{{{parentClassName}}}{{/x-one-of-explicit-name}}{{#x-one-of-explicit-name}}{{{type}}}{{/x-one-of-explicit-name}}(Seq({{#value}}{{> tests/param_value}}{{^-last}},{{/-last}}{{/value}})){{/oneOfModel}}{{^oneOfModel}}Seq({{#value}}{{> tests/param_value}}{{^-last}},{{/-last}}{{/value}}){{/oneOfModel}} \ No newline at end of file diff --git a/templates/scala/tests/param_value.mustache b/templates/scala/tests/param_value.mustache index 3aa0254b077..bf8532d6ace 100644 --- a/templates/scala/tests/param_value.mustache +++ b/templates/scala/tests/param_value.mustache @@ -1 +1 @@ -{{#isNull}}null{{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}{{#oneOfModel}}{{{parentClassName}}}("{{{value}}}"){{/oneOfModel}}{{^oneOfModel}}"{{{value}}}"{{/oneOfModel}}{{/isString}}{{#isInteger}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isInteger}}{{#isLong}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}L){{/oneOfModel}}{{^oneOfModel}}{{{value}}}L{{/oneOfModel}}{{/isLong}}{{#isDouble}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isDouble}}{{#isBoolean}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isBoolean}}{{#isEnum}}{{{objectName}}}.withName("{{{value}}}"){{/isEnum}}{{#isArray}}{{> tests/param_list}}{{/isArray}}{{#isObject}}{{> tests/param_object}}{{/isObject}}{{#isFreeFormObject}}{{#isSimpleObject}}{{> tests/param_json_object}}{{/isSimpleObject}}{{^isSimpleObject}}{{#isAnyType}}{{> tests/param_json_any}}{{/isAnyType}}{{^isAnyType}}{{> tests/param_map}}{{/isAnyType}}{{/isSimpleObject}}{{/isFreeFormObject}} \ No newline at end of file +{{#isNull}}null{{/isNull}}{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isString}}{{#oneOfModel}}{{{parentClassName}}}("{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}"){{/oneOfModel}}{{^oneOfModel}}"{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}"{{/oneOfModel}}{{/isString}}{{#isInteger}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isInteger}}{{#isLong}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}L){{/oneOfModel}}{{^oneOfModel}}{{{value}}}L{{/oneOfModel}}{{/isLong}}{{#isDouble}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isDouble}}{{#isBoolean}}{{#oneOfModel}}{{{parentClassName}}}({{{value}}}){{/oneOfModel}}{{^oneOfModel}}{{{value}}}{{/oneOfModel}}{{/isBoolean}}{{#isEnum}}{{{objectName}}}.withName("{{{value}}}"){{/isEnum}}{{#isArray}}{{> tests/param_list}}{{/isArray}}{{#isObject}}{{> tests/param_object}}{{/isObject}}{{#isFreeFormObject}}{{#isSimpleObject}}{{> tests/param_json_object}}{{/isSimpleObject}}{{^isSimpleObject}}{{#isAnyType}}{{> tests/param_json_any}}{{/isAnyType}}{{^isAnyType}}{{> tests/param_map}}{{/isAnyType}}{{/isSimpleObject}}{{/isFreeFormObject}} \ No newline at end of file diff --git a/templates/scala/tests/requests/requestOptionsParams.mustache b/templates/scala/tests/requests/requestOptionsParams.mustache index c5f5f7643c1..91702623d85 100644 --- a/templates/scala/tests/requests/requestOptionsParams.mustache +++ b/templates/scala/tests/requests/requestOptionsParams.mustache @@ -2,7 +2,7 @@ null {{/isNull}} {{#isString}} - "{{{value}}}" + "{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}" {{/isString}} {{#isInteger}} {{{value}}} diff --git a/templates/swift/tests/client/method.mustache b/templates/swift/tests/client/method.mustache index 414f0ed90f3..490cd58536e 100644 --- a/templates/swift/tests/client/method.mustache +++ b/templates/swift/tests/client/method.mustache @@ -1,4 +1,5 @@ -{{#hasResponse}}let response{{#isGeneric}}: Response<{{{returnType}}}>{{/isGeneric}} = {{/hasResponse}}{{> tests/method}} +{{#hasResponse}}let response{{#isGeneric}}: Response<{{{returnType}}}>{{/isGeneric}} = {{> tests/method}}{{/hasResponse}} +{{^hasResponse}}let _{{#isGeneric}}: Response<{{{returnType}}}>{{/isGeneric}} = {{> tests/method}}{{/hasResponse}} {{^isHelper}} {{^isBenchmark}} let responseBodyData = try XCTUnwrap(response.bodyData) diff --git a/templates/swift/tests/client/tests.mustache b/templates/swift/tests/client/tests.mustache index 21ada3789dd..d9072620a09 100644 --- a/templates/swift/tests/client/tests.mustache +++ b/templates/swift/tests/client/tests.mustache @@ -29,7 +29,7 @@ {{/shouldScope}} {{#dynamicTemplate}}{{/dynamicTemplate}} {{#testUserAgent}} - let pattern = "{{#lambda.escapeSlash}}{{{match.value}}}{{/lambda.escapeSlash}}" + let pattern = "{{#lambda.escapeJSON}}{{{match.value}}}{{/lambda.escapeJSON}}" XCTAssertNoThrow(try regexMatch(echoResponse.algoliaAgent, against: pattern), "Expected " + echoResponse.algoliaAgent + " to match the following regex: " + pattern); {{/testUserAgent}} {{#testTimeouts}} diff --git a/templates/swift/tests/e2e/e2e.mustache b/templates/swift/tests/e2e/e2e.mustache index ad9ef581661..a40ec002903 100644 --- a/templates/swift/tests/e2e/e2e.mustache +++ b/templates/swift/tests/e2e/e2e.mustache @@ -66,7 +66,7 @@ final class {{client}}RequestsTestsE2E: XCTestCase { let responseBody = try XCTUnwrap(response.body) let responseBodyData = try CodableHelper.jsonEncoder.encode(responseBody) - let expectedBodyData = try XCTUnwrap("{{#lambda.escapeQuotes}}{{{body}}}{{/lambda.escapeQuotes}}".data(using: .utf8)) + let expectedBodyData = try XCTUnwrap("{{#lambda.escapeJSON}}{{{body}}}{{/lambda.escapeJSON}}".data(using: .utf8)) XCTLenientAssertEqual(received: responseBodyData, expected: expectedBodyData) {{/body}} diff --git a/templates/swift/tests/paramKey.mustache b/templates/swift/tests/paramKey.mustache index b30a802a25f..e1171e3ab80 100644 --- a/templates/swift/tests/paramKey.mustache +++ b/templates/swift/tests/paramKey.mustache @@ -1 +1 @@ -{{#isRoot}}{{#lambda.camelcase}}{{key}}{{/lambda.camelcase}}: {{/isRoot}}{{^isRoot}}{{#useAnonymousKey}}{{#isParentFreeFormObject}}"{{/isParentFreeFormObject}}{{#isAdditionalProperty}}"{{/isAdditionalProperty}}{{#lambda.camelcase}}{{key}}{{/lambda.camelcase}}{{#isParentFreeFormObject}}"{{/isParentFreeFormObject}}{{#isAdditionalProperty}}"{{/isAdditionalProperty}}: {{/useAnonymousKey}}{{/isRoot}} \ No newline at end of file +{{#isRoot}}{{#lambda.camelcase}}{{key}}{{/lambda.camelcase}}: {{/isRoot}}{{^isRoot}}{{#useAnonymousKey}}{{#isParentFreeFormObject}}"{{/isParentFreeFormObject}}{{#isAdditionalProperty}}"{{/isAdditionalProperty}}{{#isParentFreeFormObject}}{{key}}{{/isParentFreeFormObject}}{{^isParentFreeFormObject}}{{#lambda.camelcase}}{{key}}{{/lambda.camelcase}}{{/isParentFreeFormObject}}{{#isParentFreeFormObject}}"{{/isParentFreeFormObject}}{{#isAdditionalProperty}}"{{/isAdditionalProperty}}: {{/useAnonymousKey}}{{/isRoot}} \ No newline at end of file diff --git a/templates/swift/tests/paramValue.mustache b/templates/swift/tests/paramValue.mustache index cf53215d082..90462b8d176 100644 --- a/templates/swift/tests/paramValue.mustache +++ b/templates/swift/tests/paramValue.mustache @@ -1 +1 @@ -{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isObject}}{{objectName}}({{^hasAdditionalProperties}}{{#value}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{/value}}{{/hasAdditionalProperties}}{{#hasAdditionalProperties}}from: [{{#value}}"{{key}}": AnyCodable({{> tests/paramValue }}){{^-last}}, {{/-last}}{{/value}}]{{/hasAdditionalProperties}}){{/isObject}}{{#isString}}{{#isAnyType}}AnyCodable({{/isAnyType}}"{{{value}}}"{{#isAnyType}}){{/isAnyType}}{{/isString}}{{#isNumber}}{{#isLong}}Int64({{/isLong}}{{{value}}}{{#isLong}}){{/isLong}}{{/isNumber}}{{#isBoolean}}{{{value}}}{{/isBoolean}}{{#isEnum}}{{objectName}}.{{#lambda.identifier}}{{#lambda.camelcase}}{{value}}{{/lambda.camelcase}}{{/lambda.identifier}}{{/isEnum}}{{#isArray}}[{{#value}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{/value}}]{{/isArray}}{{#isMap}}Map[{{{.}}}]{{/isMap}}{{#isFreeFormObject}}{{#isAnyType}}[{{#value}}{{#entrySet}}"{{key}}": "{{{value}}}"{{/entrySet}}{{/value}}]{{/isAnyType}}{{^isAnyType}}{{^value}}[String: AnyCodable](){{/value}}{{#value}}{{#-first}}[{{/-first}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{#-last}}]{{/-last}}{{/value}}{{/isAnyType}}{{/isFreeFormObject}}{{#isNull}}{{#inClientTest}}TestNull{{{objectName}}}(){{/inClientTest}}{{/isNull}} \ No newline at end of file +{{#isVerbatim}}{{{value}}}{{/isVerbatim}}{{#isObject}}{{objectName}}({{^hasAdditionalProperties}}{{#value}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{/value}}{{/hasAdditionalProperties}}{{#hasAdditionalProperties}}from: [{{#value}}"{{key}}": AnyCodable({{> tests/paramValue }}){{^-last}}, {{/-last}}{{/value}}]{{/hasAdditionalProperties}}){{/isObject}}{{#isString}}{{#isAnyType}}AnyCodable({{/isAnyType}}"{{#lambda.escapeQuotes}}{{{value}}}{{/lambda.escapeQuotes}}"{{#isAnyType}}){{/isAnyType}}{{/isString}}{{#isNumber}}{{#isLong}}Int64({{/isLong}}{{{value}}}{{#isLong}}){{/isLong}}{{/isNumber}}{{#isBoolean}}{{{value}}}{{/isBoolean}}{{#isEnum}}{{objectName}}.{{#lambda.identifier}}{{#lambda.camelcase}}{{value}}{{/lambda.camelcase}}{{/lambda.identifier}}{{/isEnum}}{{#isArray}}[{{#value}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{/value}}]{{/isArray}}{{#isMap}}Map[{{{.}}}]{{/isMap}}{{#isFreeFormObject}}{{#isAnyType}}[{{#value}}{{#entrySet}}"{{key}}": "{{{value}}}"{{/entrySet}}{{/value}}]{{/isAnyType}}{{^isAnyType}}{{^value}}[String: AnyCodable](){{/value}}{{#value}}{{#-first}}[{{/-first}}{{> tests/generateParams}}{{^-last}}, {{/-last}}{{#-last}}]{{/-last}}{{/value}}{{/isAnyType}}{{/isFreeFormObject}}{{#isNull}}{{#inClientTest}}TestNull{{{objectName}}}(){{/inClientTest}}{{/isNull}} \ No newline at end of file diff --git a/templates/swift/tests/requests/requests.mustache b/templates/swift/tests/requests/requests.mustache index 862a447a646..17b0d2ba77f 100644 --- a/templates/swift/tests/requests/requests.mustache +++ b/templates/swift/tests/requests/requests.mustache @@ -30,7 +30,7 @@ final class {{client}}RequestsTests: XCTestCase { let echoResponseBodyData = try XCTUnwrap(echoResponse.originalBodyData) let echoResponseBodyJSON = try XCTUnwrap(echoResponseBodyData.jsonString) - let expectedBodyData = "{{#lambda.escapeQuotes}}{{{body}}}{{/lambda.escapeQuotes}}".data(using: .utf8) + let expectedBodyData = "{{#lambda.escapeJSON}}{{{body}}}{{/lambda.escapeJSON}}".data(using: .utf8) let expectedBodyJSON = try XCTUnwrap(expectedBodyData?.jsonString) XCTAssertEqual(echoResponseBodyJSON, expectedBodyJSON) diff --git a/tests/CTS/client/search/generateSecuredApiKey.json b/tests/CTS/client/search/generateSecuredApiKey.json index 046c0e13c13..a914508a0cf 100644 --- a/tests/CTS/client/search/generateSecuredApiKey.json +++ b/tests/CTS/client/search/generateSecuredApiKey.json @@ -1,6 +1,6 @@ [ { - "testName": "generate secured api key basic", + "testName": "api key basic", "steps": [ { "type": "method", @@ -22,7 +22,7 @@ ] }, { - "testName": "generate secured api key with searchParams", + "testName": "with searchParams", "steps": [ { "type": "method", @@ -57,5 +57,50 @@ } } ] + }, + { + "testName": "with filters", + "steps": [ + { + "type": "method", + "method": "generateSecuredApiKey", + "parameters": { + "parentApiKey": "2640659426d5107b6e47d75db9cbaef8", + "restrictions": { + "filters": "user:user42 AND user:public AND (visible_by:John OR visible_by:group/Finance)" + } + } + } + ] + }, + { + "testName": "with visible_by filter", + "steps": [ + { + "type": "method", + "method": "generateSecuredApiKey", + "parameters": { + "parentApiKey": "2640659426d5107b6e47d75db9cbaef8", + "restrictions": { + "filters": "visible_by:group/Finance" + } + } + } + ] + }, + { + "testName": "with userID", + "steps": [ + { + "type": "method", + "method": "generateSecuredApiKey", + "parameters": { + "parentApiKey": "2640659426d5107b6e47d75db9cbaef8", + "restrictions": { + "userToken": "user42" + } + } + } + ] } ] diff --git a/tests/CTS/client/search/saveObjects.json b/tests/CTS/client/search/saveObjects.json index 49445d7dbd3..c74b00fdf2e 100644 --- a/tests/CTS/client/search/saveObjects.json +++ b/tests/CTS/client/search/saveObjects.json @@ -93,5 +93,78 @@ } } ] + }, + { + "testName": "saveObjectsPlaylist", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "test-app-id", + "apiKey": "test-api-key", + "customHosts": [ + { + "port": 6686 + } + ] + } + }, + { + "type": "method", + "method": "saveObjects", + "parameters": { + "indexName": "playlists", + "objects": [ + { + "objectID": "1", + "visibility": "public", + "name": "Hot 100 Billboard Charts", + "playlistId": "d3e8e8f3-0a4f-4b7d-9b6b-7e8f4e8e3a0f", + "createdAt": "1500240452" + } + ] + } + } + ] + }, + { + "testName": "saveObjectsPublicUser", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "test-app-id", + "apiKey": "test-api-key", + "customHosts": [ + { + "port": 6686 + } + ] + } + }, + { + "type": "method", + "method": "saveObjects", + "parameters": { + "indexName": "playlists", + "objects": [ + { + "objectID": "1", + "visibility": "public", + "name": "Hot 100 Billboard Charts", + "playlistId": "d3e8e8f3-0a4f-4b7d-9b6b-7e8f4e8e3a0f", + "createdAt": "1500240452" + } + ] + }, + "requestOptions": { + "headers": { + "X-Algolia-User-ID": "*" + } + } + } + ] } ] diff --git a/tests/CTS/requests/search/assignUserId.json b/tests/CTS/requests/search/assignUserId.json index a2a99688e29..6eab923bb82 100644 --- a/tests/CTS/requests/search/assignUserId.json +++ b/tests/CTS/requests/search/assignUserId.json @@ -1,19 +1,20 @@ [ { + "testName": "simple", "parameters": { - "xAlgoliaUserID": "userID", + "xAlgoliaUserID": "user42", "assignUserIdParams": { - "cluster": "theCluster" + "cluster": "d4242-eu" } }, "request": { "path": "/1/clusters/mapping", "method": "POST", "body": { - "cluster": "theCluster" + "cluster": "d4242-eu" }, "headers": { - "x-algolia-user-id": "userID" + "x-algolia-user-id": "user42" } } }, diff --git a/tests/CTS/requests/search/listIndices.json b/tests/CTS/requests/search/listIndices.json index 2825d5054a1..53a64863e51 100644 --- a/tests/CTS/requests/search/listIndices.json +++ b/tests/CTS/requests/search/listIndices.json @@ -1,6 +1,7 @@ [ { "testName": "listIndices with minimal parameters", + "isSnippet": true, "parameters": {}, "request": { "path": "/1/indexes", diff --git a/tests/CTS/requests/search/partialUpdateObject.json b/tests/CTS/requests/search/partialUpdateObject.json index 589298e30a9..9bc401334f0 100644 --- a/tests/CTS/requests/search/partialUpdateObject.json +++ b/tests/CTS/requests/search/partialUpdateObject.json @@ -77,6 +77,7 @@ }, { "testName": "Partial update with a new value for an object attribute", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "objectID": "uniqueID", @@ -95,5 +96,23 @@ } } } + }, + { + "testName": "with visible_by filter", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "objectID": "uniqueID", + "attributesToUpdate": { + "visible_by": ["Angela", "group/Finance", "group/Shareholders" ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/uniqueID/partial", + "method": "POST", + "body": { + "visible_by": ["Angela", "group/Finance", "group/Shareholders" ] + } + } } ] diff --git a/tests/CTS/requests/search/saveRule.json b/tests/CTS/requests/search/saveRule.json index 9ec0e86095e..8cd629e6d40 100644 --- a/tests/CTS/requests/search/saveRule.json +++ b/tests/CTS/requests/search/saveRule.json @@ -178,5 +178,801 @@ "forwardToReplicas": "true" } } + }, + { + "testName": "b2b catalog", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "article-rule", + "rule": { + "objectID": "article-rule", + "conditions": [ + { + "pattern": "article", + "anchoring": "startsWith" + } + ], + "consequence": { + "params": { + "query": { + "edits": [{ + "type": "remove", + "delete": "article" + }] + }, + "restrictSearchableAttributes": ["title", "book_id"] + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/article-rule", + "method": "PUT", + "body": { + "objectID": "article-rule", + "conditions": [ + { + "pattern": "article", + "anchoring": "startsWith" + } + ], + "consequence": { + "params": { + "query": { + "edits": [{ + "type": "remove", + "delete": "article" + }] + }, + "restrictSearchableAttributes": ["title", "book_id"] + } + } + } + } + }, + { + "testName": "merchandising and promoting", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "director-rule", + "rule": { + "objectID": "director-rule", + "conditions": [ + { + "pattern": "{facet:director} director", + "anchoring": "contains" + } + ], + "consequence": { + "params": { + "restrictSearchableAttributes": ["title", "book_id"], + "automaticFacetFilters": [{ + "facet":"director" + }], + "query": { + "edits": [{ + "type": "remove", + "delete": "director" + }] + } + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/director-rule", + "method": "PUT", + "body": { + "objectID": "director-rule", + "conditions": [ + { + "pattern": "{facet:director} director", + "anchoring": "contains" + } + ], + "consequence": { + "params": { + "restrictSearchableAttributes": ["title", "book_id"], + "automaticFacetFilters": [{ + "facet":"director" + }], + "query": { + "edits": [{ + "type": "remove", + "delete": "director" + }] + } + } + } + } + } + }, + { + "testName": "harry potter", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "harry-potter-rule", + "rule": { + "objectID": "harry-potter-rule", + "conditions": [ + { + "pattern": "harry potter", + "anchoring": "contains" + } + ], + "consequence": { + "userData": { + "promo_content": "20% OFF on all Harry Potter books!" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/harry-potter-rule", + "method": "PUT", + "body": { + "objectID": "harry-potter-rule", + "conditions": [ + { + "pattern": "harry potter", + "anchoring": "contains" + } + ], + "consequence": { + "userData": { + "promo_content": "20% OFF on all Harry Potter books!" + } + } + } + } + }, + { + "testName": "merchandising empty query", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "clearance-category-filter", + "rule": { + "objectID": "clearance-category-filter", + "conditions": [ + { + "pattern": "", + "anchoring": "is", + "context": "landing" + } + ], + "consequence": { + "params": { + "optionalFilters": "clearance:true" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/clearance-category-filter", + "method": "PUT", + "body": { + "objectID": "clearance-category-filter", + "conditions": [ + { + "pattern": "", + "anchoring": "is", + "context": "landing" + } + ], + "consequence": { + "params": { + "optionalFilters": "clearance:true" + } + } + } + } + }, + { + "testName": "redirect", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "redirect-help-rule", + "rule": { + "objectID": "redirect-help-rule", + "conditions": [ + { + "pattern": "help", + "anchoring": "contains" + } + ], + "consequence": { + "userData": { + "redirect": "https://www.algolia.com/support" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/redirect-help-rule", + "method": "PUT", + "body": { + "objectID": "redirect-help-rule", + "conditions": [ + { + "pattern": "help", + "anchoring": "contains" + } + ], + "consequence": { + "userData": { + "redirect": "https://www.algolia.com/support" + } + } + } + } + }, + { + "testName": "promote some results over others", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "tomato-fruit", + "rule": { + "objectID": "tomato-fruit", + "conditions": [{ + "pattern": "tomato", + "anchoring": "contains" + }], + "consequence": { + "params": { + "optionalFilters": "food_group:fruit" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/tomato-fruit", + "method": "PUT", + "body": { + "objectID": "tomato-fruit", + "conditions": [{ + "pattern": "tomato", + "anchoring": "contains" + }], + "consequence": { + "params": { + "optionalFilters": "food_group:fruit" + } + } + } + } + }, + { + "testName": "promote several hits", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "Promote-Apple-Newest", + "rule": { + "objectID": "Promote-Apple-Newest", + "conditions": [{ + "pattern": "apple", + "anchoring": "is" + }], + "consequence": { + "promote": [ + { + "objectIDs": ["iPhone-12345", "watch-123"], + "position": 0 + } + ] + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/Promote-Apple-Newest", + "method": "PUT", + "body": { + "objectID": "Promote-Apple-Newest", + "conditions": [{ + "pattern": "apple", + "anchoring": "is" + }], + "consequence": { + "promote": [ + { + "objectIDs": ["iPhone-12345", "watch-123"], + "position": 0 + } + ] + } + } + } + }, + { + "testName": "promote newest release", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "Promote-iPhone-X", + "rule": { + "objectID": "Promote-iPhone-X", + "conditions": [{ + "pattern": "iPhone", + "anchoring": "contains" + }], + "consequence": { + "promote": [ + { + "objectID": "iPhone-12345", + "position": 0 + } + ] + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/Promote-iPhone-X", + "method": "PUT", + "body": { + "objectID": "Promote-iPhone-X", + "conditions": [{ + "pattern": "iPhone", + "anchoring": "contains" + }], + "consequence": { + "promote": [ + { + "objectID": "iPhone-12345", + "position": 0 + } + ] + } + } + } + }, + { + "testName": "promote single item", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "promote-harry-potter-box-set", + "rule": { + "objectID": "promote-harry-potter-box-set", + "conditions": [{ + "pattern": "Harry Potter", + "anchoring": "contains" + }], + "consequence": { + "promote": [{ + "objectID": "HP-12345", + "position": 0 + }] + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/promote-harry-potter-box-set", + "method": "PUT", + "body": { + "objectID": "promote-harry-potter-box-set", + "conditions": [{ + "pattern": "Harry Potter", + "anchoring": "contains" + }], + "consequence": { + "promote": [ + { + "objectID": "HP-12345", + "position": 0 + } + ] + } + } + } + }, + { + "testName": "limit search results", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "article-rule", + "rule": { + "objectID": "article-rule", + "conditions": [{ + "pattern": "article", + "anchoring": "startsWith" + }], + "consequence": { + "params": { + "query": { + "edits": [{ + "type": "remove", + "delete": "article" + }] + }, + "restrictSearchableAttributes": ["title", "book_id"] + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/article-rule", + "method": "PUT", + "body": { + "objectID": "article-rule", + "conditions": [{ + "pattern": "article", + "anchoring": "startsWith" + }], + "consequence": { + "params": { + "query": { + "edits": [{ + "type": "remove", + "delete": "article" + }] + }, + "restrictSearchableAttributes": ["title", "book_id"] + } + } + } + } + }, + { + "testName": "query match", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "tagged-brand-rule", + "rule": { + "conditions": [{ + "pattern": "brand: {facet:brand}", + "anchoring": "contains", + "alternatives": false + }], + "consequence": { + "params": { + "automaticFacetFilters": [{ + "facet":"brand" + }], + "query": { + "remove": ["brand:", "{facet:brand}"] + } + } + }, + "description": "filter on brand: {brand}", + "objectID": "tagged-brand-rule" + } + }, + "request": { + "path": "/1/indexes/indexName/rules/tagged-brand-rule", + "method": "PUT", + "body": { + "conditions": [{ + "pattern": "brand: {facet:brand}", + "anchoring": "contains", + "alternatives": false + }], + "consequence": { + "params": { + "automaticFacetFilters": [{ + "facet":"brand" + }], + "query": { + "remove": ["brand:", "{facet:brand}"] + } + } + }, + "description": "filter on brand: {brand}", + "objectID": "tagged-brand-rule" + } + } + }, + { + "testName": "dynamic filtering", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "color-facets", + "rule": { + "objectID": "color-facets", + "conditions": [{ + "pattern": "{facet:color}" + }], + "consequence": { + "params": { + "automaticFacetFilters": [{ + "facet":"color" + }] + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/color-facets", + "method": "PUT", + "body": { + "objectID": "color-facets", + "conditions": [{ + "pattern": "{facet:color}" + }], + "consequence": { + "params": { + "automaticFacetFilters": [{ + "facet":"color" + }] + } + } + } + } + }, + { + "testName": "hide hits", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "hide-12345", + "rule": { + "objectID": "hide-12345", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "hide": [{ + "objectID": "to-hide-12345" + }] + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/hide-12345", + "method": "PUT", + "body": { + "objectID": "hide-12345", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "hide": [{ + "objectID": "to-hide-12345" + }] + } + } + } + }, + { + "testName": "one rule per facet", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "red-color", + "rule": { + "objectID": "red-color", + "conditions": [{ + "pattern": "red", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["red"] + }, + "filters": "color:red" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/red-color", + "method": "PUT", + "body": { + "objectID": "red-color", + "conditions": [{ + "pattern": "red", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["red"] + }, + "filters": "color:red" + } + } + } + } + }, + { + "testName": "numerical filters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "cheap", + "rule": { + "objectID": "cheap", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["cheap"] + }, + "filters": "price < 10" + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/cheap", + "method": "PUT", + "body": { + "objectID": "cheap", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["cheap"] + }, + "filters": "price < 10" + } + } + } + } + }, + { + "testName": "negative filters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "gluten-free-rule", + "rule": { + "objectID": "gluten-free-rule", + "conditions": [{ + "pattern": "gluten-free", + "anchoring": "contains" + }], + "consequence": { + "params": { + "filters": "NOT allergens:gluten", + "query": { + "edits": [ + { + "type": "remove", + "delete": "gluten-free" + } + ] + } + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/gluten-free-rule", + "method": "PUT", + "body": { + "objectID": "gluten-free-rule", + "conditions": [{ + "pattern": "gluten-free", + "anchoring": "contains" + }], + "consequence": { + "params": { + "filters": "NOT allergens:gluten", + "query": { + "edits": [ + { + "type": "remove", + "delete": "gluten-free" + } + ] + } + } + } + } + } + }, + { + "testName": "positive filters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "diet-rule", + "rule": { + "objectID": "diet-rule", + "conditions": [{ + "pattern": "diet", + "anchoring": "contains" + }], + "consequence": { + "params": { + "filters": "'low-carb' OR 'low-fat'", + "query": { + "edits": [ + { + "type": "remove", + "delete": "diet" + } + ] + } + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/diet-rule", + "method": "PUT", + "body": { + "objectID": "diet-rule", + "conditions": [{ + "pattern": "diet", + "anchoring": "contains" + }], + "consequence": { + "params": { + "filters": "'low-carb' OR 'low-fat'", + "query": { + "edits": [ + { + "type": "remove", + "delete": "diet" + } + ] + } + } + } + } + } + }, + { + "testName": "conditionless", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "objectID": "diet-rule", + "rule": { + "objectID": "diet-rule", + "consequence": { + "params": { + "filters": "'low-carb' OR 'low-fat'", + "query": { + "edits": [ + { + "type": "remove", + "delete": "diet" + } + ] + } + } + } + } + }, + "request": { + "path": "/1/indexes/indexName/rules/diet-rule", + "method": "PUT", + "body": { + "objectID": "diet-rule", + "consequence": { + "params": { + "filters": "'low-carb' OR 'low-fat'", + "query": { + "edits": [ + { + "type": "remove", + "delete": "diet" + } + ] + } + } + } + } + } } ] diff --git a/tests/CTS/requests/search/saveRules.json b/tests/CTS/requests/search/saveRules.json index 416e8168eae..d0e59a5a251 100644 --- a/tests/CTS/requests/search/saveRules.json +++ b/tests/CTS/requests/search/saveRules.json @@ -220,5 +220,141 @@ "clearExistingRules": "true" } } + }, + { + "testName": "dynamic filtering", + "parameters": { + "indexName": "", + "rules": [ + { + "objectID": "toaster", + "conditions": [{ + "pattern": "toaster", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["toaster"] + }, + "filters": "product_type:toaster" + } + } + }, + { + "objectID": "cheap", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["cheap"] + }, + "filters": "price < 15" + } + } + } + ] + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/rules/batch", + "method": "POST", + "body": [ + { + "objectID": "toaster", + "conditions": [{ + "pattern": "toaster", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["toaster"] + }, + "filters": "product_type:toaster" + } + } + }, + { + "objectID": "cheap", + "conditions": [{ + "pattern": "cheap", + "anchoring": "contains" + }], + "consequence": { + "params": { + "query": { + "remove": ["cheap"] + }, + "filters": "price < 15" + } + } + } + ] + } + }, + { + "testName": "enhance search results", + "parameters": { + "indexName": "", + "rules": [ + { + "objectID": "country", + "conditions": [{ + "pattern": "{facet:country}", + "anchoring": "contains" + }], + "consequence": { + "params": { + "aroundLatLngViaIP": false + } + } + }, + { + "objectID": "city", + "conditions": [{ + "pattern": "{facet:city}", + "anchoring": "contains" + }], + "consequence": { + "params": { + "aroundLatLngViaIP": false + } + } + } + ] + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/rules/batch", + "method": "POST", + "body": [ + { + "objectID": "country", + "conditions": [{ + "pattern": "{facet:country}", + "anchoring": "contains" + }], + "consequence": { + "params": { + "aroundLatLngViaIP": false + } + } + }, + { + "objectID": "city", + "conditions": [{ + "pattern": "{facet:city}", + "anchoring": "contains" + }], + "consequence": { + "params": { + "aroundLatLngViaIP": false + } + } + } + ] + } } ] diff --git a/tests/CTS/requests/search/searchSingleIndex.json b/tests/CTS/requests/search/searchSingleIndex.json index 34fae33da6a..25efe5ea591 100644 --- a/tests/CTS/requests/search/searchSingleIndex.json +++ b/tests/CTS/requests/search/searchSingleIndex.json @@ -126,5 +126,657 @@ ] } } + }, + { + "testName": "query", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "query": "phone" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "query": "phone" + } + } + }, + { + "testName": "filters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "country:US AND price.gross < 2.0" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "country:US AND price.gross < 2.0" + } + } + }, + { + "testName": "distinct", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "distinct": true + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "distinct": true + } + } + }, + { + "testName": "filtersNumeric", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "price < 10" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "price < 10" + } + } + }, + { + "testName": "filtersTimestamp", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "NOT date_timestamp:1514764800 TO 1546300799" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "NOT date_timestamp:1514764800 TO 1546300799" + } + } + }, + { + "testName": "filtersSumOrFiltersScoresFalse", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "(company:Google OR company:Amazon OR company:Facebook)", + "sumOrFiltersScores": false + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "(company:Google OR company:Amazon OR company:Facebook)", + "sumOrFiltersScores": false + } + } + }, + { + "testName": "filtersSumOrFiltersScoresTrue", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "(company:Google OR company:Amazon OR company:Facebook)", + "sumOrFiltersScores": true + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "(company:Google OR company:Amazon OR company:Facebook)", + "sumOrFiltersScores": true + } + } + }, + { + "testName": "filtersStephenKing", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "author:\"Stephen King\"" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "author:\"Stephen King\"" + } + } + }, + { + "testName": "filtersNotTags", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "NOT _tags:non-fiction" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "NOT _tags:non-fiction" + } + } + }, + { + "testName": "facetFiltersList", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "facetFilters": [ + "publisher:Penguin", + [ + "author:Stephen King", + "genre:Horror" + ] + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "facetFilters": [ + "publisher:Penguin", + [ + "author:Stephen King", + "genre:Horror" + ] + ] + } + } + }, + { + "testName": "facetFiltersNeg", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "facetFilters": "category:-Ebook" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "facetFilters": "category:-Ebook" + } + } + }, + { + "testName": "filtersAndFacetFilters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "(author:\"Stephen King\" OR genre:\"Horror\")", + "facetFilters": [ + "publisher:Penguin" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "(author:\"Stephen King\" OR genre:\"Horror\")", + "facetFilters": [ + "publisher:Penguin" + ] + } + } + }, + { + "testName": "aroundLatLng", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "aroundLatLng": "40.71, -74.01" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "aroundLatLng": "40.71, -74.01" + } + } + }, + { + "testName": "aroundLatLngViaIP", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "aroundLatLngViaIP": true + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "aroundLatLngViaIP": true + } + } + }, + { + "testName": "aroundRadius", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "aroundLatLng": "40.71, -74.01", + "aroundRadius": 1000000 + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "aroundLatLng": "40.71, -74.01", + "aroundRadius": 1000000 + } + } + }, + { + "testName": "insideBoundingBox", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "insideBoundingBox": [ + [ + 49.067996905313834, + 65.73828125, + 25.905859247243498, + 128.8046875 + ] + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "insideBoundingBox": [ + [ + 49.067996905313834, + 65.73828125, + 25.905859247243498, + 128.8046875 + ] + ] + } + } + }, + { + "testName": "insidePolygon", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "insidePolygon": [ + [ + 42.01, + -124.31, + 48.835509470063045, + -124.40453125000005, + 45.01082951668149, + -65.95726562500005, + 31.247243545293433, + -81.06578125000004, + 25.924152577235226, + -97.68234374999997, + 32.300311895879545, + -117.54828125 + ] + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "insidePolygon": [ + [ + 42.01, + -124.31, + 48.835509470063045, + -124.40453125000005, + 45.01082951668149, + -65.95726562500005, + 31.247243545293433, + -81.06578125000004, + 25.924152577235226, + -97.68234374999997, + 32.300311895879545, + -117.54828125 + ] + ] + } + } + }, + { + "testName": "insidePolygon", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "insidePolygon": [ + [ + 42.01, + -124.31, + 48.835509470063045, + -124.40453125000005, + 45.01082951668149, + -65.95726562500005, + 31.247243545293433, + -81.06578125000004, + 25.924152577235226, + -97.68234374999997, + 32.300311895879545, + -117.54828125 + ] + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "insidePolygon": [ + [ + 42.01, + -124.31, + 48.835509470063045, + -124.40453125000005, + 45.01082951668149, + -65.95726562500005, + 31.247243545293433, + -81.06578125000004, + 25.924152577235226, + -97.68234374999997, + 32.300311895879545, + -117.54828125 + ] + ] + } + } + }, + { + "testName": "optionalFilters", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "optionalFilters": [ + "can_deliver_quickly:true" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "optionalFilters": [ + "can_deliver_quickly:true" + ] + } + } + }, + { + "testName": "optionalFiltersMany", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "optionalFilters": [ + "brand:Apple", + "brand:Samsung", + "brand:-Huawei" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "optionalFilters": [ + "brand:Apple", + "brand:Samsung", + "brand:-Huawei" + ] + } + } + }, + { + "testName": "optionalFiltersSimple", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "optionalFilters": [ + "brand:Apple", + "type:tablet" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "optionalFilters": [ + "brand:Apple", + "type:tablet" + ] + } + } + }, + { + "testName": "restrictSearchableAttributes", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "restrictSearchableAttributes": [ + "title_fr" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "restrictSearchableAttributes": [ + "title_fr" + ] + } + } + }, + { + "testName": "getRankingInfo", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "getRankingInfo": true + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "getRankingInfo": true + } + } + }, + { + "testName": "clickAnalytics", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "clickAnalytics": true + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "clickAnalytics": true + } + } + }, + { + "testName": "clickAnalyticsUserToken", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "clickAnalytics": true, + "userToken": "user-1" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "clickAnalytics": true, + "userToken": "user-1" + } + } + }, + { + "testName": "enablePersonalization", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "enablePersonalization": true, + "userToken": "user-1" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "enablePersonalization": true, + "userToken": "user-1" + } + } + }, + { + "testName": "userToken", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "userToken": "user-1" + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "userToken": "user-1" + } + } + }, + { + "testName": "analyticsTag", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "analyticsTags": [ + "YOUR_ANALYTICS_TAG" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "analyticsTags": [ + "YOUR_ANALYTICS_TAG" + ] + } + } + }, + { + "testName": "facetFiltersUsers", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "facetFilters": [ + "user:user42", + "user:public" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "facetFilters": [ + "user:user42", + "user:public" + ] + } + } + }, + { + "testName": "buildTheQuery", + "isSnippet": true, + "parameters": { + "indexName": "indexName", + "searchParams": { + "filters": "categoryPageId: Men's Clothing", + "hitsPerPage": 50, + "analyticsTags": [ + "mens-clothing" + ] + } + }, + "request": { + "path": "/1/indexes/indexName/query", + "method": "POST", + "body": { + "filters": "categoryPageId: Men's Clothing", + "hitsPerPage": 50, + "analyticsTags": [ + "mens-clothing" + ] + } + } } ] diff --git a/tests/CTS/requests/search/setSettings.json b/tests/CTS/requests/search/setSettings.json index 9c048606967..3ba3be1a8ec 100644 --- a/tests/CTS/requests/search/setSettings.json +++ b/tests/CTS/requests/search/setSettings.json @@ -1,14 +1,279 @@ [ { - "testName": "setSettingsAttributesForFaceting", + "testName": "minimal parameters", + "parameters": { + "indexName": "cts_e2e_settings", + "indexSettings": { + "paginationLimitedTo": 10 + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/cts_e2e_settings/settings", + "method": "PUT", + "body": { + "paginationLimitedTo": 10 + }, + "queryParameters": { + "forwardToReplicas": "true" + } + }, + "response": { + "statusCode": 200 + } + }, + { + "testName": "boolean typoTolerance", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "typoTolerance": true + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "typoTolerance": true + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "enum typoTolerance", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "typoTolerance": "min" + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "typoTolerance": "min" + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "ignorePlurals", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "ignorePlurals": true + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "ignorePlurals": true + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "list of string ignorePlurals", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "ignorePlurals": [ + "fr" + ] + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "ignorePlurals": [ + "fr" + ] + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "removeStopWords boolean", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "removeStopWords": true + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "removeStopWords": true + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "removeStopWords list of string", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "removeStopWords": [ + "fr" + ] + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "removeStopWords": [ + "fr" + ] + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "boolean distinct", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "distinct": true + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "distinct": true + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "integer distinct", + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "distinct": 1 + }, + "forwardToReplicas": true + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "distinct": 1 + }, + "queryParameters": { + "forwardToReplicas": "true" + } + } + }, + { + "testName": "distinct company", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "attributeForDistinct": "company", + "distinct": true + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "attributeForDistinct": "company", + "distinct": true + } + } + }, + { + "testName": "distinct design", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "attributeForDistinct": "design", + "distinct": true + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "attributeForDistinct": "design", + "distinct": true + } + } + }, + { + "testName": "distinct true", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "distinct": true + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "distinct": true + } + } + }, + { + "testName": "distinct section", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "attributeForDistinct": "section", + "distinct": true + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "attributeForDistinct": "section", + "distinct": true + } + } + }, + { + "testName": "attributesForFaceting allergens", "isSnippet": true, "parameters": { "indexName": "", "indexSettings": { "attributesForFaceting": [ - "actor", - "filterOnly(category)", - "searchable(publisher)" + "allergens" ] } }, @@ -17,206 +282,774 @@ "method": "PUT", "body": { "attributesForFaceting": [ - "actor", - "filterOnly(category)", - "searchable(publisher)" + "allergens" ] } } }, { - "testName": "setSettings with minimal parameters", + "testName": "attributesForFaceting categoryPageId", + "isSnippet": true, "parameters": { - "indexName": "cts_e2e_settings", + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "searchable(categoryPageId)" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "searchable(categoryPageId)" + ] + } + } + }, + { + "testName": "unretrievableAttributes", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "unretrievableAttributes": [ + "visible_by" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "unretrievableAttributes": [ + "visible_by" + ] + } + } + }, + { + "testName": "attributesForFaceting user restricted data", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "filterOnly(visible_by)" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "filterOnly(visible_by)" + ] + } + } + }, + { + "testName": "attributesForFaceting optional filters", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "can_deliver_quickly", + "restaurant" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "can_deliver_quickly", + "restaurant" + ] + } + } + }, + { + "testName": "attributesForFaceting redirect index", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "query_terms" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "query_terms" + ] + } + } + }, + { + "testName": "attributesForFaceting multiple consequences", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "director" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "director" + ] + } + } + }, + { + "testName": "attributesForFaceting in-depth optional filters", + "isSnippet": true, + "parameters": { + "indexName": "", + "indexSettings": { + "attributesForFaceting": [ + "filterOnly(brand)" + ] + } + }, + "request": { + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", + "method": "PUT", + "body": { + "attributesForFaceting": [ + "filterOnly(brand)" + ] + } + } + }, + { + "testName": "mode neuralSearch", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "mode": "neuralSearch" + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "mode": "neuralSearch" + } + } + }, + { + "testName": "mode keywordSearch", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "mode": "keywordSearch" + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "mode": "keywordSearch" + } + } + }, + { + "testName": "searchableAttributes same priority", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "title,comments", + "ingredients" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "title,comments", + "ingredients" + ] + } + } + }, + { + "testName": "searchableAttributes higher priority", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "title", + "ingredients" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "title", + "ingredients" + ] + } + } + }, + { + "testName": "customRanking retweets", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(retweets)", + "desc(likes)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(retweets)", + "desc(likes)" + ] + } + } + }, + { + "testName": "customRanking boosted", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ "desc(boosted)" ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ "desc(boosted)" ] + } + } + }, + { + "testName": "customRanking pageviews", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(pageviews)", + "desc(comments)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(pageviews)", + "desc(comments)" + ] + } + } + }, + { + "testName": "customRanking applying search parameters for a specific query", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(nb_airline_liaisons)" + ], + "attributesForFaceting": ["city, country"] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(nb_airline_liaisons)" + ], + "attributesForFaceting": ["city, country"] + } + } + }, + { + "testName": "customRanking rounded pageviews", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(rounded_pageviews)", + "desc(comments)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(rounded_pageviews)", + "desc(comments)" + ] + } + } + }, + { + "testName": "customRanking price", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(price)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(price)" + ] + } + } + }, + { + "testName": "ranking exhaustive", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "ranking": [ + "desc(price)", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact", + "custom" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "ranking": [ + "desc(price)", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact", + "custom" + ] + } + } + }, + { + "testName": "ranking standard replica", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "ranking": [ + "desc(post_date_timestamp)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "ranking": [ + "desc(post_date_timestamp)" + ] + } + } + }, + { + "testName": "ranking virtual replica", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "desc(post_date_timestamp)" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "desc(post_date_timestamp)" + ] + } + } + }, + { + "testName": "customRanking and ranking sort alphabetically", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "asc(textual_attribute)" + ], + "ranking": [ + "custom", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "asc(textual_attribute)" + ], + "ranking": [ + "custom", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact" + ] + } + } + }, + { + "testName": "relevancyStrictness", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "customRanking": [ + "asc(textual_attribute)" + ], + "relevancyStrictness": 0 + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "customRanking": [ + "asc(textual_attribute)" + ], + "relevancyStrictness": 0 + } + } + }, + { + "testName": "create replica index", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "replicas": [ + "products_price_desc" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "replicas": [ + "products_price_desc" + ] + } + } + }, + { + "testName": "unlink replica index", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "replicas": [""] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "replicas": [""] + } + } + }, + { + "testName": "forwardToReplicas", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", "indexSettings": { - "paginationLimitedTo": 10 + "searchableAttributes": ["name", "description"] }, "forwardToReplicas": true }, "request": { - "path": "/1/indexes/cts_e2e_settings/settings", + "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "paginationLimitedTo": 10 + "searchableAttributes": ["name", "description"] }, - "queryParameters": { - "forwardToReplicas": "true" - } - }, - "response": { - "statusCode": 200 + "queryParameters": { + "forwardToReplicas": "true" + } } }, { - "testName": "setSettings allow boolean `typoTolerance`", + "testName": "maxValuesPerFacet", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "typoTolerance": true - }, - "forwardToReplicas": true + "maxValuesPerFacet": 1000 + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "typoTolerance": true - }, - "queryParameters": { - "forwardToReplicas": "true" + "maxValuesPerFacet": 1000 } } }, { - "testName": "setSettings allow enum `typoTolerance`", + "testName": "maxFacetHits", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "typoTolerance": "min" - }, - "forwardToReplicas": true + "maxFacetHits": 1000 + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "typoTolerance": "min" - }, - "queryParameters": { - "forwardToReplicas": "true" + "maxFacetHits": 1000 } } }, { - "testName": "setSettings allow boolean `ignorePlurals`", + "testName": "attributesForFaceting complex", + "isSnippet": true, "parameters": { - "indexName": "theIndexName", + "indexName": "", "indexSettings": { - "ignorePlurals": true - }, - "forwardToReplicas": true + "attributesForFaceting": [ + "actor", + "filterOnly(category)", + "searchable(publisher)" + ] + } }, "request": { - "path": "/1/indexes/theIndexName/settings", + "path": "/1/indexes/%3CYOUR_INDEX_NAME%3E/settings", "method": "PUT", "body": { - "ignorePlurals": true - }, - "queryParameters": { - "forwardToReplicas": "true" + "attributesForFaceting": [ + "actor", + "filterOnly(category)", + "searchable(publisher)" + ] } } }, { - "testName": "setSettings allow list of string `ignorePlurals`", + "testName": "ranking closest dates", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "ignorePlurals": [ - "fr" + "ranking": [ + "asc(date_timestamp)", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact", + "custom" ] - }, - "forwardToReplicas": true + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "ignorePlurals": [ - "fr" + "ranking": [ + "asc(date_timestamp)", + "typo", + "geo", + "words", + "filters", + "proximity", + "attribute", + "exact", + "custom" ] - }, - "queryParameters": { - "forwardToReplicas": "true" } } }, { - "testName": "setSettings allow boolean `removeStopWords`", + "testName": "searchableAttributes item variation", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "removeStopWords": true - }, - "forwardToReplicas": true + "searchableAttributes": [ + "design", + "type", + "color" + ] + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "removeStopWords": true - }, - "queryParameters": { - "forwardToReplicas": "true" + "searchableAttributes": [ + "design", + "type", + "color" + ] } } }, { - "testName": "setSettings allow list of string `removeStopWords`", + "testName": "searchableAttributes around location", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "removeStopWords": [ - "fr" - ] - }, - "forwardToReplicas": true + "searchableAttributes": [ + "name", + "country", + "code", + "iata_code" + ], + "customRanking": ["desc(links_count)"] + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "removeStopWords": [ - "fr" - ] - }, - "queryParameters": { - "forwardToReplicas": "true" + "searchableAttributes": [ + "name", + "country", + "code", + "iata_code" + ], + "customRanking": ["desc(links_count)"] } } }, { - "testName": "setSettings allow boolean `distinct`", + "testName": "searchableAttributes around location", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "distinct": true - }, - "forwardToReplicas": true + "searchableAttributes": [ + "name", + "country", + "code", + "iata_code" + ], + "customRanking": ["desc(links_count)"] + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "distinct": true - }, - "queryParameters": { - "forwardToReplicas": "true" + "searchableAttributes": [ + "name", + "country", + "code", + "iata_code" + ], + "customRanking": ["desc(links_count)"] } } }, { - "testName": "setSettings allow integers for `distinct`", + "testName": "disableTypoToleranceOnAttributes", + "isSnippet": true, "parameters": { "indexName": "theIndexName", "indexSettings": { - "distinct": 1 - }, - "forwardToReplicas": true + "disableTypoToleranceOnAttributes": [ + "serial_number" + ] + } }, "request": { "path": "/1/indexes/theIndexName/settings", "method": "PUT", "body": { - "distinct": 1 - }, - "queryParameters": { - "forwardToReplicas": "true" + "disableTypoToleranceOnAttributes": [ + "serial_number" + ] } } }, { - "testName": "setSettings allow all `indexSettings`", + "testName": "everything", "parameters": { "indexName": "theIndexName", "indexSettings": { @@ -496,5 +1329,205 @@ } } } + }, + { + "testName": "searchableAttributesWithCustomRankingsAndAttributesForFaceting", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "brand", + "name", + "categories", + "unordered(description)" + ], + "customRanking": [ + "desc(popularity)" + ], + "attributesForFaceting": [ + "searchable(brand)", + "type", + "categories", + "price" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "brand", + "name", + "categories", + "unordered(description)" + ], + "customRanking": [ + "desc(popularity)" + ], + "attributesForFaceting": [ + "searchable(brand)", + "type", + "categories", + "price" + ] + } + } + }, + { + "testName": "searchableAttributesProductReferenceSuffixes", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "name", + "product_reference", + "product_reference_suffixes" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "name", + "product_reference", + "product_reference_suffixes" + ] + } + } + }, + { + "testName": "queryLanguageAndIgnorePlurals", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "queryLanguages": [ + "en" + ], + "ignorePlurals": true + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "queryLanguages": [ + "en" + ], + "ignorePlurals": true + } + } + }, + { + "testName": "searchableAttributesInMovies", + "isSnippet": true, + "parameters": { + "indexName": "movies", + "indexSettings": { + "searchableAttributes": [ + "title_eng", "title_fr", "title_es" + ] + } + }, + "request": { + "path": "/1/indexes/movies/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "title_eng", "title_fr", "title_es" + ] + } + } + }, + { + "testName": "disablePrefixOnAttributes", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "disablePrefixOnAttributes": [ + "serial_number" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "disablePrefixOnAttributes": [ + "serial_number" + ] + } + } + }, + { + "testName": "disableTypoToleranceOnAttributes", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "disableTypoToleranceOnAttributes": [ + "serial_number" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "disableTypoToleranceOnAttributes": [ + "serial_number" + ] + } + } + }, + { + "testName": "searchableAttributesSimpleExample", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "serial_number" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "serial_number" + ] + } + } + }, + { + "testName": "searchableAttributesSimpleExampleAlt", + "isSnippet": true, + "parameters": { + "indexName": "theIndexName", + "indexSettings": { + "searchableAttributes": [ + "serial_number", + "serial_number_suffixes" + ] + } + }, + "request": { + "path": "/1/indexes/theIndexName/settings", + "method": "PUT", + "body": { + "searchableAttributes": [ + "serial_number", + "serial_number_suffixes" + ] + } + } } ]