-
Notifications
You must be signed in to change notification settings - Fork 254
Expand file tree
/
Copy pathupgradeToast.test.tsx
More file actions
119 lines (95 loc) · 4.1 KB
/
upgradeToast.test.tsx
File metadata and controls
119 lines (95 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { describe, expect, test, vi, beforeEach } from 'vitest'
import { getVersionFromString, getVersionString, compareVersions } from './upgradeToast';
// --- Pure utility function tests ---
describe('getVersionFromString', () => {
test('parses a valid semver string', () => {
expect(getVersionFromString('v1.2.3')).toEqual({ major: 1, minor: 2, patch: 3 });
});
test('returns null for invalid version strings', () => {
expect(getVersionFromString('not-a-version')).toBeNull();
expect(getVersionFromString('1.2.3')).toBeNull(); // missing v prefix
expect(getVersionFromString('v1.2')).toBeNull(); // missing patch
expect(getVersionFromString('v1.2.3-beta')).toBeNull(); // pre-release suffix
});
test('parses zero versions', () => {
expect(getVersionFromString('v0.0.0')).toEqual({ major: 0, minor: 0, patch: 0 });
});
});
describe('getVersionString', () => {
test('formats a version object as a string', () => {
expect(getVersionString({ major: 1, minor: 2, patch: 3 })).toBe('v1.2.3');
});
test('formats zero version', () => {
expect(getVersionString({ major: 0, minor: 0, patch: 0 })).toBe('v0.0.0');
});
});
describe('compareVersions', () => {
test('returns 0 for equal versions', () => {
const v = { major: 1, minor: 2, patch: 3 };
expect(compareVersions(v, v)).toBe(0);
});
test('compares by major version first', () => {
const a = { major: 2, minor: 0, patch: 0 };
const b = { major: 1, minor: 9, patch: 9 };
expect(compareVersions(a, b)).toBeGreaterThan(0);
expect(compareVersions(b, a)).toBeLessThan(0);
});
test('compares by minor version when major is equal', () => {
const a = { major: 1, minor: 3, patch: 0 };
const b = { major: 1, minor: 2, patch: 9 };
expect(compareVersions(a, b)).toBeGreaterThan(0);
expect(compareVersions(b, a)).toBeLessThan(0);
});
test('compares by patch version when major and minor are equal', () => {
const a = { major: 1, minor: 2, patch: 4 };
const b = { major: 1, minor: 2, patch: 3 };
expect(compareVersions(a, b)).toBeGreaterThan(0);
expect(compareVersions(b, a)).toBeLessThan(0);
});
});
// --- UpgradeToast isOwner gating test ---
// We mock the external dependencies to isolate the isOwner behavior.
// The key assertion: when isOwner=false, fetch should NOT be called.
const mockToast = vi.fn();
vi.mock('@/components/hooks/use-toast', () => ({
useToast: () => ({ toast: mockToast }),
}));
vi.mock('usehooks-ts', () => ({
useLocalStorage: () => [new Date(0).toUTCString(), vi.fn()],
}));
vi.mock('@tanstack/react-query', () => ({
useQuery: () => ({ data: 'v1.0.0' }),
}));
vi.mock('@/app/api/(client)/client', () => ({
getVersion: vi.fn(),
}));
describe('UpgradeToast isOwner gating', () => {
beforeEach(() => {
vi.restoreAllMocks();
// Reset the global fetch mock before each test
global.fetch = vi.fn();
});
test('does not fetch or show toast when isOwner is false', async () => {
// Dynamic import after mocks are set up
const { UpgradeToast } = await import('./upgradeToast');
const { render } = await import('@testing-library/react');
render(<UpgradeToast isOwner={false} />);
// fetch should not have been called because isOwner is false
expect(global.fetch).not.toHaveBeenCalled();
expect(mockToast).not.toHaveBeenCalled();
});
test('fetches GitHub tags when isOwner is true', async () => {
const mockResponse = {
json: () => Promise.resolve([{ name: 'v2.0.0' }]),
};
global.fetch = vi.fn().mockResolvedValue(mockResponse);
const { UpgradeToast } = await import('./upgradeToast');
const { render, waitFor } = await import('@testing-library/react');
render(<UpgradeToast isOwner={true} />);
await waitFor(() => {
expect(global.fetch).toHaveBeenCalledWith(
'https://api.github.com/repos/sourcebot-dev/sourcebot/tags'
);
});
});
});