The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/features/auth-config/ProviderConfigForm.test.tsx

196 lines
6.7 KiB

import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React, { JSX } from 'react';
import { reportInteraction } from '@grafana/runtime';
import { ProviderConfigForm } from './ProviderConfigForm';
import { SSOProvider } from './types';
import { emptySettings } from './utils/data';
const putMock = jest.fn(() => Promise.resolve({}));
const deleteMock = jest.fn(() => Promise.resolve({}));
jest.mock('@grafana/runtime', () => ({
getBackendSrv: () => ({
put: putMock,
delete: deleteMock,
}),
config: {
panels: {
test: {
id: 'test',
name: 'test',
},
},
},
getAppEvents: () => ({
publish: jest.fn(),
}),
isFetchError: () => true,
locationService: {
push: jest.fn(),
},
reportInteraction: jest.fn(),
}));
const reportInteractionMock = jest.mocked(reportInteraction);
// Mock the FormPrompt component as it requires Router setup to work
jest.mock('app/core/components/FormPrompt/FormPrompt', () => ({
FormPrompt: () => <></>,
}));
const testConfig: SSOProvider = {
SSO Config: Add generic OAuth (#79972) * Setup route * Set up the page * Add orgs * Load settings * Make API call * Remove log * Add FormPrompt * Update types * Add tests * Fix tests * Cleanup * Load settings * Fix naming * Switch to PUT endpoint * Switch to CSS object * Setup fields * Render fields * Extend types * Dynamic provider page * Rename page * Filter out non-implemented providers * Fix types * Add teamIDs validation * Update tests * Fix URL * Update name * Send full data * Add password input * Update test * Expand default values * Fix test * Use SecretInput * Remove dev mode for the feature toggle * Convert fields * Remove fieldFormat utils * Update fields logic * Update tests * Update betterer * SSO: Add Generic OAuth page * SSO: Add Generic OAuth page * SSO: Make client secret not required * Update field name * Revert feature toggle to dev mode * Use provider endpoint * Fix form state check * Update tests * Fix URL redirect after form submit * Mock locationService * Separate Form component * Update fields * Add more fields * Add more fields * Fix spacing * Add UserMapping fields * Add rest of the fields * Add FieldRenderer * Update types * Update comment * Update feature toggle * Add checkbox * Do not submit form if there are errors * Fix revalidation * Redirect on success only * Fix redirect behavior * Add missing descriptions * Use inline checkbox * Add enabled field * Restore feature toggle * Remove source field from PUT request * Add URL to the fields * Add hidden prop to fields and sections * Add Delete button * Prettier * Add authStyle, still not working, description updates * Fix saving select values * Run prettier * Use defaultValue in Select field --------- Co-authored-by: Mihaly Gyongyosi <mgyongyosi@users.noreply.github.com>
2 years ago
id: '300f9b7c-0488-40db-9763-a22ce8bf6b3e',
provider: 'github',
source: 'database',
settings: {
...emptySettings,
name: 'GitHub',
type: 'OAuth',
clientId: '12345',
clientSecret: 'abcde',
enabled: true,
teamIds: '',
allowedOrganizations: '',
allowedDomains: '',
allowedGroups: '',
scopes: '',
},
};
const emptyConfig = {
...testConfig,
settings: { ...testConfig.settings, enabled: false, clientId: '', clientSecret: '' },
};
function setup(jsx: JSX.Element) {
return {
user: userEvent.setup(),
...render(jsx),
};
}
describe('ProviderConfigForm', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('renders all fields correctly', async () => {
setup(<ProviderConfigForm config={testConfig} provider={testConfig.provider} />);
expect(screen.getByRole('textbox', { name: /Client ID/i })).toBeInTheDocument();
expect(screen.getByRole('combobox', { name: /Team IDs/i })).toBeInTheDocument();
expect(screen.getByRole('combobox', { name: /Allowed organizations/i })).toBeInTheDocument();
expect(screen.getByRole('button', { name: /Save/i })).toBeInTheDocument();
expect(screen.getByRole('link', { name: /Discard/i })).toBeInTheDocument();
});
it('should save and enable on form submit', async () => {
const { user } = setup(<ProviderConfigForm config={emptyConfig} provider={emptyConfig.provider} />);
await user.type(screen.getByRole('textbox', { name: /Client ID/i }), 'test-client-id');
await user.type(screen.getByLabelText(/Client secret/i), 'test-client-secret');
// Type a team name and press enter to select it
await user.type(screen.getByRole('combobox', { name: /Team IDs/i }), '12324{enter}');
// Add two orgs
await user.type(screen.getByRole('combobox', { name: /Allowed organizations/i }), 'test-org1{enter}');
await user.type(screen.getByRole('combobox', { name: /Allowed organizations/i }), 'test-org2{enter}');
await user.click(screen.getByRole('button', { name: /Save and enable/i }));
await waitFor(() => {
expect(putMock).toHaveBeenCalledWith(
'/api/v1/sso-settings/github',
{
id: '300f9b7c-0488-40db-9763-a22ce8bf6b3e',
provider: 'github',
settings: {
name: 'GitHub',
allowedOrganizations: 'test-org1,test-org2',
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
teamIds: '12324',
enabled: true,
},
},
{ showErrorAlert: false }
);
expect(reportInteractionMock).toHaveBeenCalledWith('grafana_authentication_ssosettings_saved', {
provider: 'github',
enabled: true,
});
});
});
it('should save on form submit', async () => {
const { user } = setup(<ProviderConfigForm config={emptyConfig} provider={emptyConfig.provider} />);
await user.type(screen.getByRole('textbox', { name: /Client ID/i }), 'test-client-id');
await user.type(screen.getByLabelText(/Client secret/i), 'test-client-secret');
// Type a team name and press enter to select it
await user.type(screen.getByRole('combobox', { name: /Team IDs/i }), '12324{enter}');
// Add two orgs
await user.type(screen.getByRole('combobox', { name: /Allowed organizations/i }), 'test-org1{enter}');
await user.type(screen.getByRole('combobox', { name: /Allowed organizations/i }), 'test-org2{enter}');
await user.click(screen.getByText('Save'));
await waitFor(() => {
expect(putMock).toHaveBeenCalledWith(
'/api/v1/sso-settings/github',
{
id: '300f9b7c-0488-40db-9763-a22ce8bf6b3e',
provider: 'github',
settings: {
name: 'GitHub',
allowedOrganizations: 'test-org1,test-org2',
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
teamIds: '12324',
enabled: false,
},
},
{ showErrorAlert: false }
);
expect(reportInteractionMock).toHaveBeenCalledWith('grafana_authentication_ssosettings_saved', {
provider: 'github',
enabled: false,
});
});
});
it('should validate required fields on Save', async () => {
const { user } = setup(<ProviderConfigForm config={emptyConfig} provider={emptyConfig.provider} />);
await user.click(screen.getByText('Save'));
// Should show an alert for empty client ID
expect(await screen.findAllByRole('alert')).toHaveLength(1);
});
it('should validate required fields on Save and enable', async () => {
const { user } = setup(<ProviderConfigForm config={emptyConfig} provider={emptyConfig.provider} />);
await user.click(screen.getByRole('button', { name: /Save and enable/i }));
// Should show an alert for empty client ID
expect(await screen.findAllByRole('alert')).toHaveLength(1);
});
it('should delete the current config', async () => {
const { user } = setup(<ProviderConfigForm config={emptyConfig} provider={emptyConfig.provider} />);
await user.click(screen.getByTitle(/More actions/i));
await user.click(screen.getByRole('menuitem', { name: /Reset to default values/i }));
expect(screen.getByRole('dialog', { name: /Reset/i })).toBeInTheDocument();
await user.click(screen.getByTestId('data-testid Confirm Modal Danger Button'));
await waitFor(() => {
expect(deleteMock).toHaveBeenCalledWith('/api/v1/sso-settings/github', undefined, { showSuccessAlert: false });
expect(reportInteractionMock).toHaveBeenCalledWith('grafana_authentication_ssosettings_removed', {
provider: 'github',
});
});
});
});