Created
November 23, 2022 20:22
-
-
Save IvanAdmaers/d333595b56a88ffd94737c9fb05c7f09 to your computer and use it in GitHub Desktop.
Check is an image available by its url
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
import fs from 'fs/promises'; | |
import path from 'path'; | |
import axios from 'axios'; | |
import { checkImageUrl, allowedFormats, requestWaitingTimeInMs } from '..'; | |
jest.useFakeTimers(); | |
describe('checkImageUrl', () => { | |
it('should return a correct result for jpeg', async () => { | |
const isAllowed = allowedFormats.includes('jpeg'); | |
const jpegImageBuffer = await fs.readFile( | |
path.join(__dirname, './images/jpeg-test.jpeg') | |
); | |
const mockGet = jest.spyOn(axios, 'get'); | |
mockGet.mockImplementation(() => | |
Promise.resolve({ data: jpegImageBuffer }) | |
); | |
const result = await checkImageUrl('https://tsthisisforyoudear.com/'); | |
expect(result).toBe(isAllowed); | |
}); | |
it('should return a correct result for webp', async () => { | |
const isAllowed = allowedFormats.includes('webp'); | |
const webpImageBuffer = await fs.readFile( | |
path.join(__dirname, './images/webp-test.webp') | |
); | |
const mockGet = jest.spyOn(axios, 'get'); | |
mockGet.mockImplementation(() => | |
Promise.resolve({ data: webpImageBuffer }) | |
); | |
const result = await checkImageUrl('https://tsthisisforyoudear.com/'); | |
expect(result).toBe(isAllowed); | |
}); | |
it('should return null when server not responding', () => { | |
const mockGet = jest.spyOn(axios, 'get'); | |
mockGet.mockImplementation(() => new Promise(() => {})); | |
const pendingPromise = checkImageUrl( | |
'https://tsthisisforyoudear.com/' | |
).then((result) => { | |
expect(result).toBe(null); | |
}); | |
jest.advanceTimersByTime(requestWaitingTimeInMs); | |
return pendingPromise; | |
}); | |
}); |
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
import axios from 'axios'; | |
import AbortController from 'abort-controller'; | |
import FileType from 'file-type'; | |
export const allowedFormats = ['jpg', 'jpeg', 'png']; | |
export const requestWaitingTimeInMs = 3 * 1000; | |
/** | |
* This function checks does an image available by url | |
*/ | |
export const checkImageUrl = async (url: string): Promise<boolean | null> => | |
new Promise((resolve) => { | |
try { | |
(async () => { | |
const controller = new AbortController(); | |
const { signal } = controller; | |
const timeout = setTimeout(() => { | |
controller.abort(); | |
}, requestWaitingTimeInMs); | |
signal.addEventListener('abort', () => { | |
console.log( | |
`Request to URL ${url} cancelled due to server not responding` | |
); | |
resolve(null); | |
}); | |
const req = await axios.get(url, { | |
responseType: 'arraybuffer', | |
signal, | |
}); | |
clearTimeout(timeout); | |
const buffer = Buffer.from(req.data, 'binary'); | |
const fileData = await FileType.fromBuffer(buffer); | |
const { ext, mime } = fileData ?? {}; | |
if (ext === undefined || mime === undefined) { | |
return resolve(false); | |
} | |
const fileType = mime.split('/')[0]; | |
if (fileType !== 'image') { | |
return resolve(false); | |
} | |
if (allowedFormats.includes(ext) === false) { | |
return resolve(false); | |
} | |
return resolve(true); | |
})(); | |
} catch (error) { | |
console.error(error); | |
return resolve(null); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment