diff --git a/clients/algoliasearch-client-javascript/client-common/src/requester/EchoRequester.ts b/clients/algoliasearch-client-javascript/client-common/src/requester/EchoRequester.ts index 491a9d69de4..5d1766df97a 100644 --- a/clients/algoliasearch-client-javascript/client-common/src/requester/EchoRequester.ts +++ b/clients/algoliasearch-client-javascript/client-common/src/requester/EchoRequester.ts @@ -29,7 +29,7 @@ export class EchoRequester extends Requester { { headers, url, connectTimeout, responseTimeout }: EndRequest, { data, ...originalRequest }: Request ): Promise { - const urlSearchParams = new URL(url).searchParams; + const { host, searchParams: urlSearchParams } = new URL(url); const userAgent = urlSearchParams.get('x-algolia-agent') || undefined; const originalData = data && Object.entries(data).length > 0 ? data : undefined; @@ -37,6 +37,7 @@ export class EchoRequester extends Requester { return Promise.resolve({ content: JSON.stringify({ ...originalRequest, + host, headers, connectTimeout, responseTimeout, diff --git a/clients/algoliasearch-client-javascript/client-common/src/types.ts b/clients/algoliasearch-client-javascript/client-common/src/types.ts index dc590d840e7..1f45c28816a 100644 --- a/clients/algoliasearch-client-javascript/client-common/src/types.ts +++ b/clients/algoliasearch-client-javascript/client-common/src/types.ts @@ -45,6 +45,7 @@ export type Response = { export type EchoResponse = Request & { connectTimeout: number; + host: string; headers: Record; responseTimeout: number; searchParams?: Record; diff --git a/tests/CTS/client/abtesting/api.json b/tests/CTS/client/abtesting/api.json new file mode 100644 index 00000000000..99eee49c34b --- /dev/null +++ b/tests/CTS/client/abtesting/api.json @@ -0,0 +1,50 @@ +[ + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "addABTests", + "parameters": [ + { + "name": "test", + "variant": [{ "index": "my-test-index", "trafficPercentage": 90 }], + "endAt": "2022-02-01T13:37:01Z" + } + ], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "addABTests", + "parameters": [ + { + "name": "test", + "variant": [{ "index": "my-test-index", "trafficPercentage": 90 }], + "endAt": "2022-02-01T13:37:01Z" + } + ], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/abtesting/parameters.json b/tests/CTS/client/abtesting/parameters.json new file mode 100644 index 00000000000..ae44b7123b4 --- /dev/null +++ b/tests/CTS/client/abtesting/parameters.json @@ -0,0 +1,36 @@ +[ + { + "testName": "fallbacks to the alias when region is not given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "" + }, + "expected": { + "error": false + } + }, + { + "type": "method", + "object": "$client", + "path": "getABTest", + "parameters": [ + { + "id": "test" + } + ], + "expected": { + "match": { + "objectContaining": { + "host": "analytics.algolia.com" + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/analytics/api.json b/tests/CTS/client/analytics/api.json new file mode 100644 index 00000000000..ae0c75c2b4e --- /dev/null +++ b/tests/CTS/client/analytics/api.json @@ -0,0 +1,38 @@ +[ + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getAverageClickPosition", + "parameters": [{ "index": "my-index" }], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getAverageClickPosition", + "parameters": [{ "index": "my-index" }], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 5 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/analytics/basic.json b/tests/CTS/client/analytics/parameters.json similarity index 62% rename from tests/CTS/client/analytics/basic.json rename to tests/CTS/client/analytics/parameters.json index 7d539ef3c3d..df7387b8de3 100644 --- a/tests/CTS/client/analytics/basic.json +++ b/tests/CTS/client/analytics/parameters.json @@ -1,6 +1,6 @@ [ { - "testName": "does not throw when region is not given", + "testName": "fallbacks to the alias when region is not given", "autoCreateClient": false, "steps": [ { @@ -13,6 +13,19 @@ "expected": { "error": false } + }, + { + "type": "method", + "object": "$client", + "path": "getAverageClickPosition", + "parameters": [{ "index": "my-index" }], + "expected": { + "match": { + "objectContaining": { + "host": "analytics.algolia.com" + } + } + } } ] }, diff --git a/tests/CTS/client/insights/api.json b/tests/CTS/client/insights/api.json new file mode 100644 index 00000000000..1256ff24a4a --- /dev/null +++ b/tests/CTS/client/insights/api.json @@ -0,0 +1,46 @@ +[ + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "pushEvents", + "parameters": [ + { + "events": [] + } + ], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "pushEvents", + "parameters": [ + { + "events": [] + } + ], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/insights/parameters.json b/tests/CTS/client/insights/parameters.json new file mode 100644 index 00000000000..c7ca54f2121 --- /dev/null +++ b/tests/CTS/client/insights/parameters.json @@ -0,0 +1,32 @@ +[ + { + "testName": "fallbacks to the alias when region is not given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "" + }, + "expected": { + "error": false + } + }, + { + "type": "method", + "object": "$client", + "path": "pushEvents", + "parameters": [{ "events": [] }], + "expected": { + "match": { + "objectContaining": { + "host": "insights.algolia.io" + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/personalization/api.json b/tests/CTS/client/personalization/api.json new file mode 100644 index 00000000000..fa8e43d7faa --- /dev/null +++ b/tests/CTS/client/personalization/api.json @@ -0,0 +1,38 @@ +[ + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getPersonalizationStrategy", + "parameters": [], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getPersonalizationStrategy", + "parameters": [], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 5 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/personalization/parameters.json b/tests/CTS/client/personalization/parameters.json new file mode 100644 index 00000000000..5f097fb0ab4 --- /dev/null +++ b/tests/CTS/client/personalization/parameters.json @@ -0,0 +1,36 @@ +[ + { + "testName": "throws when region is not given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "" + }, + "expected": { + "error": "`region` is missing." + } + } + ] + }, + { + "testName": "does not throw when region is given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "us" + }, + "expected": { + "error": false + } + } + ] + } +] diff --git a/tests/CTS/client/query-suggestions/api.json b/tests/CTS/client/query-suggestions/api.json new file mode 100644 index 00000000000..ea3f7ab0571 --- /dev/null +++ b/tests/CTS/client/query-suggestions/api.json @@ -0,0 +1,38 @@ +[ + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "createConfig", + "parameters": [{}], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "createConfig", + "parameters": [{}], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/query-suggestions/parameters.json b/tests/CTS/client/query-suggestions/parameters.json new file mode 100644 index 00000000000..5f097fb0ab4 --- /dev/null +++ b/tests/CTS/client/query-suggestions/parameters.json @@ -0,0 +1,36 @@ +[ + { + "testName": "throws when region is not given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "" + }, + "expected": { + "error": "`region` is missing." + } + } + ] + }, + { + "testName": "does not throw when region is given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "us" + }, + "expected": { + "error": false + } + } + ] + } +] diff --git a/tests/CTS/client/recommend/api.json b/tests/CTS/client/recommend/api.json new file mode 100644 index 00000000000..b402d3847a5 --- /dev/null +++ b/tests/CTS/client/recommend/api.json @@ -0,0 +1,56 @@ +[ + { + "testName": "calls api with correct host", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getRecommendations", + "parameters": [{ "requests": [] }], + "expected": { + "match": { + "objectContaining": { + "host": "test-app-id.algolia.net" + } + } + } + } + ] + }, + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getRecommendations", + "parameters": [{ "requests": [] }], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "getRecommendations", + "parameters": [{ "requests": [] }], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/search/api.json b/tests/CTS/client/search/api.json new file mode 100644 index 00000000000..b0513a010f1 --- /dev/null +++ b/tests/CTS/client/search/api.json @@ -0,0 +1,56 @@ +[ + { + "testName": "calls api with correct host", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "search", + "parameters": [{ "indexName": "my-index", "searchParams": {} }], + "expected": { + "match": { + "objectContaining": { + "host": "test-app-id.algolia.net" + } + } + } + } + ] + }, + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "search", + "parameters": [{ "indexName": "my-index", "searchParams": {} }], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "search", + "parameters": [{ "indexName": "my-index", "searchParams": {} }], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/search/parameters.json b/tests/CTS/client/search/parameters.json index f80fe060e5d..b23e13d3407 100644 --- a/tests/CTS/client/search/parameters.json +++ b/tests/CTS/client/search/parameters.json @@ -1,6 +1,6 @@ [ { - "testName": "constructor throws with invalid parameters", + "testName": "client throws with invalid parameters", "autoCreateClient": false, "steps": [ { diff --git a/tests/CTS/client/sources/api.json b/tests/CTS/client/sources/api.json new file mode 100644 index 00000000000..ac87c64ead6 --- /dev/null +++ b/tests/CTS/client/sources/api.json @@ -0,0 +1,56 @@ +[ + { + "testName": "calls api with correct host", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "postIngestUrl", + "parameters": [{ "type": "csv", "input": { "url": "..." } }], + "expected": { + "match": { + "objectContaining": { + "host": "data.us.algolia.com" + } + } + } + } + ] + }, + { + "testName": "calls api with correct user agent", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "postIngestUrl", + "parameters": [{ "type": "csv", "input": { "url": "..." } }], + "expected": { + "testSubject": "actual.userAgent", + "match": { + "regexp": "/Algolia%20for%20(.+)%20\\(\\d+\\.\\d+\\.\\d+\\)/" + } + } + } + ] + }, + { + "testName": "calls api with correct timeouts", + "steps": [ + { + "type": "method", + "object": "$client", + "path": "postIngestUrl", + "parameters": [{ "type": "csv", "input": { "url": "..." } }], + "expected": { + "match": { + "objectContaining": { + "connectTimeout": 2, + "responseTimeout": 30 + } + } + } + } + ] + } +] diff --git a/tests/CTS/client/sources/parameters.json b/tests/CTS/client/sources/parameters.json new file mode 100644 index 00000000000..5f097fb0ab4 --- /dev/null +++ b/tests/CTS/client/sources/parameters.json @@ -0,0 +1,36 @@ +[ + { + "testName": "throws when region is not given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "" + }, + "expected": { + "error": "`region` is missing." + } + } + ] + }, + { + "testName": "does not throw when region is given", + "autoCreateClient": false, + "steps": [ + { + "type": "createClient", + "parameters": { + "appId": "my-app-id", + "apiKey": "my-api-key", + "region": "us" + }, + "expected": { + "error": false + } + } + ] + } +] diff --git a/tests/CTS/client/templates/javascript/expected.mustache b/tests/CTS/client/templates/javascript/expected.mustache index 83136041259..408fbe57c65 100644 --- a/tests/CTS/client/templates/javascript/expected.mustache +++ b/tests/CTS/client/templates/javascript/expected.mustache @@ -1,3 +1,13 @@ {{#length}} - expect(actual).toHaveLength({{length}}); -{{/length}} \ No newline at end of file + expect({{> testSubject}}).toHaveLength({{length}}); +{{/length}} + +{{#match}} + {{#objectContaining}} + expect({{> testSubject}}).toEqual(expect.objectContaining({{{objectContaining}}})); + {{/objectContaining}} + + {{#regexp}} + expect({{> testSubject}}).toMatch({{{regexp}}}); + {{/regexp}} +{{/match}} \ No newline at end of file diff --git a/tests/CTS/client/templates/javascript/step.mustache b/tests/CTS/client/templates/javascript/step.mustache index 7b1854b3d4f..d03394f619f 100644 --- a/tests/CTS/client/templates/javascript/step.mustache +++ b/tests/CTS/client/templates/javascript/step.mustache @@ -1,5 +1,5 @@ {{#isCreateClient}} - const $client = {{> createClient}} + $client = {{> createClient}} actual = $client; {{/isCreateClient}} diff --git a/tests/CTS/client/templates/javascript/suite.mustache b/tests/CTS/client/templates/javascript/suite.mustache index 3385dc6a413..cb8490cc2ed 100644 --- a/tests/CTS/client/templates/javascript/suite.mustache +++ b/tests/CTS/client/templates/javascript/suite.mustache @@ -1,12 +1,13 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable require-await */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -// @ts-nocheck +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. import { {{client}} } from '{{{import}}}'; import { EchoRequester } from '@algolia/client-common'; -const appId = process.env.ALGOLIA_APPLICATION_ID || 'Algolia-API-Key'; -const apiKey = process.env.ALGOLIA_SEARCH_KEY || 'Algolia-Application-Id'; +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function createClient() { @@ -17,8 +18,9 @@ function createClient() { describe('{{operationId}}', () => { {{#tests}} test('{{{testName}}}', async () => { + let $client; {{#autoCreateClient}} - const $client = createClient(); + $client = createClient(); {{/autoCreateClient}} let actual; diff --git a/tests/CTS/client/templates/javascript/testSubject.mustache b/tests/CTS/client/templates/javascript/testSubject.mustache new file mode 100644 index 00000000000..ffa50baad3d --- /dev/null +++ b/tests/CTS/client/templates/javascript/testSubject.mustache @@ -0,0 +1,7 @@ +{{#testSubject}} + {{{testSubject}}} +{{/testSubject}} + +{{^testSubject}} + actual +{{/testSubject}} \ No newline at end of file diff --git a/tests/output/javascript/src/client/abtesting.test.ts b/tests/output/javascript/src/client/abtesting.test.ts new file mode 100644 index 00000000000..77cd6a156cb --- /dev/null +++ b/tests/output/javascript/src/client/abtesting.test.ts @@ -0,0 +1,90 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { abtestingApi } from '@algolia/client-abtesting'; +import { EchoRequester } from '@algolia/client-common'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return abtestingApi(appId, apiKey, 'us', { requester: new EchoRequester() }); +} + +describe('api', () => { + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.addABTests({ + name: 'test', + variant: [{ index: 'my-test-index', trafficPercentage: 90 }], + endAt: '2022-02-01T13:37:01Z', + }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.addABTests({ + name: 'test', + variant: [{ index: 'my-test-index', trafficPercentage: 90 }], + endAt: '2022-02-01T13:37:01Z', + }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); + +describe('parameters', () => { + test('fallbacks to the alias when region is not given', async () => { + let $client; + + let actual; + + await expect( + new Promise((resolve, reject) => { + $client = abtestingApi('my-app-id', 'my-api-key', '', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).resolves.not.toThrow(); + + actual = $client.getABTest({ id: 'test' }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'analytics.algolia.com' }) + ); + }); +}); diff --git a/tests/output/javascript/src/client/analytics.test.ts b/tests/output/javascript/src/client/analytics.test.ts index 4795f144537..a3bb0f173e1 100644 --- a/tests/output/javascript/src/client/analytics.test.ts +++ b/tests/output/javascript/src/client/analytics.test.ts @@ -1,22 +1,61 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -// @ts-nocheck +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. import { analyticsApi } from '@algolia/client-analytics'; import { EchoRequester } from '@algolia/client-common'; -const appId = process.env.ALGOLIA_APPLICATION_ID || 'Algolia-API-Key'; -const apiKey = process.env.ALGOLIA_SEARCH_KEY || 'Algolia-Application-Id'; +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; function createClient() { return analyticsApi(appId, apiKey, 'us', { requester: new EchoRequester() }); } -describe('basic', () => { - test('does not throw when region is not given', async () => { +describe('api', () => { + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getAverageClickPosition({ index: 'my-index' }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getAverageClickPosition({ index: 'my-index' }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 5 }) + ); + }); +}); + +describe('parameters', () => { + test('fallbacks to the alias when region is not given', async () => { + let $client; + let actual; await expect( new Promise((resolve, reject) => { - const $client = analyticsApi('my-app-id', 'my-api-key', '', { + $client = analyticsApi('my-app-id', 'my-api-key', '', { requester: new EchoRequester(), }); @@ -29,10 +68,21 @@ describe('basic', () => { } }) ).resolves.not.toThrow(); + + actual = $client.getAverageClickPosition({ index: 'my-index' }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'analytics.algolia.com' }) + ); }); test('getAverageClickPosition throws without index', async () => { - const $client = createClient(); + let $client; + $client = createClient(); let actual; await expect( diff --git a/tests/output/javascript/src/client/insights.test.ts b/tests/output/javascript/src/client/insights.test.ts new file mode 100644 index 00000000000..4d90bdb5faf --- /dev/null +++ b/tests/output/javascript/src/client/insights.test.ts @@ -0,0 +1,82 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { EchoRequester } from '@algolia/client-common'; +import { insightsApi } from '@algolia/client-insights'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return insightsApi(appId, apiKey, 'us', { requester: new EchoRequester() }); +} + +describe('api', () => { + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.pushEvents({ events: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.pushEvents({ events: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); + +describe('parameters', () => { + test('fallbacks to the alias when region is not given', async () => { + let $client; + + let actual; + + await expect( + new Promise((resolve, reject) => { + $client = insightsApi('my-app-id', 'my-api-key', '', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).resolves.not.toThrow(); + + actual = $client.pushEvents({ events: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'insights.algolia.io' }) + ); + }); +}); diff --git a/tests/output/javascript/src/client/personalization.test.ts b/tests/output/javascript/src/client/personalization.test.ts new file mode 100644 index 00000000000..889303cdd8b --- /dev/null +++ b/tests/output/javascript/src/client/personalization.test.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { EchoRequester } from '@algolia/client-common'; +import { personalizationApi } from '@algolia/client-personalization'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return personalizationApi(appId, apiKey, 'us', { + requester: new EchoRequester(), + }); +} + +describe('api', () => { + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getPersonalizationStrategy(); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getPersonalizationStrategy(); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 5 }) + ); + }); +}); + +describe('parameters', () => { + test('throws when region is not given', async () => { + let $client; + + let actual; + await expect( + new Promise((resolve, reject) => { + $client = personalizationApi('my-app-id', 'my-api-key', '', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).rejects.toThrow('`region` is missing.'); + }); + + test('does not throw when region is given', async () => { + let $client; + + let actual; + + await expect( + new Promise((resolve, reject) => { + $client = personalizationApi('my-app-id', 'my-api-key', 'us', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).resolves.not.toThrow(); + }); +}); diff --git a/tests/output/javascript/src/client/query-suggestions.test.ts b/tests/output/javascript/src/client/query-suggestions.test.ts new file mode 100644 index 00000000000..1bcfb930fdf --- /dev/null +++ b/tests/output/javascript/src/client/query-suggestions.test.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { EchoRequester } from '@algolia/client-common'; +import { querySuggestionsApi } from '@algolia/client-query-suggestions'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return querySuggestionsApi(appId, apiKey, 'us', { + requester: new EchoRequester(), + }); +} + +describe('api', () => { + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.createConfig({}); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.createConfig({}); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); + +describe('parameters', () => { + test('throws when region is not given', async () => { + let $client; + + let actual; + await expect( + new Promise((resolve, reject) => { + $client = querySuggestionsApi('my-app-id', 'my-api-key', '', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).rejects.toThrow('`region` is missing.'); + }); + + test('does not throw when region is given', async () => { + let $client; + + let actual; + + await expect( + new Promise((resolve, reject) => { + $client = querySuggestionsApi('my-app-id', 'my-api-key', 'us', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).resolves.not.toThrow(); + }); +}); diff --git a/tests/output/javascript/src/client/recommend.test.ts b/tests/output/javascript/src/client/recommend.test.ts new file mode 100644 index 00000000000..833aacf4e52 --- /dev/null +++ b/tests/output/javascript/src/client/recommend.test.ts @@ -0,0 +1,65 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { EchoRequester } from '@algolia/client-common'; +import { recommendApi } from '@algolia/recommend'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return recommendApi(appId, apiKey, { requester: new EchoRequester() }); +} + +describe('api', () => { + test('calls api with correct host', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getRecommendations({ requests: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'test-app-id.algolia.net' }) + ); + }); + + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getRecommendations({ requests: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.getRecommendations({ requests: [] }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); diff --git a/tests/output/javascript/src/client/search.test.ts b/tests/output/javascript/src/client/search.test.ts index 7cf803766f5..db91a6dbe03 100644 --- a/tests/output/javascript/src/client/search.test.ts +++ b/tests/output/javascript/src/client/search.test.ts @@ -1,21 +1,77 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -// @ts-nocheck +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. import { EchoRequester } from '@algolia/client-common'; import { searchApi } from '@algolia/client-search'; -const appId = process.env.ALGOLIA_APPLICATION_ID || 'Algolia-API-Key'; -const apiKey = process.env.ALGOLIA_SEARCH_KEY || 'Algolia-Application-Id'; +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; function createClient() { return searchApi(appId, apiKey, { requester: new EchoRequester() }); } +describe('api', () => { + test('calls api with correct host', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.search({ indexName: 'my-index', searchParams: {} }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'test-app-id.algolia.net' }) + ); + }); + + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.search({ indexName: 'my-index', searchParams: {} }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.search({ indexName: 'my-index', searchParams: {} }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); + describe('parameters', () => { - test('constructor throws with invalid parameters', async () => { + test('client throws with invalid parameters', async () => { + let $client; + let actual; await expect( new Promise((resolve, reject) => { - const $client = searchApi('', '', { requester: new EchoRequester() }); + $client = searchApi('', '', { requester: new EchoRequester() }); actual = $client; @@ -29,7 +85,7 @@ describe('parameters', () => { await expect( new Promise((resolve, reject) => { - const $client = searchApi('', 'my-api-key', { + $client = searchApi('', 'my-api-key', { requester: new EchoRequester(), }); @@ -45,7 +101,7 @@ describe('parameters', () => { await expect( new Promise((resolve, reject) => { - const $client = searchApi('my-app-id', '', { + $client = searchApi('my-app-id', '', { requester: new EchoRequester(), }); @@ -61,7 +117,8 @@ describe('parameters', () => { }); test('`addApiKey` throws with invalid parameters', async () => { - const $client = createClient(); + let $client; + $client = createClient(); let actual; await expect( @@ -92,7 +149,8 @@ describe('parameters', () => { }); test('`addOrUpdateObject` throws with invalid parameters', async () => { - const $client = createClient(); + let $client; + $client = createClient(); let actual; await expect( diff --git a/tests/output/javascript/src/client/sources.test.ts b/tests/output/javascript/src/client/sources.test.ts new file mode 100644 index 00000000000..846f1e1cd27 --- /dev/null +++ b/tests/output/javascript/src/client/sources.test.ts @@ -0,0 +1,110 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable prefer-const */ +// @ts-nocheck Failing tests will have type errors, but we cannot suppress them even with @ts-expect-error because it doesn't work for a block of lines. +import { EchoRequester } from '@algolia/client-common'; +import { sourcesApi } from '@algolia/client-sources'; + +const appId = 'test-app-id'; +const apiKey = 'test-api-key'; + +function createClient() { + return sourcesApi(appId, apiKey, 'us', { requester: new EchoRequester() }); +} + +describe('api', () => { + test('calls api with correct host', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.postIngestUrl({ type: 'csv', input: { url: '...' } }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ host: 'data.us.algolia.com' }) + ); + }); + + test('calls api with correct user agent', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.postIngestUrl({ type: 'csv', input: { url: '...' } }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual.userAgent).toMatch( + /Algolia%20for%20(.+)%20\(\d+\.\d+\.\d+\)/ + ); + }); + + test('calls api with correct timeouts', async () => { + let $client; + $client = createClient(); + + let actual; + + actual = $client.postIngestUrl({ type: 'csv', input: { url: '...' } }); + + if (actual instanceof Promise) { + actual = await actual; + } + + expect(actual).toEqual( + expect.objectContaining({ connectTimeout: 2, responseTimeout: 30 }) + ); + }); +}); + +describe('parameters', () => { + test('throws when region is not given', async () => { + let $client; + + let actual; + await expect( + new Promise((resolve, reject) => { + $client = sourcesApi('my-app-id', 'my-api-key', '', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).rejects.toThrow('`region` is missing.'); + }); + + test('does not throw when region is given', async () => { + let $client; + + let actual; + + await expect( + new Promise((resolve, reject) => { + $client = sourcesApi('my-app-id', 'my-api-key', 'us', { + requester: new EchoRequester(), + }); + + actual = $client; + + if (actual instanceof Promise) { + actual.then(resolve).catch(reject); + } else { + resolve(); + } + }) + ).resolves.not.toThrow(); + }); +}); diff --git a/tests/src/client/generate.ts b/tests/src/client/generate.ts index 9469c0ebccc..268c130564f 100644 --- a/tests/src/client/generate.ts +++ b/tests/src/client/generate.ts @@ -128,6 +128,7 @@ function modifyForMustache( type: step.type, object: step.object, path: step.path, + expected: step.expected, parameters: step.parameters && serializeParameters(step.parameters), ...base, }; @@ -143,6 +144,18 @@ function modifyForMustache( modified.expectedNoError = true; } + if (step.expected?.match?.objectContaining) { + if (!modified.expected) { + modified.expected = {}; + } + + modified.expected.match = { + objectContaining: JSON.stringify( + step.expected?.match?.objectContaining + ), + }; + } + return modified; }), })),