Skip to content
Merged
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
25 changes: 25 additions & 0 deletions src/renderer/components/filters/AccountFilter.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { renderWithProviders } from '../../__helpers__/test-utils';
import { mockMultipleAccountNotifications } from '../../__mocks__/notifications-mocks';
import { mockAuth } from '../../__mocks__/state-mocks';

import { AccountFilter } from './AccountFilter';

describe('renderer/components/filters/AccountFilter.tsx', () => {
it('should count notifications from the current filtered list per account', () => {
const tree = renderWithProviders(<AccountFilter />, {
accounts: mockAuth.accounts,
notifications: mockMultipleAccountNotifications,
});

const counters = Array.from(
tree.container.querySelectorAll('span.text-gitify-counter-text'),
).map((el) => Number.parseInt(el.textContent ?? '0', 10));

expect(counters.reduce((sum, value) => sum + value, 0)).toBe(
mockMultipleAccountNotifications.reduce(
(sum, account) => sum + account.notifications.length,
0,
),
);
});
});
80 changes: 79 additions & 1 deletion src/renderer/components/filters/FilterSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import userEvent from '@testing-library/user-event';
import { MarkGithubIcon } from '@primer/octicons-react';

import { renderWithProviders } from '../../__helpers__/test-utils';
import { mockMultipleAccountNotifications } from '../../__mocks__/notifications-mocks';
import {
mockMultipleAccountNotifications,
mockPartialGitifyNotification,
} from '../../__mocks__/notifications-mocks';
import { mockSettings } from '../../__mocks__/state-mocks';

import { useFiltersStore } from '../../stores';
Expand Down Expand Up @@ -116,4 +119,79 @@ describe('renderer/components/filters/FilterSection.tsx', () => {

expect(updateFilterSpy).toHaveBeenCalledWith(mockFilterSetting, 'closed', true);
});

it('should count notifications from the currently filtered list', () => {
const filteredNotifications = [
mockPartialGitifyNotification({ state: 'OPEN' }),
mockPartialGitifyNotification({ state: 'CLOSED' }),
mockPartialGitifyNotification({ state: 'MERGED' }),
].map((notification) => ({
account: notification.account,
notifications: [notification],
error: null,
}));

renderWithProviders(
<FilterSection
filter={mockFilter}
filterSetting={mockFilterSetting}
icon={MarkGithubIcon}
id={'FilterSectionTest'}
title={'FilterSectionTitle'}
/>,
{
settings: {
...mockSettings,
detailedNotifications: true,
},
notifications: filteredNotifications,
},
);

const counters = getCounterValues();
expect(counters.reduce((sum, value) => sum + value, 0)).toBe(3);
});

it('should rescale counts when a filter in another section is toggled', () => {
renderWithProviders(
<FilterSection
filter={mockFilter}
filterSetting={mockFilterSetting}
icon={MarkGithubIcon}
id={'FilterSectionTest'}
title={'FilterSectionTitle'}
/>,
{
settings: {
...mockSettings,
detailedNotifications: true,
},
notifications: [
mockPartialGitifyNotification({ state: 'OPEN' }),
mockPartialGitifyNotification({ state: 'CLOSED' }),
mockPartialGitifyNotification({ state: 'MERGED' }),
].map((notification) => ({
account: notification.account,
notifications: [notification],
error: null,
})),
},
);

const before = getCounterValues();
expect(before.reduce((sum, value) => sum + value, 0)).toBe(3);

act(() => {
useFiltersStore.getState().updateFilter('reasons', 'mention', true);
});

const after = getCounterValues();
expect(after).toEqual(before);
});

function getCounterValues(): number[] {
return Array.from(document.querySelectorAll('span.text-gitify-counter-text')).map((el) =>
Number.parseInt(el.textContent ?? '0', 10),
);
}
});
15 changes: 11 additions & 4 deletions src/renderer/components/filters/FilterSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,19 @@ const FilterSectionComponent = <K extends keyof FiltersState>({

<Stack direction={layout} gap={layout === 'horizontal' ? 'normal' : 'condensed'}>
{(Object.keys(filter.FILTER_TYPES) as FiltersState[K][number][])
.sort((a, b) =>
filter
.sort((a, b) => {
// Always pin the catch-all 'other' option to the end of the list.
if ((a as string) === 'other') {
return 1;
}
if ((b as string) === 'other') {
return -1;
}
return filter
.getTypeDetails(a)
.title.toLowerCase()
.localeCompare(filter.getTypeDetails(b).title.toLowerCase(), 'en'),
)
.localeCompare(filter.getTypeDetails(b).title.toLowerCase(), 'en');
})
.map((type) => {
const typeDetails = filter.getTypeDetails(type);
const typeTitle = typeDetails.title;
Expand Down
15 changes: 11 additions & 4 deletions src/renderer/components/filters/ReviewRequestTypeFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FC } from 'react';

import { GitPullRequestIcon } from '@primer/octicons-react';
import { Text } from '@primer/react';
import { Stack, Text } from '@primer/react';

import { reviewRequestTypeFilter } from '../../utils/notifications/filters';
import { FilterSection } from './FilterSection';
Expand All @@ -15,9 +15,16 @@ export const ReviewRequestTypeFilter: FC = () => {
id="filter-review-request-types"
title="Review Request Type"
tooltip={
<Text>
Filter review requests by whether you were directly requested or requested via a team.
</Text>
<Stack direction="vertical" gap="condensed">
<Text>
Filter review requests by whether you were directly requested or requested via a team.
Selecting an option shows only matching review requests.
</Text>
<Text>
Other shows all notifications that are not a review request, such as mentions, comments,
and assigned issues.
</Text>
</Stack>
}
/>
);
Expand Down
8 changes: 7 additions & 1 deletion src/renderer/components/filters/UserTypeFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const UserTypeFilter: FC = () => {
filterSetting="userTypes"
icon={FeedPersonIcon}
id="filter-user-types"
layout="horizontal"
title="User Type"
tooltip={
<Stack direction="vertical" gap="condensed">
Expand All @@ -39,8 +38,15 @@ export const UserTypeFilter: FC = () => {
<OrganizationIcon size={Size.SMALL} />
{userTypeFilter.FILTER_TYPES.Organization.title}
</Stack>
<Stack direction="horizontal" gap="condensed">
<PersonIcon size={Size.SMALL} />
{userTypeFilter.FILTER_TYPES.other.title}
</Stack>
</Stack>
</div>
<Text>
Other covers notifications with no author or a non-human, non-organization author.
</Text>
</Stack>
}
/>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading