* Add next suggestions and remove console logs * Add pomodoro timer * Add pomodoro switch in settings * Fix pomodoro setting * Add timezones to settings * Fix an issue with password reset * Cleanup * Sort tags alphabetically * Clean up today's view * Add an indicator for repeatedly added to today * Refactor tags * Add due date today item * Move recurrence to the subtitle area * Fix today layout * Add a badge to Inbox items * Move inbox badge to sidebar * Add quotes and progress bar * Add translations for quotes * Fix test issues * Add helper script for docker local * Set up overdue tasks * Add linux/arm/v7 build to deploy script * Add linux/arm/v7 build to deploy script pt2 * Fix an issue with helmet and SSL * Add volume db persistence * Fix cog icon issues
180 lines
No EOL
6.3 KiB
JavaScript
180 lines
No EOL
6.3 KiB
JavaScript
const request = require('supertest');
|
|
const app = require('../../app');
|
|
const { createTestUser } = require('../helpers/testUtils');
|
|
|
|
describe('URL Routes', () => {
|
|
let user, agent;
|
|
|
|
beforeEach(async () => {
|
|
user = await createTestUser({
|
|
email: 'test@example.com'
|
|
});
|
|
|
|
// Create authenticated agent
|
|
agent = request.agent(app);
|
|
await agent
|
|
.post('/api/login')
|
|
.send({
|
|
email: 'test@example.com',
|
|
password: 'password123'
|
|
});
|
|
});
|
|
|
|
describe('GET /api/url/title', () => {
|
|
it('should require authentication', async () => {
|
|
const response = await request(app)
|
|
.get('/api/url/title')
|
|
.query({ url: 'https://example.com' });
|
|
|
|
expect(response.status).toBe(401);
|
|
expect(response.body.error).toBe('Authentication required');
|
|
});
|
|
|
|
it('should require url parameter', async () => {
|
|
const response = await agent
|
|
.get('/api/url/title');
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(response.body.error).toBe('URL parameter is required');
|
|
});
|
|
|
|
it('should return title for valid URL', async () => {
|
|
const response = await agent
|
|
.get('/api/url/title')
|
|
.query({ url: 'https://httpbin.org/html' });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('url');
|
|
expect(response.body).toHaveProperty('title');
|
|
expect(response.body.url).toBe('https://httpbin.org/html');
|
|
// Title could be extracted or null depending on network conditions
|
|
expect(typeof response.body.title === 'string' || response.body.title === null).toBe(true);
|
|
}, 10000);
|
|
|
|
it('should handle URL without protocol', async () => {
|
|
const response = await agent
|
|
.get('/api/url/title')
|
|
.query({ url: 'httpbin.org/html' });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('url');
|
|
expect(response.body).toHaveProperty('title');
|
|
expect(response.body.url).toBe('httpbin.org/html');
|
|
// Title could be extracted or null depending on network conditions
|
|
expect(typeof response.body.title === 'string' || response.body.title === null).toBe(true);
|
|
}, 10000);
|
|
|
|
it('should handle invalid URL gracefully', async () => {
|
|
const response = await agent
|
|
.get('/api/url/title')
|
|
.query({ url: 'not-a-valid-url' });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('url');
|
|
expect(response.body).toHaveProperty('title');
|
|
expect(response.body.url).toBe('not-a-valid-url');
|
|
// Title could be null or error message
|
|
expect(response.body.title === null || typeof response.body.title === 'string').toBe(true);
|
|
});
|
|
|
|
it('should handle unreachable URL', async () => {
|
|
const response = await agent
|
|
.get('/api/url/title')
|
|
.query({ url: 'https://nonexistent-domain-12345.com' });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('url');
|
|
expect(response.body).toHaveProperty('title');
|
|
expect(response.body.url).toBe('https://nonexistent-domain-12345.com');
|
|
expect(response.body.title).toBe(null);
|
|
});
|
|
});
|
|
|
|
describe('POST /api/url/extract-from-text', () => {
|
|
it('should require authentication', async () => {
|
|
const response = await request(app)
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: 'Check out https://example.com' });
|
|
|
|
expect(response.status).toBe(401);
|
|
expect(response.body.error).toBe('Authentication required');
|
|
});
|
|
|
|
it('should require text parameter', async () => {
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({});
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(response.body.error).toBe('Text parameter is required');
|
|
});
|
|
|
|
it('should extract URL from text and get title', async () => {
|
|
const testText = 'Check out this interesting site: https://httpbin.org/html';
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: testText });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.found).toBe(true);
|
|
expect(response.body.url).toBe('https://httpbin.org/html');
|
|
expect(response.body.originalText).toBe(testText);
|
|
expect(response.body).toHaveProperty('title');
|
|
// Title could be extracted or null depending on network conditions
|
|
expect(typeof response.body.title === 'string' || response.body.title === null).toBe(true);
|
|
}, 10000);
|
|
|
|
it('should extract first URL when multiple URLs in text', async () => {
|
|
const testText = 'Check out https://httpbin.org/html and also https://example.com';
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: testText });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.found).toBe(true);
|
|
expect(response.body.url).toBe('https://httpbin.org/html');
|
|
expect(response.body.originalText).toBe(testText);
|
|
expect(response.body).toHaveProperty('title');
|
|
}, 10000);
|
|
|
|
it('should detect URLs without protocol', async () => {
|
|
const testText = 'Visit httpbin.org/html for testing';
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: testText });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.found).toBe(true);
|
|
expect(response.body.url).toBe('httpbin.org/html');
|
|
expect(response.body.originalText).toBe(testText);
|
|
});
|
|
|
|
it('should return found false when no URL in text', async () => {
|
|
const testText = 'This text has no URLs in it at all';
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: testText });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.found).toBe(false);
|
|
});
|
|
|
|
it('should handle empty text', async () => {
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: '' });
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(response.body.error).toBe('Text parameter is required');
|
|
});
|
|
|
|
it('should handle text with only whitespace', async () => {
|
|
const response = await agent
|
|
.post('/api/url/extract-from-text')
|
|
.send({ text: ' \n\t ' });
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.found).toBe(false);
|
|
});
|
|
});
|
|
}); |