diff options
Diffstat (limited to 'src/services/github')
| -rw-r--r-- | src/services/github/fetch-github-repo-meta.test.ts | 47 | ||||
| -rw-r--r-- | src/services/github/fetch-github-repo-meta.ts | 45 | ||||
| -rw-r--r-- | src/services/github/index.ts | 1 |
3 files changed, 93 insertions, 0 deletions
diff --git a/src/services/github/fetch-github-repo-meta.test.ts b/src/services/github/fetch-github-repo-meta.test.ts new file mode 100644 index 0000000..324db9a --- /dev/null +++ b/src/services/github/fetch-github-repo-meta.test.ts @@ -0,0 +1,47 @@ +import { afterEach, describe, expect, it } from '@jest/globals'; +import { githubRepos } from '../../../tests/fixtures'; +import { fetchGithubRepoMeta } from './fetch-github-repo-meta'; + +describe('fetch-github-repo-meta', () => { + afterEach(() => { + window.history.replaceState({}, '', '/'); + }); + + it('returns the Github repository meta using GraphQL', async () => { + const result = await fetchGithubRepoMeta({ + name: githubRepos[0].name, + owner: githubRepos[0].owner, + }); + + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + expect.assertions(3); + + expect(result.createdAt).toBe(githubRepos[0].createdAt); + expect(result.stargazerCount).toBe(githubRepos[0].stargazerCount); + expect(result.updatedAt).toBe(githubRepos[0].updatedAt); + }); + + it('rejects with an error when repository is not found', async () => { + const name = 'inexistent-repo'; + const owner = 'inexistent-owner'; + + window.history.replaceState({}, '', '/?error=true'); + expect.assertions(1); + + await expect(async () => + fetchGithubRepoMeta({ name, owner }) + ).rejects.toEqual( + new Error(`No data found for the following repository ${owner}/${name}.`) + ); + }); + + it('throws an error if the Github token is not defined', async () => { + process.env.NEXT_PUBLIC_GITHUB_TOKEN = ''; + + expect.assertions(1); + + await expect(async () => + fetchGithubRepoMeta({ name: 'any-name', owner: 'any-owner' }) + ).rejects.toThrowError(new Error('Github token is not defined.')); + }); +}); diff --git a/src/services/github/fetch-github-repo-meta.ts b/src/services/github/fetch-github-repo-meta.ts new file mode 100644 index 0000000..14c8516 --- /dev/null +++ b/src/services/github/fetch-github-repo-meta.ts @@ -0,0 +1,45 @@ +import type { GithubRepositoryMeta, Nullable } from '../../types'; +import { GITHUB_API } from '../../utils/constants'; +import { fetchGraphQL } from '../../utils/helpers'; + +export type GithubRepositoryResponse = { + repository: Nullable<GithubRepositoryMeta>; +}; + +const githubRepoQuery = `query GithubRepository($name: String!, $owner: String!) { + repository(name: $name, owner: $owner) { + createdAt + stargazerCount + updatedAt + } +}`; + +export type FetchGithubRepoMetaInput = { + name: string; + owner: string; +}; + +export const fetchGithubRepoMeta = async ({ + name, + owner, +}: FetchGithubRepoMetaInput) => { + const token = process.env.NEXT_PUBLIC_GITHUB_TOKEN; + + if (!token) throw new Error('Github token is not defined.'); + + const response = await fetchGraphQL<GithubRepositoryResponse>({ + headers: { + Authorization: `Bearer ${token}`, + }, + query: githubRepoQuery, + url: GITHUB_API, + variables: { name, owner }, + }); + + if (!response.repository) + return Promise.reject( + new Error(`No data found for the following repository ${owner}/${name}.`) + ); + + return response.repository; +}; diff --git a/src/services/github/index.ts b/src/services/github/index.ts new file mode 100644 index 0000000..44b0cbf --- /dev/null +++ b/src/services/github/index.ts @@ -0,0 +1 @@ +export * from './fetch-github-repo-meta'; |
