Skip to content

Commit 152e467

Browse files
authored
test: getInstallerInfo() (#177)
Signed-off-by: David Wosk <dwosk@us.ibm.com>
1 parent 507fef7 commit 152e467

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import {getInstallerInfo} from '../../src/index';
2+
import {mockFetch, resetSdk, lastFetchCall} from '../test-helpers';
3+
4+
describe('getInstallerInfo', () => {
5+
const CLOUDFRONT_URL = 'https://downloads.ibmaspera.com/downloads/desktop/latest/stable';
6+
const OFFLINE_ENDPOINT = 'https://mycompany.example.com/aspera/installers';
7+
8+
// Returns a fresh copy to avoid mutation across tests
9+
const getCloudFrontResponse = () => ({
10+
entries: [
11+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: 'https://downloads.ibmaspera.com/downloads/desktop/macos/1.0.16/stable/universal/ibm-aspera-desktop-1.0.16.pkg'},
12+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe'},
13+
{version: '1.0.16', platform: 'windows', type: 'msi', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.msi'},
14+
{version: '1.0.16', platform: 'linux', type: 'appimage', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x86_64.AppImage'},
15+
{version: '1.0.16', platform: 'linux', type: 'deb', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-amd64.deb'},
16+
],
17+
});
18+
19+
const getOfflineResponse = () => ({
20+
entries: [
21+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: 'macos/1.0.16/stable/universal/ibm-aspera-desktop-1.0.16.pkg'},
22+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: 'windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe'},
23+
{version: '1.0.16', platform: 'windows', type: 'msi', arch: 'x64', url: 'windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.msi'},
24+
{version: '1.0.16', platform: 'linux', type: 'appimage', arch: 'x64', url: 'linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x86_64.AppImage'},
25+
{version: '1.0.16', platform: 'linux', type: 'deb', arch: 'x64', url: 'linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-amd64.deb'},
26+
],
27+
});
28+
29+
afterEach(() => {
30+
resetSdk();
31+
jest.restoreAllMocks();
32+
});
33+
34+
describe('CloudFront mode (default)', () => {
35+
it('should fetch from CloudFront latest.json', async () => {
36+
mockFetch(() => ({status: 200, body: getCloudFrontResponse()}));
37+
38+
await getInstallerInfo({all: true});
39+
40+
const call = lastFetchCall();
41+
expect(call.url).toBe(`${CLOUDFRONT_URL}/latest.json`);
42+
expect(call.method).toBe('GET');
43+
});
44+
45+
it('should return all entries when options.all is true', async () => {
46+
mockFetch(() => ({status: 200, body: getCloudFrontResponse()}));
47+
48+
const result = await getInstallerInfo({all: true});
49+
50+
expect(result).toEqual({
51+
entries: [
52+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: 'https://downloads.ibmaspera.com/downloads/desktop/macos/1.0.16/stable/universal/ibm-aspera-desktop-1.0.16.pkg'},
53+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe'},
54+
{version: '1.0.16', platform: 'windows', type: 'msi', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.msi'},
55+
{version: '1.0.16', platform: 'linux', type: 'appimage', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x86_64.AppImage'},
56+
{version: '1.0.16', platform: 'linux', type: 'deb', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-amd64.deb'},
57+
],
58+
});
59+
});
60+
61+
it('should filter entries by current platform when options.all is false', async () => {
62+
// Mock userAgent to return macOS
63+
const originalUserAgent = navigator.userAgent;
64+
Object.defineProperty(navigator, 'userAgent', {
65+
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
66+
configurable: true,
67+
});
68+
69+
mockFetch(() => ({status: 200, body: getCloudFrontResponse()}));
70+
71+
const result = await getInstallerInfo();
72+
73+
expect(result).toEqual({
74+
entries: [
75+
{
76+
version: '1.0.16',
77+
platform: 'macos',
78+
type: 'pkg',
79+
arch: 'universal',
80+
url: 'https://downloads.ibmaspera.com/downloads/desktop/macos/1.0.16/stable/universal/ibm-aspera-desktop-1.0.16.pkg',
81+
},
82+
],
83+
});
84+
85+
// Restore userAgent
86+
Object.defineProperty(navigator, 'userAgent', {
87+
value: originalUserAgent,
88+
configurable: true,
89+
});
90+
});
91+
92+
it('should filter entries for Windows platform', async () => {
93+
const originalUserAgent = navigator.userAgent;
94+
Object.defineProperty(navigator, 'userAgent', {
95+
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
96+
configurable: true,
97+
});
98+
99+
mockFetch(() => ({status: 200, body: getCloudFrontResponse()}));
100+
101+
const result = await getInstallerInfo();
102+
103+
expect(result).toEqual({
104+
entries: [
105+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe'},
106+
{version: '1.0.16', platform: 'windows', type: 'msi', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.msi'},
107+
],
108+
});
109+
110+
Object.defineProperty(navigator, 'userAgent', {
111+
value: originalUserAgent,
112+
configurable: true,
113+
});
114+
});
115+
116+
it('should filter entries for Linux platform', async () => {
117+
const originalUserAgent = navigator.userAgent;
118+
Object.defineProperty(navigator, 'userAgent', {
119+
value: 'Mozilla/5.0 (X11; Linux x86_64)',
120+
configurable: true,
121+
});
122+
123+
mockFetch(() => ({status: 200, body: getCloudFrontResponse()}));
124+
125+
const result = await getInstallerInfo();
126+
127+
expect(result).toEqual({
128+
entries: [
129+
{version: '1.0.16', platform: 'linux', type: 'appimage', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x86_64.AppImage'},
130+
{version: '1.0.16', platform: 'linux', type: 'deb', arch: 'x64', url: 'https://downloads.ibmaspera.com/downloads/desktop/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-amd64.deb'},
131+
],
132+
});
133+
134+
Object.defineProperty(navigator, 'userAgent', {
135+
value: originalUserAgent,
136+
configurable: true,
137+
});
138+
});
139+
140+
it('should reject when fetch fails', async () => {
141+
mockFetch(() => {
142+
throw new Error('Network error');
143+
});
144+
145+
await expect(getInstallerInfo({all: true})).rejects.toEqual({
146+
error: true,
147+
message: 'Unable to get latest installers',
148+
});
149+
});
150+
});
151+
152+
describe('Offline mode (custom endpoint)', () => {
153+
it('should fetch from custom endpoint', async () => {
154+
mockFetch(() => ({status: 200, body: getOfflineResponse()}));
155+
156+
await getInstallerInfo({endpoint: OFFLINE_ENDPOINT, all: true});
157+
158+
const call = lastFetchCall();
159+
expect(call.url).toBe(`${OFFLINE_ENDPOINT}/latest.json`);
160+
});
161+
162+
it('should prepend endpoint to relative URLs', async () => {
163+
mockFetch(() => ({status: 200, body: getOfflineResponse()}));
164+
165+
const result = await getInstallerInfo({endpoint: OFFLINE_ENDPOINT, all: true});
166+
167+
expect(result).toEqual({
168+
entries: [
169+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: `${OFFLINE_ENDPOINT}/macos/1.0.16/stable/universal/ibm-aspera-desktop-1.0.16.pkg`},
170+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: `${OFFLINE_ENDPOINT}/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe`},
171+
{version: '1.0.16', platform: 'windows', type: 'msi', arch: 'x64', url: `${OFFLINE_ENDPOINT}/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.msi`},
172+
{version: '1.0.16', platform: 'linux', type: 'appimage', arch: 'x64', url: `${OFFLINE_ENDPOINT}/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x86_64.AppImage`},
173+
{version: '1.0.16', platform: 'linux', type: 'deb', arch: 'x64', url: `${OFFLINE_ENDPOINT}/linux/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-amd64.deb`},
174+
],
175+
});
176+
});
177+
178+
it('should not modify URLs that are already absolute', async () => {
179+
// Mix of absolute and relative URLs
180+
const mixedResponse = {
181+
entries: [
182+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: 'https://other-cdn.example.com/ibm-aspera-desktop-1.0.16.pkg'},
183+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: 'windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe'},
184+
],
185+
};
186+
mockFetch(() => ({status: 200, body: mixedResponse}));
187+
188+
const result = await getInstallerInfo({endpoint: OFFLINE_ENDPOINT, all: true});
189+
190+
expect(result).toEqual({
191+
entries: [
192+
{version: '1.0.16', platform: 'macos', type: 'pkg', arch: 'universal', url: 'https://other-cdn.example.com/ibm-aspera-desktop-1.0.16.pkg'},
193+
{version: '1.0.16', platform: 'windows', type: 'exe', arch: 'x64', url: `${OFFLINE_ENDPOINT}/windows/1.0.16/stable/x64/ibm-aspera-desktop-1.0.16-x64.exe`},
194+
],
195+
});
196+
});
197+
198+
it('should strip /latest.json from endpoint if provided', async () => {
199+
mockFetch(() => ({status: 200, body: getOfflineResponse()}));
200+
201+
await getInstallerInfo({endpoint: `${OFFLINE_ENDPOINT}/latest.json`, all: true});
202+
203+
const call = lastFetchCall();
204+
expect(call.url).toBe(`${OFFLINE_ENDPOINT}/latest.json`);
205+
});
206+
207+
it('should reject when endpoint is not a valid URL', async () => {
208+
await expect(getInstallerInfo({endpoint: 'not-a-valid-url'})).rejects.toEqual({
209+
error: true,
210+
message: 'The specified endpoint is not a valid URL',
211+
});
212+
});
213+
});
214+
});

0 commit comments

Comments
 (0)