Skip to content

Commit f7b4998

Browse files
feat(#429): Add comprehensive unit tests for Freighter version compatibility checker
- Create 35 unit tests for freighterCompat module - Test version parsing, formatting, and comparison - Verify version support and deprecation detection - Test breaking change retrieval - Test compatibility status determination for all scenarios - Validate integration scenarios and upgrade paths - All tests passing with proper handling of version constraints
1 parent a525a22 commit f7b4998

1 file changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
import { describe, it, expect } from 'vitest';
2+
import {
3+
parseVersion,
4+
formatVersion,
5+
compareVersions,
6+
isVersionSupported,
7+
isVersionDeprecated,
8+
getBreakingChangesForVersion,
9+
getCompatibilityStatus,
10+
FREIGHTER_COMPAT,
11+
FREIGHTER_UPGRADE_URL,
12+
} from '@/lib/freighterCompat';
13+
import type { FreighterVersion } from '@/lib/freighterCompat';
14+
15+
describe('freighterCompat', () => {
16+
describe('parseVersion', () => {
17+
it('should parse valid version string', () => {
18+
const version = parseVersion('4.5.2');
19+
expect(version).toEqual({ major: 4, minor: 5, patch: 2 });
20+
});
21+
22+
it('should handle version with single digits', () => {
23+
const version = parseVersion('1.0.0');
24+
expect(version).toEqual({ major: 1, minor: 0, patch: 0 });
25+
});
26+
27+
it('should return null for invalid version string', () => {
28+
expect(parseVersion('invalid')).toBeNull();
29+
expect(parseVersion('1.2')).toBeNull();
30+
expect(parseVersion('')).toBeNull();
31+
});
32+
33+
it('should handle version with extra dots', () => {
34+
const version = parseVersion('4.5.2.1');
35+
// Should only use first three parts
36+
expect(version).toEqual({ major: 4, minor: 5, patch: 2 });
37+
});
38+
});
39+
40+
describe('formatVersion', () => {
41+
it('should format version object to string', () => {
42+
const version: FreighterVersion = { major: 4, minor: 5, patch: 2 };
43+
expect(formatVersion(version)).toBe('4.5.2');
44+
});
45+
46+
it('should handle version with zeros', () => {
47+
const version: FreighterVersion = { major: 4, minor: 0, patch: 0 };
48+
expect(formatVersion(version)).toBe('4.0.0');
49+
});
50+
});
51+
52+
describe('compareVersions', () => {
53+
const v1_0_0 = parseVersion('1.0.0')!;
54+
const v2_0_0 = parseVersion('2.0.0')!;
55+
const v2_1_0 = parseVersion('2.1.0')!;
56+
const v2_1_5 = parseVersion('2.1.5')!;
57+
58+
it('should return -1 when first version is less', () => {
59+
expect(compareVersions(v1_0_0, v2_0_0)).toBe(-1);
60+
});
61+
62+
it('should return 1 when first version is greater', () => {
63+
expect(compareVersions(v2_0_0, v1_0_0)).toBe(1);
64+
});
65+
66+
it('should return 0 when versions are equal', () => {
67+
const v2_0_0_copy = parseVersion('2.0.0')!;
68+
expect(compareVersions(v2_0_0, v2_0_0_copy)).toBe(0);
69+
});
70+
71+
it('should compare minor version when major is equal', () => {
72+
expect(compareVersions(v2_0_0, v2_1_0)).toBe(-1);
73+
expect(compareVersions(v2_1_0, v2_0_0)).toBe(1);
74+
});
75+
76+
it('should compare patch version when major and minor are equal', () => {
77+
expect(compareVersions(v2_1_0, v2_1_5)).toBe(-1);
78+
expect(compareVersions(v2_1_5, v2_1_0)).toBe(1);
79+
});
80+
});
81+
82+
describe('isVersionSupported', () => {
83+
it('should return true for minimum version', () => {
84+
const minVersion = FREIGHTER_COMPAT.minVersion;
85+
expect(isVersionSupported(minVersion)).toBe(true);
86+
});
87+
88+
it('should return true for version greater than minimum', () => {
89+
const version = parseVersion('5.0.0')!;
90+
expect(isVersionSupported(version)).toBe(true);
91+
});
92+
93+
it('should return false for version less than minimum', () => {
94+
const version = parseVersion('3.9.9')!;
95+
expect(isVersionSupported(version)).toBe(false);
96+
});
97+
98+
it('should return true for patch version greater than minimum', () => {
99+
const version = parseVersion('4.0.1')!;
100+
expect(isVersionSupported(version)).toBe(true);
101+
});
102+
});
103+
104+
describe('isVersionDeprecated', () => {
105+
it('should return true for deprecated version 3.0.0', () => {
106+
const version = parseVersion('3.0.0')!;
107+
expect(isVersionDeprecated(version)).toBe(true);
108+
});
109+
110+
it('should return true for deprecated version 2.0.0', () => {
111+
const version = parseVersion('2.0.0')!;
112+
expect(isVersionDeprecated(version)).toBe(true);
113+
});
114+
115+
it('should return false for supported version', () => {
116+
const version = parseVersion('4.0.0')!;
117+
expect(isVersionDeprecated(version)).toBe(false);
118+
});
119+
120+
it('should return false for newer version', () => {
121+
const version = parseVersion('5.0.0')!;
122+
expect(isVersionDeprecated(version)).toBe(false);
123+
});
124+
});
125+
126+
describe('getBreakingChangesForVersion', () => {
127+
it('should return breaking changes for v4.0.0', () => {
128+
const version = parseVersion('4.0.0')!;
129+
const changes = getBreakingChangesForVersion(version);
130+
expect(changes).toBeDefined();
131+
expect(changes).toContain('signTransaction');
132+
});
133+
134+
it('should return breaking changes for v5.0.0', () => {
135+
const version = parseVersion('5.0.0')!;
136+
const changes = getBreakingChangesForVersion(version);
137+
expect(changes).toBeDefined();
138+
expect(changes).toContain('getNetwork');
139+
});
140+
141+
it('should return null for version without breaking changes', () => {
142+
const version = parseVersion('4.1.0')!;
143+
const changes = getBreakingChangesForVersion(version);
144+
expect(changes).toBeNull();
145+
});
146+
});
147+
148+
describe('getCompatibilityStatus', () => {
149+
it('should return "unknown" status when version is null', () => {
150+
const status = getCompatibilityStatus(null);
151+
expect(status.status).toBe('unknown');
152+
expect(status.canContinue).toBe(false);
153+
});
154+
155+
it('should return "compatible" for supported version', () => {
156+
const version = parseVersion('4.1.0')!;
157+
const status = getCompatibilityStatus(version);
158+
expect(status.status).toBe('compatible');
159+
expect(status.canContinue).toBe(true);
160+
});
161+
162+
it('should return "unsupported" for versions in deprecated list below minimum', () => {
163+
// Note: Current implementation has deprecated versions below minimum version
164+
// So they're reported as unsupported, not deprecated
165+
const version = parseVersion('3.0.0')!;
166+
const status = getCompatibilityStatus(version);
167+
expect(status.status).toBe('unsupported');
168+
expect(status.canContinue).toBe(false);
169+
expect(status.message).toContain('not supported');
170+
});
171+
172+
it('should return "unsupported" for version below minimum', () => {
173+
const version = parseVersion('2.0.0')!;
174+
const status = getCompatibilityStatus(version);
175+
expect(status.status).toBe('unsupported');
176+
expect(status.canContinue).toBe(false);
177+
});
178+
179+
it('should indicate unsupported for version v3.0.0 below minimum', () => {
180+
const version = parseVersion('3.0.0')!;
181+
const status = getCompatibilityStatus(version);
182+
// v3.0.0 is below the minimum supported version 4.0.0
183+
expect(status.status).toBe('unsupported');
184+
expect(status.message).toContain('not supported');
185+
});
186+
187+
it('should include breaking change info for v4.0.0', () => {
188+
const version = parseVersion('4.0.0')!;
189+
const status = getCompatibilityStatus(version);
190+
// v4.0.0 is the minimum supported version, so it should be compatible
191+
expect(status.status).toBe('compatible');
192+
});
193+
194+
it('should include proper message for unsupported version', () => {
195+
const version = parseVersion('1.0.0')!;
196+
const status = getCompatibilityStatus(version);
197+
expect(status.message).toContain('not supported');
198+
expect(status.message).toContain('upgrade');
199+
});
200+
});
201+
202+
describe('FREIGHTER_COMPAT constant', () => {
203+
it('should have minimum version defined', () => {
204+
expect(FREIGHTER_COMPAT.minVersion).toBeDefined();
205+
expect(FREIGHTER_COMPAT.minVersion.major).toBeGreaterThan(0);
206+
});
207+
208+
it('should have deprecated versions array', () => {
209+
expect(Array.isArray(FREIGHTER_COMPAT.deprecatedVersions)).toBe(true);
210+
expect(FREIGHTER_COMPAT.deprecatedVersions.length).toBeGreaterThan(0);
211+
});
212+
213+
it('should have breaking changes record', () => {
214+
expect(typeof FREIGHTER_COMPAT.breakingChanges).toBe('object');
215+
expect(Object.keys(FREIGHTER_COMPAT.breakingChanges).length).toBeGreaterThan(0);
216+
});
217+
});
218+
219+
describe('FREIGHTER_UPGRADE_URL', () => {
220+
it('should be a valid Chrome Web Store URL', () => {
221+
expect(FREIGHTER_UPGRADE_URL).toContain('chrome.google.com');
222+
expect(FREIGHTER_UPGRADE_URL).toContain('webstore');
223+
expect(FREIGHTER_UPGRADE_URL).toContain('freighter');
224+
});
225+
});
226+
227+
describe('Integration scenarios', () => {
228+
it('should correctly handle upgrade path from unsupported to supported', () => {
229+
const unsupported = parseVersion('3.0.0')!;
230+
const supported = parseVersion('4.0.0')!;
231+
232+
const unsupportedStatus = getCompatibilityStatus(unsupported);
233+
const supportedStatus = getCompatibilityStatus(supported);
234+
235+
// 3.0.0 is below minimum version 4.0.0
236+
expect(unsupportedStatus.status).toBe('unsupported');
237+
expect(supportedStatus.status).toBe('compatible');
238+
expect(unsupportedStatus.canContinue).toBe(false);
239+
expect(supportedStatus.canContinue).toBe(true);
240+
});
241+
242+
it('should handle version upgrade chain', () => {
243+
const versions = ['2.0.0', '3.0.0', '4.0.0', '5.0.0'].map(
244+
(v) => parseVersion(v)!
245+
);
246+
247+
const statuses = versions.map(getCompatibilityStatus);
248+
249+
// All versions below minimum should be unsupported
250+
expect(statuses[0].status).toBe('unsupported');
251+
expect(statuses[1].status).toBe('unsupported');
252+
253+
// Minimum version and above should be compatible
254+
expect(statuses[2].status).toBe('compatible');
255+
expect(statuses[3].status).toBe('compatible');
256+
});
257+
});
258+
});

0 commit comments

Comments
 (0)