import { GenericContainer, type StartedTestContainer, Wait } from 'testcontainers' import { afterAll, beforeAll, describe, expect, it } from 'vitest' import { createEsBackend } from '../../src/es/backend.js' import type { ConnectionConfig } from '../../src/schema.js' import { runGetMapping } from '../../src/tools/mappingTool.js' import { runEsSearch } from '../../src/tools/search.js' const VERSIONS = ['7.17.22', '8.15.0'] for (const version of VERSIONS) { describe('elasticsearch ' + version, () => { let container: StartedTestContainer let backend: ReturnType beforeAll(async () => { container = await new GenericContainer( 'docker.elastic.co/elasticsearch/elasticsearch:' + version ) .withExposedPorts(9200) .withEnvironment({ 'discovery.type': 'single-node', 'xpack.security.enabled': 'false', ES_JAVA_OPTS: '-Xms512m -Xmx512m' }) .withWaitStrategy( Wait.forHttp('/_cluster/health', 9200).forStatusCodeMatching((c) => c === 200) ) .withStartupTimeout(180_000) .start() const config = { name: 'it', host: container.getHost(), type: 'elasticsearch', scheme: 'http', verifyTls: false, user: 'elastic', password: 'x', readonly: false } as ConnectionConfig backend = createEsBackend({ config, connectHost: container.getHost(), connectPort: container.getMappedPort(9200), serverName: container.getHost() }) }, 240_000) afterAll(async () => { await backend?.dispose() await container?.stop() }) it('indexes, refreshes, searches, and reads mapping', async () => { await backend.request('PUT', '/books/_doc/1', { body: { title: 'Dune', author: { name: 'Herbert' }, year: 1965 } }) await backend.request('POST', '/books/_refresh') const managed = { config: { name: 'it', readonly: false, type: 'elasticsearch' }, backend } as never const search = await runEsSearch( managed, 'books', { match: { title: 'Dune' } }, undefined, 10, ['title'] ) expect(search.status).toBe(200) expect((search.body as { hits: { total: { value: number } } }).hits.total.value).toBe(1) const mapping = await runGetMapping(managed, 'books', false) expect(mapping.fields).toContainEqual({ field: 'year', type: 'long' }) }) }) }