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
8 changes: 4 additions & 4 deletions src/main/updater.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ describe('main/updater.ts', () => {
});

it('performs initial check and schedules periodic checks', async () => {
const originalSetInterval = global.setInterval;
const originalSetInterval = globalThis.setInterval;
const setIntervalSpy = jest
.spyOn(global, 'setInterval')
.spyOn(globalThis, 'setInterval')
.mockImplementation(((fn: () => void) => {
fn();
return 0 as unknown as NodeJS.Timer;
return 0 as unknown as NodeJS.Timeout;
}) as unknown as typeof setInterval);
try {
await updater.start();
Expand All @@ -224,7 +224,7 @@ describe('main/updater.ts', () => {
);
} finally {
setIntervalSpy.mockRestore();
global.setInterval = originalSetInterval;
globalThis.setInterval = originalSetInterval;
}
});
});
Expand Down
76 changes: 76 additions & 0 deletions src/renderer/__helpers__/test-utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { render } from '@testing-library/react';
import type { ReactElement, ReactNode } from 'react';
import { useMemo } from 'react';

import { BaseStyles, ThemeProvider } from '@primer/react';

import { mockAuth, mockSettings } from '../__mocks__/state-mocks';
import type { AppContextState } from '../context/App';
import { AppContext } from '../context/App';

/**
* Props for the AppContextProvider wrapper
*/
interface AppContextProviderProps {
readonly children: ReactNode;
readonly value?: Partial<AppContextState>;
}

/**
* Wrapper component that provides ThemeProvider, BaseStyles, and AppContext
* with sensible defaults for testing.
*/
export function AppContextProvider({
children,
value = {},
}: AppContextProviderProps) {
const defaultValue: Partial<AppContextState> = useMemo(() => {
return {
auth: mockAuth,
settings: mockSettings,

notifications: [],

status: 'success',
globalError: null,

...value,
} as Partial<AppContextState>;
}, [value]);

return (
<ThemeProvider>
<BaseStyles>
<AppContext.Provider value={defaultValue}>
{children}
</AppContext.Provider>
</BaseStyles>
</ThemeProvider>
);
}

/**
* Custom render that wraps components with AppContextProvider by default.
*
* Usage:
* renderWithAppContext(<MyComponent />, { auth, settings, ... })
*/
export function renderWithAppContext(
ui: ReactElement,
context: Partial<AppContextState> = {},
) {
const value: Partial<AppContextState> = { ...context };

return render(ui, {
wrapper: ({ children }) => (
<AppContextProvider value={value}>{children}</AppContextProvider>
),
});
}

/**
* Ensure stable snapshots for our randomized emoji use-cases
*/
export function ensureStableEmojis() {
global.Math.random = jest.fn(() => 0.1);
}
63 changes: 63 additions & 0 deletions src/renderer/__mocks__/account-mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Constants } from '../constants';
import type {
Account,
AccountNotifications,
GitifyError,
Hostname,
Token,
} from '../types';
import { mockGitifyUser } from './user-mocks';

