-
Notifications
You must be signed in to change notification settings - Fork 2
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
Refactor/sites #341
Merged
Merged
Refactor/sites #341
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
b0abfe6
Feat: add sitesService
alexanderleegs 37c78a9
Feat: add sites router
alexanderleegs 1f007bd
Feat: add site endpoints
alexanderleegs bc4b5fd
Tests: add tests
alexanderleegs 296318e
Fix: use pushed_at instead of updated_at
alexanderleegs 6e21636
Style: add spacing to tests
alexanderleegs 63cc4d9
Style: object destructuring
alexanderleegs 9b05ff7
Style: return type and map
alexanderleegs e94c7d0
Fix: return last updated time instead of string representing time and…
alexanderleegs e6a4d6e
Feat: throw 404 error if no staging url found
alexanderleegs 4005f44
Style: destructuring response
alexanderleegs a7a5380
Feat: add access check in github service
alexanderleegs fc27b00
Fix: tests
alexanderleegs 5b4a4e4
Fix: test comment
alexanderleegs 699784e
Rebase: use auth verify middleware in sites router
alexanderleegs fb05904
Fix: test for config priority
alexanderleegs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,66 @@ | ||
const repoInfo = { | ||
name: "repo", | ||
private: false, | ||
description: | ||
"Staging: https://repo-staging.netlify.app | Production: https://repo-prod.netlify.app", | ||
pushed_at: "2021-09-09T02:41:37Z", | ||
permissions: { | ||
admin: true, | ||
maintain: true, | ||
push: true, | ||
triage: true, | ||
pull: true, | ||
}, | ||
} | ||
|
||
const repoInfo2 = { | ||
name: "repo2", | ||
private: false, | ||
description: | ||
"Staging: https://repo2-staging.netlify.app | Production: https://repo2-prod.netlify.app", | ||
pushed_at: "2021-09-09T02:41:37Z", | ||
permissions: { | ||
admin: true, | ||
maintain: true, | ||
push: true, | ||
triage: true, | ||
pull: true, | ||
}, | ||
} | ||
|
||
const adminRepo = { | ||
name: "isomercms-backend", | ||
private: false, | ||
description: | ||
"Staging: https://isomercms-backend-staging.netlify.app | Production: https://isomercms-backend-prod.netlify.app", | ||
pushed_at: "2021-09-09T02:41:37Z", | ||
permissions: { | ||
admin: true, | ||
maintain: true, | ||
push: true, | ||
triage: true, | ||
pull: true, | ||
}, | ||
} | ||
|
||
const noAccessRepo = { | ||
name: "noaccess", | ||
private: false, | ||
description: | ||
"Staging: https://noaccess-staging.netlify.app | Production: https://noaccess-prod.netlify.app", | ||
pushed_at: "2021-09-09T02:41:37Z", | ||
permissions: { | ||
admin: false, | ||
maintain: false, | ||
push: false, | ||
triage: false, | ||
pull: true, | ||
}, | ||
} | ||
|
||
module.exports = { | ||
repoInfo, | ||
repoInfo2, | ||
adminRepo, | ||
noAccessRepo, | ||
} |
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,113 @@ | ||
const cookieParser = require("cookie-parser") | ||
const express = require("express") | ||
const request = require("supertest") | ||
|
||
const { NotFoundError } = require("@errors/NotFoundError") | ||
|
||
const { errorHandler } = require("@middleware/errorHandler") | ||
const { attachReadRouteHandlerWrapper } = require("@middleware/routeHandler") | ||
|
||
const { SitesRouter } = require("../sites") | ||
|
||
// Can't set request fields - will always be undefined | ||
const userId = undefined | ||
const accessToken = undefined | ||
|
||
const siteName = "siteName" | ||
|
||
const reqDetails = { siteName, accessToken } | ||
|
||
describe("Sites Router", () => { | ||
const mockSitesService = { | ||
getSites: jest.fn(), | ||
checkHasAccess: jest.fn(), | ||
getLastUpdated: jest.fn(), | ||
getStagingUrl: jest.fn(), | ||
} | ||
|
||
const router = new SitesRouter({ | ||
sitesService: mockSitesService, | ||
}) | ||
|
||
const app = express() | ||
app.use(express.json({ limit: "7mb" })) | ||
app.use(express.urlencoded({ extended: false })) | ||
app.use(cookieParser()) | ||
|
||
// We can use read route handler here because we don't need to lock the repo | ||
app.get("/", attachReadRouteHandlerWrapper(router.getSites)) | ||
app.get("/:siteName", attachReadRouteHandlerWrapper(router.checkHasAccess)) | ||
app.get( | ||
"/:siteName/lastUpdated", | ||
attachReadRouteHandlerWrapper(router.getLastUpdated) | ||
) | ||
app.get( | ||
"/:siteName/stagingUrl", | ||
attachReadRouteHandlerWrapper(router.getStagingUrl) | ||
) | ||
app.use(errorHandler) | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
describe("getSites", () => { | ||
it("returns the list of sites accessible to the user", async () => { | ||
const sitesResp = ["site1", "site2"] | ||
mockSitesService.getSites.mockResolvedValueOnce(sitesResp) | ||
|
||
const resp = await request(app).get(`/`).expect(200) | ||
|
||
expect(resp.body).toStrictEqual({ siteNames: sitesResp }) | ||
expect(mockSitesService.getSites).toHaveBeenCalledWith({ accessToken }) | ||
}) | ||
}) | ||
|
||
describe("checkHasAccess", () => { | ||
it("rejects if user has no access to a site", async () => { | ||
mockSitesService.checkHasAccess.mockRejectedValueOnce( | ||
new NotFoundError("") | ||
) | ||
|
||
await request(app).get(`/${siteName}`).expect(404) | ||
|
||
expect(mockSitesService.checkHasAccess).toHaveBeenCalledWith(reqDetails, { | ||
userId, | ||
}) | ||
}) | ||
|
||
it("allows if user has access to a site", async () => { | ||
await request(app).get(`/${siteName}`).expect(200) | ||
|
||
expect(mockSitesService.checkHasAccess).toHaveBeenCalledWith(reqDetails, { | ||
userId, | ||
}) | ||
}) | ||
}) | ||
|
||
describe("getLastUpdated", () => { | ||
it("returns the last updated time", async () => { | ||
const lastUpdated = "last-updated" | ||
mockSitesService.getLastUpdated.mockResolvedValueOnce(lastUpdated) | ||
|
||
const resp = await request(app) | ||
.get(`/${siteName}/lastUpdated`) | ||
.expect(200) | ||
|
||
expect(resp.body).toStrictEqual({ lastUpdated }) | ||
expect(mockSitesService.getLastUpdated).toHaveBeenCalledWith(reqDetails) | ||
}) | ||
}) | ||
|
||
describe("getStagingUrl", () => { | ||
it("returns the last updated time", async () => { | ||
const stagingUrl = "staging-url" | ||
mockSitesService.getStagingUrl.mockResolvedValueOnce(stagingUrl) | ||
|
||
const resp = await request(app).get(`/${siteName}/stagingUrl`).expect(200) | ||
|
||
expect(resp.body).toStrictEqual({ stagingUrl }) | ||
expect(mockSitesService.getStagingUrl).toHaveBeenCalledWith(reqDetails) | ||
}) | ||
}) | ||
}) |
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 @@ | ||
const autoBind = require("auto-bind") | ||
const express = require("express") | ||
|
||
// Import middleware | ||
const { attachReadRouteHandlerWrapper } = require("@middleware/routeHandler") | ||
|
||
const { authMiddleware } = require("@root/newmiddleware/index") | ||
|
||
class SitesRouter { | ||
constructor({ sitesService }) { | ||
this.sitesService = sitesService | ||
// We need to bind all methods because we don't invoke them from the class directly | ||
autoBind(this) | ||
} | ||
|
||
async getSites(req, res) { | ||
const { accessToken } = req | ||
const siteNames = await this.sitesService.getSites({ accessToken }) | ||
return res.status(200).json({ siteNames }) | ||
} | ||
|
||
async checkHasAccess(req, res) { | ||
const { | ||
accessToken, | ||
userId, | ||
params: { siteName }, | ||
} = req | ||
|
||
await this.sitesService.checkHasAccess( | ||
{ | ||
accessToken, | ||
siteName, | ||
}, | ||
{ userId } | ||
) | ||
return res.status(200).send("OK") | ||
} | ||
|
||
async getLastUpdated(req, res) { | ||
const { | ||
accessToken, | ||
params: { siteName }, | ||
} = req | ||
const lastUpdated = await this.sitesService.getLastUpdated({ | ||
accessToken, | ||
siteName, | ||
}) | ||
return res.status(200).json({ lastUpdated }) | ||
} | ||
|
||
async getStagingUrl(req, res) { | ||
const { | ||
accessToken, | ||
params: { siteName }, | ||
} = req | ||
|
||
const stagingUrl = await this.sitesService.getStagingUrl({ | ||
accessToken, | ||
siteName, | ||
}) | ||
return res.status(200).json({ stagingUrl }) | ||
} | ||
|
||
getRouter() { | ||
const router = express.Router() | ||
|
||
router.use(authMiddleware.verifyJwt) | ||
|
||
router.get("/", attachReadRouteHandlerWrapper(this.getSites)) | ||
router.get("/:siteName", attachReadRouteHandlerWrapper(this.checkHasAccess)) | ||
router.get( | ||
"/:siteName/lastUpdated", | ||
attachReadRouteHandlerWrapper(this.getLastUpdated) | ||
) | ||
router.get( | ||
"/:siteName/stagingUrl", | ||
attachReadRouteHandlerWrapper(this.getStagingUrl) | ||
) | ||
|
||
return router | ||
} | ||
} | ||
|
||
module.exports = { SitesRouter } |
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
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove the
.send("OK")
if it's unneededThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e647810
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^this commit got lost, unsure if there are others. i'm fine iwth not doing this as it's relatively minor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit was preserved as 9b05ff7 - rebasing seems to overwrite the original commit hash! I did reintroduce the
.send("OK")
in a later commit because one of the tests was failing, and elected to use.send("OK")
to keep it in line with how we return responses in the rest of our routers