Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce a new site info API endpoint #513

Merged
merged 37 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2489fd6
ref(fixtures): convert repoInfo to typescript
dcshzj Oct 5, 2022
2477bef
ref(services): migrate SitesService to typescript
dcshzj Oct 5, 2022
74dc9f3
tests: update unit and integration tests for SitesService
dcshzj Oct 5, 2022
9138b7d
ref(sites): migrate sites router to typescript
dcshzj Oct 5, 2022
3658486
fix: revert back to using SessionData
dcshzj Oct 6, 2022
7a7d1f4
fix: remove use of Bluebird and unused getSiteToken function
dcshzj Oct 6, 2022
f7045aa
fix: use more accurate type
dcshzj Oct 6, 2022
e34cc42
chore: remove unused variable
dcshzj Oct 6, 2022
8c2275e
refactor(tests): migrate generic axios instance to __mocks__
dcshzj Oct 6, 2022
81cf8cc
feat: introduce function to obtain latest commit details
dcshzj Oct 7, 2022
c8a96ce
feat: add function for obtaining a User by ID
dcshzj Oct 7, 2022
e5eded1
feat: introduce a new site info API endpoint
dcshzj Oct 7, 2022
aeab0f8
tests: add partial tests for SitesService
dcshzj Oct 7, 2022
e0fbc16
tests: use mockAxios directly instead of preparing an instance
dcshzj Oct 10, 2022
dcd72e7
Merge branch 'refactor/sites-service-typescript' into feat/site-info
dcshzj Oct 10, 2022
9ae3361
tests: fix SitesService unit tests to pass
dcshzj Oct 10, 2022
b126c53
chore: adjust constants to use SCREAMING_SNAKE_CASE
dcshzj Oct 10, 2022
e9b0112
fix: add authorizationMiddleware to ensure user is member of site
dcshzj Oct 11, 2022
d335ebf
chore: combine sessionData unpacking
dcshzj Oct 11, 2022
5ef57a4
fix: insert try-catch to handle errors from JSON.parse
dcshzj Oct 11, 2022
66defaa
chore: remove unnecessary check for undefined site
dcshzj Oct 11, 2022
ed61f55
chore: return instead of throwing NotFoundError
dcshzj Oct 11, 2022
9ca0838
fix: add assertion to ensure integrity of GitHubCommitData
dcshzj Oct 11, 2022
a12ad20
fix: remove need for adding site name to sessionData
dcshzj Oct 11, 2022
6ca64f2
refactor: convert routes Sites.spec.js to TypeScript
dcshzj Oct 11, 2022
4432732
refactor: redesign getUrlsOfSite to increase readability
dcshzj Oct 11, 2022
4f2735f
Merge branch 'feat/identity-phase-2' into feat/site-info
dcshzj Oct 12, 2022
baf16c8
fix: use correct endpoint to get latest commit data
dcshzj Oct 13, 2022
b90f80e
test: add unit tests for GitHubService getLatestCommitOfBranch
dcshzj Oct 13, 2022
208d143
fix: add stub for obtaining merge author details
dcshzj Oct 13, 2022
99d9140
fix: return a well-formatted response for known exceptions
dcshzj Oct 13, 2022
cdf94ea
test: enhance GitHubService test for all other error statuses
dcshzj Oct 13, 2022
1eb32dd
chore: rename isType function and return boolean directly
dcshzj Oct 13, 2022
3692b08
fix: create new siteUrls object instead of changing in-place
dcshzj Oct 13, 2022
fdf07a5
fix: handle case of null or undefined user email
dcshzj Oct 13, 2022
42e73df
chore: improve code style
dcshzj Oct 13, 2022
d8d7b2b
tests: fix output of getStagingUrl
dcshzj Oct 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/__mocks__/axios.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
import mockAxios from "jest-mock-axios"

const getMockAxiosInstance = () => {
const mockAxiosInstance = mockAxios.create()
mockAxiosInstance.get.mockResolvedValue({ data: [] })
mockAxiosInstance.post.mockResolvedValue({ data: [] })
mockAxiosInstance.put.mockResolvedValue({ data: [] })
mockAxiosInstance.delete.mockResolvedValue({ data: [] })
return mockAxiosInstance
}

export const mockAxiosInstance = getMockAxiosInstance()

export const prepareAxiosMock = () => {
// NOTE: We need to mock the axios instance using es5 named exports
// to ensure that the calls for .get() on the instance will actually
// return a value and not fail.
jest.mock("../services/api/AxiosInstance.ts", () => ({
__esModule: true, // this property makes it work
mockAxiosInstance,
}))
}

export default mockAxios
24 changes: 24 additions & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,27 @@ export enum CollaboratorRoles {
export const E2E_ISOMER_ID = "-1"
export const E2E_TEST_EMAIL = "test@e2e"
export const E2E_TEST_CONTACT = "12345678"

export const GH_MAX_REPO_COUNT = 100
export const ISOMERPAGES_REPO_PAGE_COUNT =
(process.env.ISOMERPAGES_REPO_PAGE_COUNT &&
parseInt(process.env.ISOMERPAGES_REPO_PAGE_COUNT, 10)) ||
3
export const ISOMER_GITHUB_ORG_NAME = process.env.GITHUB_ORG_NAME
export const ISOMER_ADMIN_REPOS = [
"isomercms-backend",
"isomercms-frontend",
"isomer-redirection",
"isomerpages-template",
"isomer-conversion-scripts",
"isomer-wysiwyg",
"isomer-slackbot",
"isomer-tooling",
"generate-site",
"travisci-scripts",
"recommender-train",
"editor",
"ci-test",
"infra",
"markdown-helper",
]
22 changes: 22 additions & 0 deletions src/fixtures/identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Attributes } from "sequelize/types"

import { User, SiteMember } from "@database/models"

import { mockIsomerUserId } from "./sessionData"

export const mockRecipient = "[email protected]"
export const mockSubject = "mock subject"
export const mockBody = "somebody"
Expand Down Expand Up @@ -138,3 +140,23 @@ export const mockSiteOrmResponseWithNoCollaborators = {
id: 1,
site_members: "",
}

export const mockCommitMessage1 = "Update file: Example.md"
export const mockCommitFileName1 = "Example.md"
export const mockGitHubEmailAddress1 = "[email protected]"
export const mockGitHubDate1 = "2022-09-22T04:07:53Z"
export const mockCommitMessageObject1 = {
message: mockCommitMessage1,
fileName: mockCommitFileName1,
userId: mockIsomerUserId,
}

export const mockCommitMessage2 = "Update file: Test.md"
export const mockCommitFileName2 = "Test.md"
export const mockGitHubEmailAddress2 = "[email protected]"
export const mockGitHubDate2 = "2022-09-28T06:25:14Z"
export const mockCommitMessageObject2 = {
message: mockCommitMessage2,
fileName: mockCommitFileName2,
userId: mockIsomerUserId,
}
dcshzj marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 6 additions & 11 deletions src/fixtures/repoInfo.js → src/fixtures/repoInfo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const repoInfo = {
import { GitHubRepositoryData } from "@root/types/repoInfo"

export const repoInfo: GitHubRepositoryData = {
name: "repo",
private: false,
description:
Expand All @@ -13,7 +15,7 @@ const repoInfo = {
},
}

const repoInfo2 = {
export const repoInfo2: GitHubRepositoryData = {
name: "repo2",
private: false,
description:
Expand All @@ -28,7 +30,7 @@ const repoInfo2 = {
},
}

const adminRepo = {
export const adminRepo: GitHubRepositoryData = {
name: "isomercms-backend",
private: false,
description:
Expand All @@ -43,7 +45,7 @@ const adminRepo = {
},
}

const noAccessRepo = {
export const noAccessRepo: GitHubRepositoryData = {
name: "noaccess",
private: false,
description:
Expand All @@ -57,10 +59,3 @@ const noAccessRepo = {
pull: true,
},
}

module.exports = {
repoInfo,
repoInfo2,
adminRepo,
noAccessRepo,
}
28 changes: 10 additions & 18 deletions src/integration/Sites.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import express from "express"
import mockAxios from "jest-mock-axios"
import request from "supertest"

import { IsomerAdmin, Repo, Site, SiteMember, User } from "@database/models"
import { generateRouter } from "@fixtures/app"
import { mockAxiosInstance, prepareAxiosMock } from "@mocks/axios"
import UserSessionData from "@root/classes/UserSessionData"
import { mockEmail, mockIsomerUserId } from "@root/fixtures/sessionData"
import { SitesRouter as _SitesRouter } from "@root/routes/v2/authenticated/sites"
import { GitHubService } from "@root/services/db/GitHubService"
import { ConfigYmlService } from "@root/services/fileServices/YmlFileServices/ConfigYmlService"
import IsomerAdminsService from "@root/services/identity/IsomerAdminsService"
import { SitesService } from "@root/services/utilServices/SitesService"
import SitesService from "@root/services/identity/SitesService"
import TokenStore from "@root/services/identity/TokenStore"
import { getUsersService } from "@services/identity"
import { sequelize } from "@tests/database"

Expand All @@ -21,15 +22,18 @@ const mockUpdatedAt = "now"
const mockPermissions = { push: true }
const mockPrivate = true

const gitHubService = new GitHubService({ axiosInstance: mockAxios.create() })
const gitHubService = new GitHubService({ axiosInstance: mockAxiosInstance })
const configYmlService = new ConfigYmlService({ gitHubService })
const usersService = getUsersService(sequelize)
const isomerAdminsService = new IsomerAdminsService({ repository: IsomerAdmin })
const tokenStore = new TokenStore()
const sitesService = new SitesService({
siteRepository: Site,
gitHubService,
configYmlService,
usersService,
isomerAdminsService,
tokenStore,
})

const SitesRouter = new _SitesRouter({ sitesService })
Expand All @@ -51,21 +55,9 @@ subrouter.use((req, res, next) => {
subrouter.use(sitesSubrouter)
const app = generateRouter(subrouter)

const mockGenericAxios = mockAxios.create()
mockGenericAxios.get.mockResolvedValue({
data: [],
})

describe("Sites Router", () => {
beforeAll(() => {
// NOTE: Because SitesService uses an axios instance,
// we need to mock the axios instance using es5 named exports
// to ensure that the calls for .get() on the instance
// will actually return a value and not fail.
jest.mock("../services/api/AxiosInstance.ts", () => ({
__esModule: true, // this property makes it work
genericGitHubAxiosInstance: mockGenericAxios,
}))
prepareAxiosMock()
})

describe("/", () => {
Expand Down Expand Up @@ -121,7 +113,7 @@ describe("Sites Router", () => {
],
}

mockGenericAxios.get.mockResolvedValueOnce({
mockAxiosInstance.get.mockResolvedValueOnce({
data: [
{
pushed_at: mockUpdatedAt,
Expand Down Expand Up @@ -165,7 +157,7 @@ describe("Sites Router", () => {
},
],
}
mockGenericAxios.get.mockResolvedValueOnce({
mockAxiosInstance.get.mockResolvedValueOnce({
data: [
{
pushed_at: mockUpdatedAt,
Expand Down
11 changes: 1 addition & 10 deletions src/routes/v2/authenticated/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const express = require("express")
const {
NetlifyTomlService,
} = require("@services/configServices/NetlifyTomlService")
const { SitesService } = require("@services/utilServices/SitesService")

const { CollaboratorsRouter } = require("./collaborators")
const { NetlifyTomlRouter } = require("./netlifyToml")
Expand All @@ -12,19 +11,11 @@ const { UsersRouter } = require("./users")

const getAuthenticatedSubrouter = ({
authenticationMiddleware,
gitHubService,
configYmlService,
sitesService,
usersService,
isomerAdminsService,
collaboratorsService,
authorizationMiddleware,
}) => {
const sitesService = new SitesService({
gitHubService,
configYmlService,
usersService,
isomerAdminsService,
})
const netlifyTomlService = new NetlifyTomlService()

const sitesV2Router = new SitesRouter({ sitesService })
Expand Down
83 changes: 0 additions & 83 deletions src/routes/v2/authenticated/sites.js

This file was deleted.

Loading