Skip to content

Commit 12ae7ea

Browse files
committed
test(cli): expand github.mts test coverage
Add tests for getOctokit, getOctokitGraphql, cacheFetch, and writeCache functions to improve coverage of the GitHub utilities module.
1 parent 8dd5271 commit 12ae7ea

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

packages/cli/test/unit/utils/git/github.test.mts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ import { RequestError } from '@octokit/request-error'
2626
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2727

2828
import {
29+
cacheFetch,
30+
getOctokit,
31+
getOctokitGraphql,
2932
handleGitHubApiError,
3033
handleGraphqlError,
3134
isGraphqlRateLimitError,
3235
withGitHubRetry,
36+
writeCache,
3337
} from '../../../../src/utils/git/github.mts'
3438

3539
// Mock debug utilities to suppress output during tests.
@@ -510,3 +514,98 @@ describe('withGitHubRetry', () => {
510514
expect(operation).toHaveBeenCalledTimes(2)
511515
})
512516
})
517+
518+
describe('getOctokit', () => {
519+
it('returns an Octokit instance', () => {
520+
const octokit = getOctokit()
521+
expect(octokit).toBeDefined()
522+
expect(octokit.pulls).toBeDefined()
523+
expect(octokit.repos).toBeDefined()
524+
})
525+
526+
it('returns the same instance on subsequent calls', () => {
527+
const octokit1 = getOctokit()
528+
const octokit2 = getOctokit()
529+
expect(octokit1).toBe(octokit2)
530+
})
531+
})
532+
533+
describe('getOctokitGraphql', () => {
534+
it('returns a GraphQL client', () => {
535+
const graphql = getOctokitGraphql()
536+
expect(graphql).toBeDefined()
537+
expect(typeof graphql).toBe('function')
538+
})
539+
540+
it('returns the same instance on subsequent calls', () => {
541+
const graphql1 = getOctokitGraphql()
542+
const graphql2 = getOctokitGraphql()
543+
expect(graphql1).toBe(graphql2)
544+
})
545+
})
546+
547+
describe('cacheFetch', () => {
548+
afterEach(() => {
549+
vi.useRealTimers()
550+
})
551+
552+
it('calls the fetcher when cache is empty', async () => {
553+
const fetcher = vi.fn().mockResolvedValue({ value: 'fetched' })
554+
// Use unique key to avoid cache from other tests.
555+
const key = `test-fetch-${Date.now()}-${Math.random()}`
556+
557+
const result = await cacheFetch(key, fetcher)
558+
559+
expect(result).toEqual({ value: 'fetched' })
560+
expect(fetcher).toHaveBeenCalledTimes(1)
561+
})
562+
563+
it('returns cached value on subsequent calls', async () => {
564+
const key = `test-cached-${Date.now()}-${Math.random()}`
565+
const fetcher = vi.fn().mockResolvedValue({ value: 'cached' })
566+
567+
// First call populates cache.
568+
await cacheFetch(key, fetcher)
569+
570+
// Second call should use cache.
571+
const result = await cacheFetch(key, fetcher)
572+
573+
expect(result).toEqual({ value: 'cached' })
574+
// Fetcher should only be called once.
575+
expect(fetcher).toHaveBeenCalledTimes(1)
576+
})
577+
578+
it('prevents concurrent fetches for the same key', async () => {
579+
const key = `test-concurrent-${Date.now()}-${Math.random()}`
580+
let resolvePromise: (value: { value: string }) => void
581+
const slowFetcher = vi.fn().mockReturnValue(
582+
new Promise(resolve => {
583+
resolvePromise = resolve
584+
}),
585+
)
586+
587+
// Start two concurrent fetches.
588+
const promise1 = cacheFetch(key, slowFetcher)
589+
const promise2 = cacheFetch(key, slowFetcher)
590+
591+
// Resolve the slow fetcher.
592+
resolvePromise!({ value: 'slow-result' })
593+
594+
const [result1, result2] = await Promise.all([promise1, promise2])
595+
596+
expect(result1).toEqual({ value: 'slow-result' })
597+
expect(result2).toEqual({ value: 'slow-result' })
598+
// Fetcher should only be called once.
599+
expect(slowFetcher).toHaveBeenCalledTimes(1)
600+
})
601+
})
602+
603+
describe('writeCache', () => {
604+
it('writes cache data without throwing', async () => {
605+
const key = `test-write-${Date.now()}-${Math.random()}`
606+
const data = { test: 'data', value: 123 }
607+
608+
// Should not throw.
609+
await expect(writeCache(key, data)).resolves.not.toThrow()
610+
})
611+
})

0 commit comments

Comments
 (0)