Skip to content

Commit

Permalink
change escalation chains searching to allow for partial searching (#1578
Browse files Browse the repository at this point in the history
)

# Which issue(s) this PR fixes

Previously if you had an Escalation Chain named "Something Critical" and
tried searching for "Critical", it would return no results. This was
because the backend was using a "starts-with" search on the `name`
attribute.

This PR changes that to use "partial searching" + adds a few e2e test
cases.

## Checklist

- [x] Tests updated
- [ ] Documentation added (N/A)
- [x] `CHANGELOG.md` updated
  • Loading branch information
joeyorlando authored Mar 20, 2023
1 parent 046d1dc commit 7ea5b07
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated wording throughout plugin to use 'Alert Group' instead of 'Incident' ([1565](https://github.com/grafana/oncall/pull/1565),
[1576](https://github.com/grafana/oncall/pull/1576))
- Filtering for Editors/Admins was added to rotation form. It is not allowed to assign Viewer to rotation ([1124](https://github.com/grafana/oncall/issues/1124))
- Modified search behaviour on the Escalation Chains page to allow for "partial searching" ([1578](https://github.com/grafana/oncall/pull/1578))

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion engine/apps/api/views/escalation_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class EscalationChainViewSet(
}

filter_backends = [SearchFilter]
search_fields = ("^name",)
search_fields = ("name",)

serializer_class = EscalationChainSerializer
list_serializer_class = EscalationChainListSerializer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { test, expect, Page } from '@playwright/test';
import { configureOnCallPlugin } from '../utils/configurePlugin';
import { generateRandomValue } from '../utils/forms';
import { createEscalationChain } from '../utils/escalationChain';

test.beforeEach(async ({ page }) => {
await configureOnCallPlugin(page);
});

const assertEscalationChainSearchWorks = async (
page: Page,
searchTerm: string,
escalationChainFullName: string
): Promise<void> => {
await page.getByTestId('escalation-chain-search-input').fill(searchTerm);

// wait for the API call(s) to finish
await page.waitForLoadState('networkidle');

await expect(page.getByTestId('escalation-chains-list')).toHaveText(escalationChainFullName);
};

test('searching allows case-insensitive partial matches', async ({ page }) => {
const escalationChainName = `${generateRandomValue()} ${generateRandomValue()}`;
const [firstHalf, secondHalf] = escalationChainName.split(' ');

await createEscalationChain(page, escalationChainName);

await assertEscalationChainSearchWorks(page, firstHalf, escalationChainName);
await assertEscalationChainSearchWorks(page, firstHalf.toUpperCase(), escalationChainName);
await assertEscalationChainSearchWorks(page, firstHalf.toLowerCase(), escalationChainName);

await assertEscalationChainSearchWorks(page, secondHalf, escalationChainName);
await assertEscalationChainSearchWorks(page, secondHalf.toUpperCase(), escalationChainName);
await assertEscalationChainSearchWorks(page, secondHalf.toLowerCase(), escalationChainName);
});
2 changes: 1 addition & 1 deletion grafana-plugin/integration-tests/utils/alertGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const incidentTimelineContainsStep = async (page: Page, triggeredStepText: strin
return Promise.resolve(false);
}

if (!page.locator('div[data-testid="incident-timeline-list"]').getByText(triggeredStepText)) {
if (!page.getByTestId('incident-timeline-list').getByText(triggeredStepText)) {
await page.reload({ waitUntil: 'networkidle' });
return incidentTimelineContainsStep(page, triggeredStepText, (retryNum += 1));
}
Expand Down
6 changes: 3 additions & 3 deletions grafana-plugin/integration-tests/utils/escalationChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const escalationStepValuePlaceholder: Record<EscalationStep, string> = {
export const createEscalationChain = async (
page: Page,
escalationChainName: string,
escalationStep: EscalationStep | null,
escalationStepValue: string | null
escalationStep?: EscalationStep,
escalationStepValue?: string
): Promise<void> => {
// go to the escalation chains page
await goToOnCallPage(page, 'escalations');
Expand All @@ -32,7 +32,7 @@ export const createEscalationChain = async (
await clickButton({ page, buttonText: 'Create' });
await page.waitForSelector(`text=${escalationChainName}`);

if (!escalationStep) {
if (!escalationStep || !escalationStepValue) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion grafana-plugin/integration-tests/utils/integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const createIntegrationAndSendDemoAlert = async (
await fillInInput(page, 'div[data-testid="edit-integration-name-modal"] >> input', integrationName);
await clickButton({ page, buttonText: 'Update' });

const integrationSettingsElement = page.locator('div[data-testid="integration-settings"]');
const integrationSettingsElement = page.getByTestId('integration-settings');

// assign the escalation chain to the integration
await selectDropdownValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const EscalationsFilters: FC<EscalationsFiltersProps> = (props) => {
<div className={cx('root')}>
<Input
autoFocus
data-testid="escalation-chain-search-input"
className={cx('search')}
prefix={<Icon name="search" />}
placeholder="Search escalations..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class EscalationChainsPage extends React.Component<EscalationChainsPageProps, Es
</Button>
</WithPermissionControlTooltip>
)}
<div className={cx('escalations-list')}>
<div className={cx('escalations-list')} data-testid="escalation-chains-list">
{searchResult ? (
<GList
autoScroll
Expand Down

0 comments on commit 7ea5b07

Please sign in to comment.