-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from HubSpot/br-unit-tests-12
Separating github api calls into new file and adding some tests
- Loading branch information
Showing
6 changed files
with
226 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import axios, { AxiosResponse } from 'axios'; | ||
import { DEFAULT_USER_AGENT_HEADERS } from '../http/getAxiosConfig'; | ||
import { GithubReleaseData, GithubRepoFile } from '../types/Github'; | ||
|
||
const GITHUB_REPOS_API = 'https://api.github.com/repos'; | ||
const GITHUB_RAW_CONTENT_API_PATH = 'https://raw.githubusercontent.com'; | ||
|
||
declare global { | ||
// eslint-disable-next-line no-var | ||
var githubToken: string; | ||
} | ||
|
||
type RepoPath = `${string}/${string}`; | ||
|
||
const GITHUB_AUTH_HEADERS = { | ||
authorization: | ||
global && global.githubToken ? `Bearer ${global.githubToken}` : null, | ||
}; | ||
|
||
// Returns information about the repo's releases. Defaults to "latest" if no tag is provided | ||
// https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#get-a-release-by-tag-name | ||
export async function fetchRepoReleaseData( | ||
repoPath: RepoPath, | ||
tag = '' | ||
): Promise<AxiosResponse<GithubReleaseData>> { | ||
const URL = `${GITHUB_REPOS_API}/${repoPath}/releases`; | ||
|
||
return axios.get<GithubReleaseData>( | ||
`${URL}/${tag ? `tags/${tag}` : 'latest'}`, | ||
{ | ||
headers: { ...DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS }, | ||
} | ||
); | ||
} | ||
|
||
// Returns the entire repo content as a zip, using the zipball_url from fetchRepoReleaseData() | ||
// https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#download-a-repository-archive-zip | ||
export async function fetchRepoAsZip( | ||
zipUrl: string | ||
): Promise<AxiosResponse<Buffer>> { | ||
return axios.get<Buffer>(zipUrl, { | ||
headers: { ...DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS }, | ||
}); | ||
} | ||
|
||
// Returns the raw file contents via the raw.githubusercontent endpoint | ||
export async function fetchRepoFile( | ||
repoPath: RepoPath, | ||
filePath: string, | ||
ref: string | ||
): Promise<AxiosResponse<Buffer>> { | ||
return axios.get<Buffer>( | ||
`${GITHUB_RAW_CONTENT_API_PATH}/${repoPath}/${ref}/${filePath}`, | ||
{ | ||
headers: { ...DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS }, | ||
} | ||
); | ||
} | ||
|
||
// Returns the raw file contents via the raw.githubusercontent endpoint | ||
export async function fetchRepoFileByDownloadUrl( | ||
downloadUrl: string | ||
): Promise<AxiosResponse<Buffer>> { | ||
return axios.get<Buffer>(downloadUrl, { | ||
headers: { ...DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS }, | ||
}); | ||
} | ||
|
||
// Returns the contents of a file or directory in a repository by path | ||
// https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content | ||
export async function fetchRepoContents( | ||
repoPath: RepoPath, | ||
path: string, | ||
ref?: string | ||
): Promise<AxiosResponse<Array<GithubRepoFile>>> { | ||
const refQuery = ref ? `?ref=${ref}` : ''; | ||
|
||
return axios.get<Array<GithubRepoFile>>( | ||
`${GITHUB_REPOS_API}/${repoPath}/contents/${path}${refQuery}`, | ||
{ | ||
headers: { ...DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS }, | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { fetchFileFromRepository } from '../github'; | ||
import { fetchRepoFile as __fetchRepoFile } from '../../api/github'; | ||
|
||
jest.mock('../../api/github'); | ||
|
||
const fetchRepoFile = __fetchRepoFile as jest.MockedFunction< | ||
typeof __fetchRepoFile | ||
>; | ||
|
||
describe('lib/github', () => { | ||
describe('fetchFileFromRepository()', () => { | ||
beforeAll(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
fetchRepoFile.mockResolvedValue({ data: null } as any); | ||
}); | ||
|
||
afterAll(() => { | ||
fetchRepoFile.mockReset(); | ||
}); | ||
|
||
it('downloads a github repo and writes it to a destination folder', async () => { | ||
await fetchFileFromRepository('owner/repo', 'file', 'ref'); | ||
expect(fetchRepoFile).toHaveBeenCalledWith('owner/repo', 'file', 'ref'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import axios from 'axios'; | ||
import { trackUsage } from '../trackUsage'; | ||
import { | ||
getAccountConfig as __getAccountConfig, | ||
getAndLoadConfigIfNeeded as __getAndLoadConfigIfNeeded, | ||
} from '../../config'; | ||
import { AuthType } from '../../types/Accounts'; | ||
import { ENVIRONMENTS } from '../../constants/environments'; | ||
|
||
jest.mock('axios'); | ||
jest.mock('../../config'); | ||
|
||
const mockedAxios = jest.mocked(axios); | ||
const getAccountConfig = __getAccountConfig as jest.MockedFunction< | ||
typeof __getAccountConfig | ||
>; | ||
const getAndLoadConfigIfNeeded = | ||
__getAndLoadConfigIfNeeded as jest.MockedFunction< | ||
typeof __getAndLoadConfigIfNeeded | ||
>; | ||
|
||
mockedAxios.mockResolvedValue({}); | ||
getAndLoadConfigIfNeeded.mockReturnValue({}); | ||
|
||
const account = { | ||
accountId: 12345, | ||
authType: 'personalaccesskey' as AuthType, | ||
personalAccessKey: 'let-me-in-3', | ||
auth: { | ||
tokenInfo: { | ||
expiresAt: '', | ||
accessToken: 'test-token', | ||
}, | ||
}, | ||
env: ENVIRONMENTS.QA, | ||
}; | ||
|
||
const usageTrackingMeta = { | ||
action: 'cli-command', | ||
command: 'test-command', | ||
}; | ||
|
||
describe('lib/trackUsage', () => { | ||
describe('trackUsage()', () => { | ||
beforeEach(() => { | ||
mockedAxios.mockClear(); | ||
getAccountConfig.mockReset(); | ||
getAccountConfig.mockReturnValue(account); | ||
}); | ||
|
||
it('tracks correctly for unauthenticated accounts', async () => { | ||
await trackUsage('test-action', 'INTERACTION', usageTrackingMeta); | ||
const requestArgs = mockedAxios.mock.lastCall | ||
? mockedAxios.mock.lastCall[0] | ||
: ({} as any); // eslint-disable-line @typescript-eslint/no-explicit-any | ||
|
||
expect(mockedAxios).toHaveBeenCalled(); | ||
expect(requestArgs!.data.eventName).toEqual('test-action'); | ||
expect(requestArgs!.url.includes('authenticated')).toBeFalsy(); | ||
expect(getAccountConfig).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('tracks correctly for authenticated accounts', async () => { | ||
await trackUsage('test-action', 'INTERACTION', usageTrackingMeta, 12345); | ||
const requestArgs = mockedAxios.mock.lastCall | ||
? mockedAxios.mock.lastCall[0] | ||
: ({} as any); // eslint-disable-line @typescript-eslint/no-explicit-any | ||
|
||
expect(mockedAxios).toHaveBeenCalled(); | ||
expect(requestArgs!.data.eventName).toEqual('test-action'); | ||
expect(requestArgs!.url.includes('authenticated')).toBeTruthy(); | ||
expect(getAccountConfig).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters