Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions superset-frontend/src/features/databases/DatabaseModal/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,63 @@ describe('DatabaseModal', () => {
expect(screen.getByTestId('sqlalchemy-uri-input')).toBeInTheDocument();
});

test('keeps dynamic form values when toggling to the URI form and back', async () => {
setup();
await selectPostgres();

const values: Record<string, string> = {
host: 'db.example.com',
port: '5432',
database: 'example_db',
username: 'example_user',
password: 'example_password',
};
Object.entries(values).forEach(([name, value]) => {
fireEvent.change(fieldByName(name), { target: { value } });
expect(fieldByName(name)).toHaveDisplayValue(value);
});

await userEvent.click(screen.getByTestId('sqla-connect-btn'));
expect(
await screen.findByTestId('sqlalchemy-uri-input'),
).toBeInTheDocument();
await userEvent.click(
screen.getByRole('button', {
name: /connect this database using the dynamic form instead/i,
}),
);

expect(await screen.findByText(/step 2 of 3/i)).toBeInTheDocument();
Object.entries(values).forEach(([name, value]) => {
expect(fieldByName(name)).toHaveDisplayValue(value);
});
expect(fieldByName('database_name')).toHaveDisplayValue('PostgreSQL');
});

test('keeps a typed SQLAlchemy URI when toggling to the dynamic form and back', async () => {
setup();
await selectPostgres();

await userEvent.click(screen.getByTestId('sqla-connect-btn'));
const typedUri =
'postgresql://example_user:example_password@db.example.com:5432/example_db';
const uriInput = await screen.findByTestId('sqlalchemy-uri-input');
await userEvent.type(uriInput, typedUri);
expect(uriInput).toHaveValue(typedUri);

await userEvent.click(
screen.getByRole('button', {
name: /connect this database using the dynamic form instead/i,
}),
);
expect(await screen.findByText(/step 2 of 3/i)).toBeInTheDocument();
await userEvent.click(screen.getByTestId('sqla-connect-btn'));

expect(await screen.findByTestId('sqlalchemy-uri-input')).toHaveValue(
typedUri,
);
});

test.each([
{
field: 'host',
Expand Down Expand Up @@ -2687,6 +2744,62 @@ describe('dbReducer', () => {
});
});

test('ConfigMethodChange preserves previous fields and applies the new configuration method', () => {
const initialState: Partial<DatabaseObject> = {
database_name: 'Example DB',
engine: 'postgresql',
driver: 'psycopg2',
configuration_method: ConfigurationMethod.DynamicForm,
parameters: {
host: 'db.example.com',
port: 5432,
database: 'example_db',
username: 'example_user',
},
sqlalchemy_uri:
'postgresql://example_user@db.example.com:5432/example_db',
masked_encrypted_extra: '{}',
extra: '{"allows_virtual_table_explore":true}',
expose_in_sqllab: true,
engine_information: { supports_file_upload: true },
};
const action: DBReducerActionType = {
type: ActionType.ConfigMethodChange,
payload: {
database_name: initialState.database_name,
engine: initialState.engine,
configuration_method: ConfigurationMethod.SqlalchemyUri,
},
};

expect(dbReducer(initialState, action)).toEqual({
...initialState,
configuration_method: ConfigurationMethod.SqlalchemyUri,
});
});

test('ConfigMethodChange falls back to the previous database_name and engine', () => {
const initialState: Partial<DatabaseObject> = {
database_name: 'Example DB',
engine: 'postgresql',
configuration_method: ConfigurationMethod.DynamicForm,
};
const action: DBReducerActionType = {
type: ActionType.ConfigMethodChange,
payload: {
database_name: undefined,
engine: undefined,
configuration_method: ConfigurationMethod.SqlalchemyUri,
},
};

expect(dbReducer(initialState, action)).toEqual({
database_name: 'Example DB',
engine: 'postgresql',
configuration_method: ConfigurationMethod.SqlalchemyUri,
});
});

// Regression test for https://github.com/apache/superset/issues/30504
// When creating a database, the POST response doesn't include engine_information,
// but it should be preserved from the state populated when the user selects a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,14 @@ export function dbReducer(
expose_in_sqllab: true,
};
case ActionType.ConfigMethodChange:
// Switching connection mode keeps everything already entered so that
// toggling back and forth does not discard the user's input.
return {
...trimmedState,
...action.payload,
database_name:
action.payload.database_name ?? trimmedState.database_name,
engine: action.payload.engine ?? trimmedState.engine,
};

case ActionType.Reset:
Expand Down
Loading