MM-59600 Add unit tests to utils/opengraph (#8444)
* Add unit tests to utils/opengraph * exporting only for tests --------- Co-authored-by: Rahim Rahman <rahim.rahman@mattermost.com>
This commit is contained in:
parent
72ccd763e6
commit
2307985539
2 changed files with 136 additions and 1 deletions
|
|
@ -1,7 +1,19 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getDistanceBW2Points, getNearestPoint} from './opengraph';
|
||||
import {getDistanceBW2Points, getNearestPoint, fetchOpenGraph, testExports} from './opengraph';
|
||||
|
||||
const {fetchRaw, getFavIcon} = testExports;
|
||||
|
||||
let mockedFetch: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
mockedFetch = jest.spyOn(global, 'fetch');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Utility Functions', () => {
|
||||
describe('getDistanceBW2Points', () => {
|
||||
|
|
@ -62,3 +74,121 @@ describe('Utility Functions', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchRaw', () => {
|
||||
it('should fetch raw HTML from a URL', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValue('<html></html>'),
|
||||
};
|
||||
mockedFetch.mockResolvedValue(mockResponse as any);
|
||||
|
||||
const result = await fetchRaw('http://example.com');
|
||||
expect(fetch).toHaveBeenCalledWith('http://example.com', {
|
||||
headers: {
|
||||
'User-Agent': 'OpenGraph',
|
||||
'Cache-Control': 'no-cache',
|
||||
Accept: '*/*',
|
||||
Connection: 'keep-alive',
|
||||
},
|
||||
});
|
||||
expect(result).toBe('<html></html>');
|
||||
});
|
||||
|
||||
it('should return response if not ok', async () => {
|
||||
const mockResponse = {
|
||||
ok: false,
|
||||
};
|
||||
mockedFetch.mockResolvedValue(mockResponse as any);
|
||||
|
||||
const result = await fetchRaw('http://example.com');
|
||||
expect(result).toBe(mockResponse);
|
||||
});
|
||||
|
||||
it('should return error message on fetch failure', async () => {
|
||||
const mockError = new Error('Network error');
|
||||
mockedFetch.mockRejectedValue(mockError);
|
||||
|
||||
const result = await fetchRaw('http://example.com');
|
||||
expect(result).toEqual({message: 'Network error'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFavIcon', () => {
|
||||
it('should return the largest favicon URL', () => {
|
||||
const mockHtml = '<html><head><link rel="icon" href="/favicon-32x32.png" sizes="32x32"><link rel="icon" href="/favicon-16x16.png" sizes="16x16"></head></html>';
|
||||
const result = getFavIcon('http://example.com', mockHtml);
|
||||
expect(result).toBe('http://example.com/favicon-32x32.png');
|
||||
});
|
||||
|
||||
it('should return default favicon URL if no icons found', () => {
|
||||
const mockHtml = '<html><head></head></html>';
|
||||
const result = getFavIcon('http://example.com', mockHtml);
|
||||
expect(result).toBe('http://example.com/favicon.ico');
|
||||
});
|
||||
|
||||
it('should handle shortcut icon rel attribute', () => {
|
||||
const mockHtml = '<html><head><link rel="shortcut icon" href="/favicon.png"></head></html>';
|
||||
const result = getFavIcon('http://example.com', mockHtml);
|
||||
expect(result).toBe('http://example.com/favicon.png');
|
||||
});
|
||||
|
||||
it('should handle absolute URLs in href', () => {
|
||||
const mockHtml = '<html><head><link rel="icon" href="https://cdn.example.com/favicon.png"></head></html>';
|
||||
const result = getFavIcon('http://example.com', mockHtml);
|
||||
expect(result).toBe('https://cdn.example.com/favicon.png');
|
||||
});
|
||||
|
||||
it('should handle icons without sizes attribute', () => {
|
||||
const mockHtml = '<html><head><link rel="icon" href="/favicon.png"><link rel="icon" href="/favicon-32x32.png" sizes="32x32"></head></html>';
|
||||
const result = getFavIcon('http://example.com', mockHtml);
|
||||
expect(result).toBe('http://example.com/favicon-32x32.png');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchOpenGraph', () => {
|
||||
it('should fetch OpenGraph data from a URL', async () => {
|
||||
const mockHtml = '<html><head><title>Example</title><meta property="og:title" content="OpenGraph Title"><meta property="og:image" content="http://example.com/image.png"></head></html>';
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValue(mockHtml),
|
||||
};
|
||||
mockedFetch.mockResolvedValue(mockResponse as any);
|
||||
|
||||
const result = await fetchOpenGraph('http://example.com', true);
|
||||
expect(result).toEqual({
|
||||
link: 'http://example.com',
|
||||
imageURL: 'http://example.com/image.png',
|
||||
favIcon: 'http://example.com/favicon.ico',
|
||||
title: 'OpenGraph Title',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return error if fetchRaw fails', async () => {
|
||||
const mockError = {message: 'Network error'};
|
||||
mockedFetch.mockRejectedValue(mockError);
|
||||
|
||||
const result = await fetchOpenGraph('http://example.com');
|
||||
expect(result).toEqual({
|
||||
link: 'http://example.com',
|
||||
error: new Error('Network error'),
|
||||
});
|
||||
});
|
||||
|
||||
it('should return default title if og:title is not found', async () => {
|
||||
const mockHtml = '<html><head><title>Example</title></head></html>';
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValue(mockHtml),
|
||||
};
|
||||
mockedFetch.mockResolvedValue(mockResponse as any);
|
||||
|
||||
const result = await fetchOpenGraph('http://example.com');
|
||||
expect(result).toEqual({
|
||||
link: 'http://example.com',
|
||||
imageURL: null,
|
||||
favIcon: undefined,
|
||||
title: 'Example',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -188,3 +188,8 @@ export const fetchOpenGraph = async (url: string, includeFavIcon = false): Promi
|
|||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const testExports = {
|
||||
fetchRaw,
|
||||
getFavIcon,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue