Files
floci-ui/packages/api/src/adapter-azure/AzureNoSqlAdapter.test.ts
T
2026-09-22 16:13:21 -04:00

156 lines
6.1 KiB
TypeScript

import {describe, expect, test} from 'bun:test'
import {AzureNoSqlAdapter} from './AzureNoSqlAdapter'
import type {AzureRuntimeClient, AzureRuntimeFetchOptions} from '../azure'
describe('AzureNoSqlAdapter', () => {
test('normalizes Cosmos databases as cloud NoSQL resources', async () => {
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs': {
_count: 1,
Databases: [{id: 'appdb', _rid: 'db-rid', _etag: '"etag"', _ts: 1779307200}],
},
}))
await expect(adapter.list()).resolves.toEqual([{
id: 'appdb',
name: 'appdb',
cloud: 'azure',
service: 'nosql',
type: 'cosmos-database',
region: null,
createdAt: '2026-05-20T20:00:00.000Z',
status: 'available',
engine: 'cosmos-nosql',
version: 'NoSQL API',
instanceClass: null,
metadata: {
provider: 'azure',
databaseService: 'cosmos',
api: 'nosql',
resourceId: 'db-rid',
self: undefined,
etag: 'etag',
},
}])
})
test('lists containers and documents from the selected database', async () => {
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs/appdb/colls': {
_count: 1,
DocumentCollections: [{
id: 'items',
_rid: 'coll-rid',
_etag: '"coll-etag"',
_ts: 1779307200,
partitionKey: {paths: ['/category'], kind: 'Hash'},
}],
},
'/dbs/appdb/colls/items': {
id: 'items',
partitionKey: {paths: ['/category'], kind: 'Hash'},
},
'/dbs/appdb/colls/items/docs': {
_count: 1,
Documents: [{id: 'item-1', category: 'demo', _etag: '"doc-etag"', _ts: 1779307201}],
},
}))
await expect(adapter.listCosmosContainers('appdb')).resolves.toMatchObject([{
id: 'items',
databaseId: 'appdb',
partitionKeyPath: '/category',
}])
await expect(adapter.listCosmosItems('appdb', 'items')).resolves.toMatchObject([{
id: 'item-1',
databaseId: 'appdb',
containerId: 'items',
partitionKey: 'demo',
etag: 'doc-etag',
document: {id: 'item-1', category: 'demo', _etag: '"doc-etag"', _ts: 1779307201},
}])
})
test('sends document partition key when deleting an item', async () => {
const calls: Array<{path: string; init: RequestInit}> = []
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs/appdb/colls/items/docs/item-1': null,
}, calls))
await adapter.deleteCosmosItem('appdb', 'items', 'item-1', 'demo')
expect(calls[0].path).toBe('/dbs/appdb/colls/items/docs/item-1')
expect(calls[0].init.method).toBe('DELETE')
expect(calls[0].init.headers).toMatchObject({'x-ms-documentdb-partitionkey': '["demo"]'})
})
test('queries documents using the Cosmos SQL query endpoint', async () => {
const calls: Array<{path: string; init: RequestInit}> = []
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs/appdb/colls/items/docs': {
_count: 1,
Documents: [{id: 'item-1'}],
},
}, calls))
await expect(adapter.queryCosmosItems('appdb', 'items', 'SELECT * FROM c')).resolves.toEqual({
count: 1,
items: [{id: 'item-1'}],
})
expect(calls[0].path).toBe('/dbs/appdb/colls/items/docs')
expect(calls[0].init.method).toBe('POST')
expect(calls[0].init.headers).toMatchObject({'x-ms-documentdb-isquery': 'True'})
})
test('falls back to account-suffixed path when root routing is not implemented', async () => {
const calls: Array<{path: string; init: RequestInit}> = []
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs': 'not-implemented',
'/devstoreaccount1-cosmos/dbs': {
_count: 1,
Databases: [{id: 'fallbackdb'}],
},
}, calls))
await expect(adapter.list()).resolves.toMatchObject([{id: 'fallbackdb'}])
expect(calls.map((call) => call.path).filter((path) => path.endsWith('/dbs'))).toEqual(['/dbs', '/devstoreaccount1-cosmos/dbs'])
})
test('falls back to named NoSQL engine path after root and default account routes fail', async () => {
const calls: Array<{path: string; init: RequestInit}> = []
const adapter = new AzureNoSqlAdapter(testClient({
'/dbs': 'not-implemented',
'/devstoreaccount1-cosmos/dbs': 'not-implemented',
'/devstoreaccount1-cosmos-nosql/dbs': {
_count: 1,
Databases: [{id: 'nosqldb'}],
},
}, calls))
await expect(adapter.list()).resolves.toMatchObject([{id: 'nosqldb'}])
expect(calls.map((call) => call.path).filter((path) => path.endsWith('/dbs'))).toEqual([
'/dbs',
'/devstoreaccount1-cosmos/dbs',
'/devstoreaccount1-cosmos-nosql/dbs',
])
})
})
function testClient(responses: Record<string, unknown>, calls: Array<{path: string; init: RequestInit}> = []): AzureRuntimeClient {
return {
endpoint: 'http://localhost:4577',
accountName: 'devstoreaccount1',
async fetch(path: string, init: RequestInit, options: AzureRuntimeFetchOptions = {}) {
calls.push({path, init})
if (responses[path] === 'not-implemented') {
throw new Error('Azure runtime request failed: HTTP 501')
}
if (!(path in responses)) {
if (options.emptyOnNotFound) return null
return new Response('Not Found', {status: 404})
}
return new Response(JSON.stringify(responses[path]), {status: 200, headers: {'content-type': 'application/json'}})
},
}
}