export const mockPersonalAccessTokenAccount: Account = {
platform: 'GitHub Cloud',
method: 'Personal Access Token',
token: 'token-123-456' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockOAuthAccount: Account = {
platform: 'GitHub Enterprise Server',
method: 'OAuth App',
token: '1234568790' as Token,
hostname: 'github.gitify.io' as Hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockGitHubCloudAccount: Account = {
platform: 'GitHub Cloud',
method: 'Personal Access Token',
token: 'token-123-456' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
version: 'latest',
hasRequiredScopes: true,
};

export const mockGitHubEnterpriseServerAccount: Account = {
platform: 'GitHub Enterprise Server',
method: 'Personal Access Token',
token: '1234568790' as Token,
hostname: 'github.gitify.io' as Hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockGitHubAppAccount: Account = {
platform: 'GitHub Cloud',
method: 'GitHub App',
token: '987654321' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export function mockAccountWithError(error: GitifyError): AccountNotifications {
return {
account: mockGitHubCloudAccount,
notifications: [],
error,
};
}
74 changes: 45 additions & 29 deletions src/renderer/__mocks__/notifications-mocks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { AccountNotifications, GitifyError } from '../types';
import { Constants } from '../constants';
import type { AccountNotifications, Hostname } from '../types';
import type {
Notification,
Repository,
StateType,
Subject,
SubjectType,
Expand All @@ -13,30 +15,11 @@ import {
import {
mockGitHubCloudAccount,
mockGitHubEnterpriseServerAccount,
} from './state-mocks';
} from './account-mocks';
import { mockToken } from './state-mocks';
import { mockGitifyUser } from './user-mocks';

export const mockAccountNotifications: AccountNotifications[] = [
{
account: mockGitHubCloudAccount,
notifications: mockGitHubNotifications,
error: null,
},
{
account: mockGitHubEnterpriseServerAccount,
notifications: mockEnterpriseNotifications,
error: null,
},
];

export const mockSingleAccountNotifications: AccountNotifications[] = [
{
account: mockGitHubCloudAccount,
notifications: [mockSingleNotification],
error: null,
},
];

export function createSubjectMock(mocks: {
export function createMockSubject(mocks: {
title?: string;
type?: SubjectType;
state?: StateType;
Expand All @@ -50,12 +33,24 @@ export function createSubjectMock(mocks: {
};
}

export function mockAccountWithError(error: GitifyError): AccountNotifications {
return {
account: mockGitHubCloudAccount,
notifications: [],
error,
export function createPartialMockNotification(
subject: Partial<Subject>,
repository?: Partial<Repository>,
): Notification {
const mockNotification: Partial<Notification> = {
account: {
method: 'Personal Access Token',
platform: 'GitHub Cloud',
hostname: Constants.GITHUB_API_BASE_URL as Hostname,
token: mockToken,
user: mockGitifyUser,
hasRequiredScopes: true,
},
subject: subject as Subject,
repository: repository as Repository,
};

return mockNotification as Notification;
}

export function createMockNotificationForRepoName(
Expand All @@ -68,3 +63,24 @@ export function createMockNotificationForRepoName(
account: mockGitHubCloudAccount,
} as Notification;
}

export const mockAccountNotifications: AccountNotifications[] = [
{
account: mockGitHubCloudAccount,
notifications: mockGitHubNotifications,
error: null,
},
{
account: mockGitHubEnterpriseServerAccount,
notifications: mockEnterpriseNotifications,
error: null,
},
];

export const mockSingleAccountNotifications: AccountNotifications[] = [
{
account: mockGitHubCloudAccount,
notifications: [mockSingleNotification],
error: null,
},
];
35 changes: 0 additions & 35 deletions src/renderer/__mocks__/partial-mocks.ts

This file was deleted.

61 changes: 4 additions & 57 deletions src/renderer/__mocks__/state-mocks.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { Constants } from '../constants';
import {
type Account,
type AppearanceSettingsState,
type AuthState,
FetchType,
type FilterSettingsState,
type GitifyState,
type GitifyUser,
GroupBy,
type Hostname,
type Link,
type NotificationSettingsState,
OpenPreference,
type Percentage,
Expand All @@ -19,59 +15,10 @@ import {
type Token,
type TraySettingsState,
} from '../types';

export const mockGitifyUser: GitifyUser = {
login: 'octocat',
name: 'Mona Lisa Octocat',
id: 123456789,
avatar: 'https://avatars.githubusercontent.com/u/583231?v=4' as Link,
};

export const mockPersonalAccessTokenAccount: Account = {
platform: 'GitHub Cloud',
method: 'Personal Access Token',
token: 'token-123-456' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockOAuthAccount: Account = {
platform: 'GitHub Enterprise Server',
method: 'OAuth App',
token: '1234568790' as Token,
hostname: 'github.gitify.io' as Hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockGitHubCloudAccount: Account = {
platform: 'GitHub Cloud',
method: 'Personal Access Token',
token: 'token-123-456' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
version: 'latest',
hasRequiredScopes: true,
};

export const mockGitHubEnterpriseServerAccount: Account = {
platform: 'GitHub Enterprise Server',
method: 'Personal Access Token',
token: '1234568790' as Token,
hostname: 'github.gitify.io' as Hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};

export const mockGitHubAppAccount: Account = {
platform: 'GitHub Cloud',
method: 'GitHub App',
token: '987654321' as Token,
hostname: Constants.DEFAULT_AUTH_OPTIONS.hostname,
user: mockGitifyUser,
hasRequiredScopes: true,
};
import {
mockGitHubCloudAccount,
mockGitHubEnterpriseServerAccount,
} from './account-mocks';

export const mockAuth: AuthState = {
accounts: [mockGitHubCloudAccount, mockGitHubEnterpriseServerAccount],
Expand Down
Loading
Loading