import { describe, expect, it } from 'vitest'; import { FormComponentType, getRowItemsFromSectionItem } from '../../types/index.js'; import { PostgresPlugin } from './postgres.js'; const datasourceItems = PostgresPlugin.datasourceTemplate?.sections.flatMap((section) => section.items.flatMap(getRowItemsFromSectionItem)); const findDatasourceItems = (name: string) => datasourceItems?.filter((item) => item.name === name) ?? []; describe('Postgres datasource template', () => { it('gates IAM fields only by Postgres plugin version 0.0.13', () => { const iamFieldNames = [ 'authentication.authType', 'authentication.custom.databaseName.value', 'authentication.custom.iamRoleArn.value', 'authentication.custom.region.value', 'authentication.custom.sessionPolicy.value', 'authentication.username', 'connection.useSsl' ]; for (const fieldName of iamFieldNames) { const versionThirteenItems = findDatasourceItems(fieldName).filter((item) => item.startVersion === '0.0.13'); expect(versionThirteenItems.length).toBeGreaterThan(0); expect(versionThirteenItems.every((item) => item.ldFlag === undefined)).toBe(true); } }); it('adds the version 0.0.13 authentication method and IAM role fields', () => { expect(findDatasourceItems('authentication.authType')).toEqual([ expect.objectContaining({ componentType: FormComponentType.DROPDOWN, display: { show: { connectionType: ['fields'] } }, initialValue: 'password', options: [ { displayName: 'Username & password', key: 'password', value: 'password' }, { displayName: 'AWS IAM Role', key: 'aws_iam_role', value: 'aws_iam_role' } ], startVersion: '0.0.13' }) ]); expect(findDatasourceItems('authentication.custom.iamRoleArn.value')).toEqual([ expect.objectContaining({ display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, rules: [{ message: 'Role ARN is required', required: true }], startVersion: '0.0.13' }) ]); expect(findDatasourceItems('authentication.custom.region.value')).toEqual([ expect.objectContaining({ display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, rules: [{ message: 'Region is required', required: true }], startVersion: '0.0.13' }) ]); expect(findDatasourceItems('authentication.custom.sessionPolicy.value')).toEqual([ expect.objectContaining({ display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, rules: [{ required: false }], startVersion: '0.0.13', style: { height: '100px' } }) ]); }); it('places session policy after the required IAM username field', () => { const iamFieldOrder = datasourceItems ?.filter((item) => item.startVersion === '0.0.13') .filter((item) => item.display?.show?.['authentication.authType']?.includes('aws_iam_role')) .map((item) => item.name) ?? []; const usernameIndex = iamFieldOrder.indexOf('authentication.username'); const sessionPolicyIndex = iamFieldOrder.indexOf('authentication.custom.sessionPolicy.value'); expect(usernameIndex).toBeGreaterThanOrEqual(0); expect(sessionPolicyIndex).toBeGreaterThan(usernameIndex); }); it('keeps username visible and password compatible with legacy configurations', () => { expect(findDatasourceItems('authentication.username')).toEqual([ expect.objectContaining({ endVersion: '0.0.10', startVersion: '0.0.1' }), expect.objectContaining({ display: { show: { connectionType: ['fields'] } }, endVersion: '0.0.12', startVersion: '0.0.11' }), expect.objectContaining({ display: { show: { 'authentication.authType': ['', 'undefined', 'password'], connectionType: ['fields'] } }, startVersion: '0.0.13' }), expect.objectContaining({ display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, rules: [{ message: 'Database username is required', required: true }], startVersion: '0.0.13' }) ]); expect(findDatasourceItems('authentication.password')).toEqual([ expect.objectContaining({ endVersion: '0.0.10', startVersion: '0.0.1' }), expect.objectContaining({ display: { show: { connectionType: ['fields'] } }, endVersion: '0.0.12', startVersion: '0.0.11' }), expect.objectContaining({ display: { show: { 'authentication.authType': ['', 'undefined', 'password'], connectionType: ['fields'] } }, startVersion: '0.0.13' }) ]); }); it('requires a database name only for IAM role authentication', () => { expect(findDatasourceItems('authentication.custom.databaseName.value')).toEqual([ expect.objectContaining({ endVersion: '0.0.10', startVersion: '0.0.1' }), expect.objectContaining({ display: { show: { connectionType: ['fields'] } }, endVersion: '0.0.12', startVersion: '0.0.11' }), expect.objectContaining({ display: { show: { 'authentication.authType': ['', 'undefined', 'password'], connectionType: ['fields'] } }, startVersion: '0.0.13' }), expect.objectContaining({ display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, rules: [{ message: 'Database name is required', required: true }], startVersion: '0.0.13' }) ]); }); it('requires TLS for IAM role authentication without changing password mode', () => { expect(findDatasourceItems('connection.useSsl')).toEqual([ expect.objectContaining({ endVersion: '0.0.10', startVersion: '0.0.1' }), expect.objectContaining({ display: { show: { connectionType: ['fields'] } }, endVersion: '0.0.12', startVersion: '0.0.11' }), expect.objectContaining({ disabled: false, display: { show: { 'authentication.authType': ['', 'undefined', 'password'], connectionType: ['fields'] } }, initialValue: true, startVersion: '0.0.13' }), expect.objectContaining({ disabled: true, display: { show: { 'authentication.authType': ['aws_iam_role'], connectionType: ['fields'] } }, initialValue: true, rules: [{ enum: [true], message: 'SSL is required for AWS IAM role authentication' }], startVersion: '0.0.13' }) ]); }); });