-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SDA-4785 AutoUpdate on app launch fix (#2259)
- Loading branch information
1 parent
beb9f53
commit 1a85223
Showing
3 changed files
with
177 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import * as electronFetch from 'electron-fetch'; | ||
import { fetchLatestVersion } from '../src/app/auto-update-utils'; | ||
import { logger } from '../src/common/logger'; | ||
|
||
jest.mock('../src/common/logger'); | ||
jest.mock('electron-fetch'); | ||
|
||
const DEFAULT_VERSION_RESPONSE = ` | ||
version: 25.1.0-2514 | ||
files: | ||
- url: https://123.exe | ||
sha512: 123 | ||
size: 206426857 | ||
path: https://123.exe | ||
releaseDate: '2024-12-27T10:16:58.947Z' | ||
sha512: 123`; | ||
|
||
describe('fetchLatestVersion', () => { | ||
const mockUrl = 'test-url'; | ||
const regex = /version: (.*)/; | ||
const mockLogger = logger as jest.Mocked<typeof logger>; | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should fetch the latest version from a URL', async () => { | ||
( | ||
electronFetch as jest.Mocked<typeof electronFetch> | ||
).default.mockResolvedValueOnce({ | ||
ok: true, | ||
text: async () => DEFAULT_VERSION_RESPONSE, | ||
}); | ||
|
||
const version = await fetchLatestVersion(mockUrl, 5000, regex); | ||
expect(version).toBe('25.1.0-2514'); | ||
expect( | ||
(electronFetch as jest.Mocked<typeof electronFetch>).default, | ||
).toHaveBeenCalledWith(mockUrl, { signal: expect.anything() }); | ||
}); | ||
|
||
it('should return undefined if the fetch fails', async () => { | ||
( | ||
electronFetch as jest.Mocked<typeof electronFetch> | ||
).default.mockRejectedValueOnce(new Error('Fetch error')); | ||
|
||
const version = await fetchLatestVersion(mockUrl, 5000, regex); | ||
expect(version).toBeUndefined(); | ||
expect( | ||
(electronFetch as jest.Mocked<typeof electronFetch>).default, | ||
).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should return undefined if the response is not ok', async () => { | ||
( | ||
electronFetch as jest.Mocked<typeof electronFetch> | ||
).default.mockResolvedValueOnce({ | ||
ok: false, | ||
status: 404, | ||
text: async () => 'Not Found', | ||
}); | ||
|
||
const version = await fetchLatestVersion(mockUrl, 5000, regex); | ||
expect(version).toBeUndefined(); | ||
}); | ||
|
||
it('should return undefined if the version is not found in the response', async () => { | ||
( | ||
electronFetch as jest.Mocked<typeof electronFetch> | ||
).default.mockResolvedValueOnce({ | ||
ok: true, | ||
text: async () => 'Invalid response', | ||
}); | ||
|
||
const version = await fetchLatestVersion(mockUrl, 5000, regex); | ||
expect(version).toBeUndefined(); | ||
}); | ||
|
||
it('should handle timeout', async () => { | ||
const mockUrl = 'test-url'; | ||
const autoUpdateTimeout = 10; | ||
|
||
jest.useFakeTimers(); | ||
|
||
const versionPromise = fetchLatestVersion( | ||
mockUrl, | ||
autoUpdateTimeout, | ||
regex, | ||
); | ||
|
||
jest.advanceTimersByTime(autoUpdateTimeout + 1); | ||
|
||
const version = await versionPromise; | ||
|
||
expect(version).toBeUndefined(); | ||
expect(mockLogger.warn).toHaveBeenCalledWith( | ||
'auto-update-handler: fetch aborted due to timeout', | ||
mockUrl, | ||
); | ||
|
||
jest.useRealTimers(); | ||
}); | ||
|
||
it('should handle error', async () => { | ||
const mockUrl = 'test-url'; | ||
const autoUpdateTimeout = 100; | ||
|
||
jest.useFakeTimers(); | ||
|
||
const versionPromise = fetchLatestVersion( | ||
mockUrl, | ||
autoUpdateTimeout, | ||
regex, | ||
); | ||
|
||
jest.advanceTimersByTime(autoUpdateTimeout - 1); | ||
|
||
const version = await versionPromise; | ||
|
||
expect(version).toBeUndefined(); | ||
expect(mockLogger.error).toHaveBeenCalledWith( | ||
'auto-update-handler: error fetching version', | ||
mockUrl, | ||
expect.anything(), | ||
); | ||
|
||
jest.useRealTimers(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import fetch from 'electron-fetch'; | ||
import { logger } from '../common/logger'; | ||
|
||
export const fetchLatestVersion = async ( | ||
url: string, | ||
autoUpdateTimeout: number, | ||
versionRegexp: RegExp, | ||
): Promise<string | undefined> => { | ||
logger.info('auto-update-handler: fetching latest version info from', url); | ||
|
||
const controller = new AbortController(); | ||
const signal = controller.signal; | ||
const timeoutId = setTimeout(() => controller.abort(), autoUpdateTimeout); | ||
|
||
try { | ||
const response = await fetch(url, { signal }); | ||
clearTimeout(timeoutId); | ||
if (!response || !response.ok) { | ||
throw new Error(`HTTP error ${response.status}`); | ||
} | ||
|
||
const responseText = await response.text(); | ||
logger.info( | ||
'auto-update-handler: latest version info from server', | ||
responseText, | ||
); | ||
|
||
const match = versionRegexp.exec(responseText); | ||
return match?.[1]; | ||
} catch (error: any) { | ||
if (controller.signal.aborted) { | ||
logger.warn('auto-update-handler: fetch aborted due to timeout', url); | ||
} else { | ||
logger.error('auto-update-handler: error fetching version', url, error); | ||
} | ||
return undefined; | ||
} finally { | ||
clearTimeout(timeoutId); | ||
} | ||
}; |