Skip to content

Commit

Permalink
Add auth override integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
slvrtrn committed Jun 6, 2024
1 parent 72f0fa2 commit febb18e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 10 deletions.
81 changes: 75 additions & 6 deletions packages/client-common/__tests__/integration/auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { type ClickHouseClient } from '@clickhouse/client-common'
import { createTestClient } from '../utils'
import { createSimpleTable } from '@test/fixtures/simple_table'
import { getAuthFromEnv } from '@test/utils/env'
import { createTestClient, guid } from '../utils'

describe('authentication', () => {
let client: ClickHouseClient
afterEach(async () => {
await client.close()
})

it('provides authentication error details', async () => {
beforeEach(() => {
client = createTestClient({
username: 'gibberish',
password: 'gibberish',
})
})
afterEach(async () => {
await client.close()
})

it('provides authentication error details', async () => {
await expectAsync(
client.query({
query: 'SELECT number FROM system.numbers LIMIT 3',
Expand All @@ -25,4 +28,70 @@ describe('authentication', () => {
}),
)
})

describe('auth override', () => {
let defaultClient: ClickHouseClient
beforeAll(() => {
defaultClient = createTestClient()
})
afterAll(async () => {
await defaultClient.close()
})

let tableName: string
const values = [
{
id: '1',
name: 'foo',
sku: [3, 4],
},
]
const auth = getAuthFromEnv()

it('should with with insert and select', async () => {
tableName = `simple_table_${guid()}`
await createSimpleTable(defaultClient, tableName)
await client.insert({
table: tableName,
format: 'JSONEachRow',
values,
auth,
})
const rs = await client.query({
query: `SELECT * FROM ${tableName} ORDER BY id ASC`,
format: 'JSONEachRow',
auth,
})
expect(await rs.json()).toEqual(values)
})

it('should work with command and select', async () => {
tableName = `simple_table_${guid()}`
await createSimpleTable(defaultClient, tableName)
await client.command({
query: `INSERT INTO ${tableName} VALUES (1, 'foo', [3, 4])`,
auth,
})
const rs = await client.query({
query: `SELECT * FROM ${tableName} ORDER BY id ASC`,
format: 'JSONEachRow',
auth,
})
expect(await rs.json()).toEqual(values)
})

it('should work with exec', async () => {
const { stream } = await client.exec({
query: 'SELECT 42, 144 FORMAT CSV',
auth,
})
let result = ''
const textDecoder = new TextDecoder()
// @ts-expect-error - ReadableStream (Web) or Stream.Readable (Node.js); same API.
for await (const chunk of stream) {
result += textDecoder.decode(chunk, { stream: true })
}
expect(result).toEqual('42,144\n')
})
})
})
6 changes: 3 additions & 3 deletions packages/client-common/__tests__/utils/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
ClickHouseClient,
ClickHouseSettings,
} from '@clickhouse/client-common'
import { getFromEnv } from './env'
import { EnvKeys, getFromEnv } from './env'
import { guid } from './guid'
import {
getClickHouseTestEnvironment,
Expand Down Expand Up @@ -55,8 +55,8 @@ export function createTestClient<Stream = unknown>(
}
if (isCloudTestEnv()) {
const cloudConfig: BaseClickHouseClientConfigOptions = {
url: `https://${getFromEnv('CLICKHOUSE_CLOUD_HOST')}:8443`,
password: getFromEnv('CLICKHOUSE_CLOUD_PASSWORD'),
url: `https://${getFromEnv(EnvKeys.host)}:8443`,
password: getFromEnv(EnvKeys.password),
database: databaseName,
...logging,
...config,
Expand Down
12 changes: 12 additions & 0 deletions packages/client-common/__tests__/utils/env.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
export const EnvKeys = {
host: 'CLICKHOUSE_CLOUD_HOST',
username: 'CLICKHOUSE_CLOUD_USERNAME',
password: 'CLICKHOUSE_CLOUD_PASSWORD',
}

export function getFromEnv(key: string): string {
const value = process.env[key]
if (value === undefined) {
throw Error(`Environment variable ${key} is not set`)
}
return value
}

export function getAuthFromEnv() {
const username = process.env[EnvKeys.username]
const password = process.env[EnvKeys.password]
return { username: username ?? 'default', password: password ?? '' }
}
8 changes: 7 additions & 1 deletion packages/client-web/src/connection/web_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,13 @@ export class WebConnection implements Connection<ReadableStream> {

try {
const headers = withCompressionHeaders({
headers: this.defaultHeaders,
headers:
params?.auth !== undefined
? {
...this.defaultHeaders,
Authorization: `Basic ${btoa(`${params.auth.username}:${params.auth.password}`)}`,
}
: this.defaultHeaders,
compress_request: false,
decompress_response: this.params.compression.decompress_response,
})
Expand Down

0 comments on commit febb18e

Please sign in to comment.