|
10 | 10 | import { cookies } from 'next/headers' |
11 | 11 |
|
12 | 12 | import { getGitHubTokenCookieName } from '@/lib/constants/cookies' |
| 13 | +import { isTestMode } from '@/tests/isTestMode' |
13 | 14 |
|
14 | 15 | const GITHUB_API_BASE_URL = 'https://api.github.com' |
15 | 16 |
|
| 17 | +/** |
| 18 | + * Mock data for E2E testing |
| 19 | + * Matches the mock data in mocks/handlers.ts |
| 20 | + */ |
| 21 | +const MOCK_GITHUB_USER = { |
| 22 | + id: 12345, |
| 23 | + login: 'testuser', |
| 24 | + avatar_url: 'https://avatars.githubusercontent.com/u/12345?v=4', |
| 25 | + name: 'Test User', |
| 26 | + type: 'User' as const, |
| 27 | +} |
| 28 | + |
| 29 | +const MOCK_GITHUB_REPOS = [ |
| 30 | + { |
| 31 | + id: 1, |
| 32 | + node_id: 'R_kgDOGq0qMQ', |
| 33 | + name: 'test-repo', |
| 34 | + full_name: 'testuser/test-repo', |
| 35 | + owner: { |
| 36 | + login: 'testuser', |
| 37 | + avatar_url: 'https://avatars.githubusercontent.com/u/12345?v=4', |
| 38 | + }, |
| 39 | + description: 'A test repository for GitBox', |
| 40 | + html_url: 'https://github.com/testuser/test-repo', |
| 41 | + homepage: 'https://test-repo.dev', |
| 42 | + stargazers_count: 42, |
| 43 | + watchers_count: 42, |
| 44 | + language: 'TypeScript', |
| 45 | + topics: ['react', 'nextjs'], |
| 46 | + visibility: 'public' as const, |
| 47 | + updated_at: '2024-01-15T00:00:00.000Z', |
| 48 | + created_at: '2023-01-01T00:00:00.000Z', |
| 49 | + }, |
| 50 | + { |
| 51 | + id: 2, |
| 52 | + node_id: 'R_kgDOGq0qMg', |
| 53 | + name: 'another-repo', |
| 54 | + full_name: 'testuser/another-repo', |
| 55 | + owner: { |
| 56 | + login: 'testuser', |
| 57 | + avatar_url: 'https://avatars.githubusercontent.com/u/12345?v=4', |
| 58 | + }, |
| 59 | + description: 'Another test repository', |
| 60 | + html_url: 'https://github.com/testuser/another-repo', |
| 61 | + homepage: null, |
| 62 | + stargazers_count: 128, |
| 63 | + watchers_count: 128, |
| 64 | + language: 'JavaScript', |
| 65 | + topics: ['nodejs', 'api'], |
| 66 | + visibility: 'public' as const, |
| 67 | + updated_at: '2024-01-10T00:00:00.000Z', |
| 68 | + created_at: '2023-06-01T00:00:00.000Z', |
| 69 | + }, |
| 70 | + { |
| 71 | + id: 3, |
| 72 | + node_id: 'R_kgDOGq0qMz', |
| 73 | + name: 'private-project', |
| 74 | + full_name: 'testuser/private-project', |
| 75 | + owner: { |
| 76 | + login: 'testuser', |
| 77 | + avatar_url: 'https://avatars.githubusercontent.com/u/12345?v=4', |
| 78 | + }, |
| 79 | + description: 'A private project', |
| 80 | + html_url: 'https://github.com/testuser/private-project', |
| 81 | + homepage: null, |
| 82 | + stargazers_count: 0, |
| 83 | + watchers_count: 1, |
| 84 | + language: 'Python', |
| 85 | + topics: ['private', 'internal'], |
| 86 | + visibility: 'private' as const, |
| 87 | + updated_at: '2024-01-20T00:00:00.000Z', |
| 88 | + created_at: '2024-01-01T00:00:00.000Z', |
| 89 | + }, |
| 90 | +] |
| 91 | + |
| 92 | +const MOCK_GITHUB_ORGS = [ |
| 93 | + { |
| 94 | + id: 100, |
| 95 | + login: 'laststance', |
| 96 | + avatar_url: 'https://avatars.githubusercontent.com/u/100?v=4', |
| 97 | + description: 'Laststance.io organization', |
| 98 | + }, |
| 99 | + { |
| 100 | + id: 101, |
| 101 | + login: 'test-org', |
| 102 | + avatar_url: 'https://avatars.githubusercontent.com/u/101?v=4', |
| 103 | + description: 'Test organization for development', |
| 104 | + }, |
| 105 | +] |
| 106 | + |
16 | 107 | export interface GitHubRepository { |
17 | 108 | id: number |
18 | 109 | node_id: string |
@@ -51,6 +142,11 @@ export async function getAuthenticatedUserRepositories(params?: { |
51 | 142 | per_page?: number |
52 | 143 | page?: number |
53 | 144 | }): Promise<{ data: GitHubRepository[] | null; error: string | null }> { |
| 145 | + // E2E test mode: return mock data |
| 146 | + if (isTestMode()) { |
| 147 | + return { data: MOCK_GITHUB_REPOS, error: null } |
| 148 | + } |
| 149 | + |
54 | 150 | const token = await getGitHubToken() |
55 | 151 |
|
56 | 152 | if (!token) { |
@@ -119,6 +215,20 @@ export async function searchRepositories(params: { |
119 | 215 | data: { total_count: number; items: GitHubRepository[] } | null |
120 | 216 | error: string | null |
121 | 217 | }> { |
| 218 | + // E2E test mode: return filtered mock data |
| 219 | + if (isTestMode()) { |
| 220 | + const query = params.q.toLowerCase() |
| 221 | + const filtered = MOCK_GITHUB_REPOS.filter( |
| 222 | + (repo) => |
| 223 | + repo.name.toLowerCase().includes(query) || |
| 224 | + (repo.description?.toLowerCase().includes(query) ?? false), |
| 225 | + ) |
| 226 | + return { |
| 227 | + data: { total_count: filtered.length, items: filtered }, |
| 228 | + error: null, |
| 229 | + } |
| 230 | + } |
| 231 | + |
122 | 232 | const token = await getGitHubToken() |
123 | 233 |
|
124 | 234 | if (!token) { |
@@ -185,6 +295,15 @@ export async function getRepository( |
185 | 295 | owner: string, |
186 | 296 | repo: string, |
187 | 297 | ): Promise<{ data: GitHubRepository | null; error: string | null }> { |
| 298 | + // E2E test mode: return mock data |
| 299 | + if (isTestMode()) { |
| 300 | + const fullName = `${owner}/${repo}` |
| 301 | + const found = MOCK_GITHUB_REPOS.find((r) => r.full_name === fullName) |
| 302 | + return found |
| 303 | + ? { data: found, error: null } |
| 304 | + : { data: null, error: 'Repository not found.' } |
| 305 | + } |
| 306 | + |
188 | 307 | const token = await getGitHubToken() |
189 | 308 |
|
190 | 309 | if (!token) { |
@@ -247,6 +366,11 @@ export async function checkGitHubTokenValidity(): Promise<{ |
247 | 366 | valid: boolean |
248 | 367 | error: string | null |
249 | 368 | }> { |
| 369 | + // E2E test mode: always valid |
| 370 | + if (isTestMode()) { |
| 371 | + return { valid: true, error: null } |
| 372 | + } |
| 373 | + |
250 | 374 | const token = await getGitHubToken() |
251 | 375 |
|
252 | 376 | if (!token) { |
@@ -307,6 +431,11 @@ export async function getAuthenticatedUser(): Promise<{ |
307 | 431 | data: GitHubUser | null |
308 | 432 | error: string | null |
309 | 433 | }> { |
| 434 | + // E2E test mode: return mock user |
| 435 | + if (isTestMode()) { |
| 436 | + return { data: MOCK_GITHUB_USER, error: null } |
| 437 | + } |
| 438 | + |
310 | 439 | const token = await getGitHubToken() |
311 | 440 |
|
312 | 441 | if (!token) { |
@@ -368,6 +497,11 @@ export async function getAuthenticatedUserOrganizations(): Promise<{ |
368 | 497 | data: GitHubOrganization[] | null |
369 | 498 | error: string | null |
370 | 499 | }> { |
| 500 | + // E2E test mode: return mock organizations |
| 501 | + if (isTestMode()) { |
| 502 | + return { data: MOCK_GITHUB_ORGS, error: null } |
| 503 | + } |
| 504 | + |
371 | 505 | const token = await getGitHubToken() |
372 | 506 |
|
373 | 507 | if (!token) { |
|
0 commit comments