Skip to main content
Glama
Jing-yilin

Reddit MCP Server

by Jing-yilin
api.test.ts12.5 kB
/** * Direct API Integration Tests for Reddit JSON API * * These tests make real API calls to verify the Reddit API works correctly. * No API key required for public Reddit endpoints. * * Run with: bun test src/api.test.ts */ import { describe, test, expect, setDefaultTimeout, beforeAll } from 'bun:test'; import axios, { AxiosInstance } from 'axios'; setDefaultTimeout(30000); describe('Reddit Direct API Integration Tests', () => { let apiClient: AxiosInstance; beforeAll(() => { apiClient = axios.create({ baseURL: 'https://www.reddit.com', timeout: 30000, headers: { 'User-Agent': 'Reddit-MCP-Server-Test/1.0.0 (by /u/mcp-bot)', 'Accept': 'application/json', }, }); }); describe('Subreddit Endpoints', () => { test('get hot posts from r/programming', async () => { const response = await apiClient.get('/r/programming/hot.json', { params: { limit: 5, raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data).toHaveProperty('data'); expect(response.data.data).toHaveProperty('children'); expect(response.data.data.children).toBeInstanceOf(Array); expect(response.data.data.children.length).toBeGreaterThan(0); const firstPost = response.data.data.children[0].data; expect(firstPost).toHaveProperty('id'); expect(firstPost).toHaveProperty('title'); expect(firstPost).toHaveProperty('subreddit'); console.log('Hot post:', firstPost.title?.substring(0, 50) + '...'); }); test('get new posts from r/technology', async () => { const response = await apiClient.get('/r/technology/new.json', { params: { limit: 5, raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); console.log('New posts count:', response.data.data.children.length); }); test('get top posts from r/askreddit with time filter', async () => { const response = await apiClient.get('/r/askreddit/top.json', { params: { t: 'week', limit: 5, raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); const firstPost = response.data.data.children[0]?.data; if (firstPost) { expect(firstPost.score).toBeGreaterThan(0); console.log('Top post score:', firstPost.score); } }); test('get subreddit info for r/news', async () => { const response = await apiClient.get('/r/news/about.json', { params: { raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data).toHaveProperty('data'); expect(response.data.data).toHaveProperty('display_name'); expect(response.data.data).toHaveProperty('subscribers'); expect(response.data.data.display_name.toLowerCase()).toBe('news'); console.log('r/news subscribers:', response.data.data.subscribers); }); }); describe('Post Content Endpoints', () => { test('get post with comments', async () => { // First get a post ID from hot posts const hotResponse = await apiClient.get('/r/programming/hot.json', { params: { limit: 1, raw_json: 1 }, }); const postId = hotResponse.data.data.children[0]?.data?.id; expect(postId).toBeDefined(); // Then get the post content with comments const response = await apiClient.get(`/comments/${postId}.json`, { params: { limit: 10, depth: 2, sort: 'top', raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data).toBeInstanceOf(Array); expect(response.data.length).toBe(2); // [post, comments] const postData = response.data[0].data.children[0]?.data; expect(postData).toHaveProperty('title'); expect(postData).toHaveProperty('id'); console.log('Post title:', postData.title?.substring(0, 50) + '...'); const commentsData = response.data[1].data.children; console.log('Comments count:', commentsData.filter((c: any) => c.kind === 't1').length); }); test('get post with different comment sorts', async () => { const hotResponse = await apiClient.get('/r/askreddit/hot.json', { params: { limit: 1, raw_json: 1 }, }); const postId = hotResponse.data.data.children[0]?.data?.id; for (const sort of ['confidence', 'top', 'new']) { const response = await apiClient.get(`/comments/${postId}.json`, { params: { limit: 5, sort, raw_json: 1 }, }); expect(response.status).toBe(200); console.log(`Comments with sort=${sort}: OK`); } }); }); describe('Search Endpoints', () => { test('search posts by query', async () => { const response = await apiClient.get('/search.json', { params: { q: 'typescript', sort: 'relevance', t: 'month', limit: 5, type: 'link', raw_json: 1, }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); console.log('Search results:', response.data.data.children.length); }); test('search posts within a subreddit', async () => { const response = await apiClient.get('/r/programming/search.json', { params: { q: 'rust', restrict_sr: 'on', sort: 'top', t: 'week', limit: 5, raw_json: 1, }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); console.log('Subreddit search results:', response.data.data.children.length); }); test('search with different sort options', async () => { for (const sort of ['relevance', 'hot', 'top', 'new', 'comments']) { const response = await apiClient.get('/search.json', { params: { q: 'python', sort, limit: 3, raw_json: 1 }, }); expect(response.status).toBe(200); console.log(`Search with sort=${sort}: OK`); } }); }); describe('User Endpoints', () => { test('get user info', async () => { const response = await apiClient.get('/user/spez/about.json', { params: { raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data).toHaveProperty('data'); expect(response.data.data).toHaveProperty('name'); expect(response.data.data.name.toLowerCase()).toBe('spez'); expect(response.data.data).toHaveProperty('link_karma'); expect(response.data.data).toHaveProperty('comment_karma'); console.log('User spez karma:', response.data.data.total_karma); }); test('get user submitted posts', async () => { const response = await apiClient.get('/user/AutoModerator/submitted.json', { params: { sort: 'new', limit: 5, raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); console.log('User posts:', response.data.data.children.length); }); test('get user comments', async () => { const response = await apiClient.get('/user/AutoModerator/comments.json', { params: { sort: 'new', limit: 5, raw_json: 1 }, }); expect(response.status).toBe(200); expect(response.data.data.children).toBeInstanceOf(Array); if (response.data.data.children.length > 0) { const comment = response.data.data.children[0].data; expect(comment).toHaveProperty('body'); expect(comment).toHaveProperty('subreddit'); } console.log('User comments:', response.data.data.children.length); }); }); describe('Pagination', () => { test('pagination with after cursor', async () => { // First page const page1 = await apiClient.get('/r/programming/hot.json', { params: { limit: 5, raw_json: 1 }, }); expect(page1.status).toBe(200); const afterCursor = page1.data.data.after; expect(afterCursor).toBeDefined(); console.log('Page 1 after cursor:', afterCursor); // Second page const page2 = await apiClient.get('/r/programming/hot.json', { params: { limit: 5, after: afterCursor, raw_json: 1 }, }); expect(page2.status).toBe(200); expect(page2.data.data.children.length).toBeGreaterThan(0); // Verify different posts const page1Ids = page1.data.data.children.map((c: any) => c.data.id); const page2Ids = page2.data.data.children.map((c: any) => c.data.id); const overlap = page1Ids.filter((id: string) => page2Ids.includes(id)); expect(overlap.length).toBe(0); console.log('Page 2 posts are different from page 1: OK'); }); }); describe('Time Filters', () => { test('top posts with different time filters', async () => { for (const time of ['hour', 'day', 'week', 'month', 'year', 'all']) { const response = await apiClient.get('/r/all/top.json', { params: { t: time, limit: 1, raw_json: 1 }, }); expect(response.status).toBe(200); console.log(`Top posts t=${time}: OK`); } }); }); }); describe('API Response Format Validation', () => { let apiClient: AxiosInstance; beforeAll(() => { apiClient = axios.create({ baseURL: 'https://www.reddit.com', timeout: 30000, headers: { 'User-Agent': 'Reddit-MCP-Server-Test/1.0.0', 'Accept': 'application/json', }, }); }); test('post response contains all expected fields', async () => { const response = await apiClient.get('/r/programming/hot.json', { params: { limit: 1, raw_json: 1 }, }); const post = response.data.data.children[0].data; // Required fields for our data cleaner expect(post).toHaveProperty('id'); expect(post).toHaveProperty('title'); expect(post).toHaveProperty('subreddit'); expect(post).toHaveProperty('author'); expect(post).toHaveProperty('score'); expect(post).toHaveProperty('upvote_ratio'); expect(post).toHaveProperty('num_comments'); expect(post).toHaveProperty('created_utc'); expect(post).toHaveProperty('url'); expect(post).toHaveProperty('permalink'); expect(post).toHaveProperty('is_video'); expect(post).toHaveProperty('is_self'); }); test('comment response contains all expected fields', async () => { const hotResponse = await apiClient.get('/r/askreddit/hot.json', { params: { limit: 1, raw_json: 1 }, }); const postId = hotResponse.data.data.children[0].data.id; const response = await apiClient.get(`/comments/${postId}.json`, { params: { limit: 5, raw_json: 1 }, }); const comments = response.data[1].data.children.filter((c: any) => c.kind === 't1'); if (comments.length > 0) { const comment = comments[0].data; expect(comment).toHaveProperty('id'); expect(comment).toHaveProperty('author'); expect(comment).toHaveProperty('body'); expect(comment).toHaveProperty('score'); expect(comment).toHaveProperty('created_utc'); } }); test('user response contains all expected fields', async () => { const response = await apiClient.get('/user/spez/about.json', { params: { raw_json: 1 }, }); const user = response.data.data; expect(user).toHaveProperty('id'); expect(user).toHaveProperty('name'); expect(user).toHaveProperty('created_utc'); expect(user).toHaveProperty('link_karma'); expect(user).toHaveProperty('comment_karma'); expect(user).toHaveProperty('total_karma'); }); test('subreddit response contains all expected fields', async () => { const response = await apiClient.get('/r/programming/about.json', { params: { raw_json: 1 }, }); const subreddit = response.data.data; expect(subreddit).toHaveProperty('id'); expect(subreddit).toHaveProperty('display_name'); expect(subreddit).toHaveProperty('title'); expect(subreddit).toHaveProperty('public_description'); expect(subreddit).toHaveProperty('subscribers'); expect(subreddit).toHaveProperty('created_utc'); }); }); describe('API Test File Validation', () => { test('Reddit public API does not require authentication', () => { console.log('Reddit public JSON API does not require API key'); console.log('All tests use public endpoints (.json suffix)'); expect(true).toBe(true); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jing-yilin/reddit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server