From 90eb48ebc16377706b067d3d6240ffc7cabc3f92 Mon Sep 17 00:00:00 2001 From: Hsu Zhong Jun <27919917+dcshzj@users.noreply.github.com> Date: Thu, 20 Oct 2022 16:23:29 +0800 Subject: [PATCH] feat: add new siteUrl API endpoint to get the production URL of site (#535) --- .../v2/authenticated/__tests__/Sites.spec.ts | 23 +++++++++- src/routes/v2/authenticated/sites.ts | 26 ++++++++++- src/services/identity/SitesService.ts | 15 +++++++ .../identity/__tests__/SitesService.spec.ts | 45 +++++++++++++++++++ 4 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/routes/v2/authenticated/__tests__/Sites.spec.ts b/src/routes/v2/authenticated/__tests__/Sites.spec.ts index 894760a28..485092714 100644 --- a/src/routes/v2/authenticated/__tests__/Sites.spec.ts +++ b/src/routes/v2/authenticated/__tests__/Sites.spec.ts @@ -19,6 +19,7 @@ describe("Sites Router", () => { getSites: jest.fn(), getLastUpdated: jest.fn(), getStagingUrl: jest.fn(), + getSiteUrl: jest.fn(), getSiteInfo: jest.fn(), } @@ -43,6 +44,10 @@ describe("Sites Router", () => { "/:siteName/stagingUrl", attachReadRouteHandlerWrapper(router.getStagingUrl) ) + subrouter.get( + "/:siteName/siteUrl", + attachReadRouteHandlerWrapper(router.getSiteUrl) + ) subrouter.get( "/:siteName/info", attachReadRouteHandlerWrapper(router.getSiteInfo) @@ -92,13 +97,29 @@ describe("Sites Router", () => { .get(`/${mockSiteName}/stagingUrl`) .expect(200) - expect(resp.body).toStrictEqual({ possibleStagingUrl: stagingUrl }) + expect(resp.body).toStrictEqual({ stagingUrl }) expect(mockSitesService.getStagingUrl).toHaveBeenCalledWith( mockUserWithSiteSessionData ) }) }) + describe("getSiteUrl", () => { + it("returns the site's site URL", async () => { + const siteUrl = "prod-url" + mockSitesService.getSiteUrl.mockResolvedValueOnce(siteUrl) + + const resp = await request(app) + .get(`/${mockSiteName}/siteUrl`) + .expect(200) + + expect(resp.body).toStrictEqual({ siteUrl }) + expect(mockSitesService.getSiteUrl).toHaveBeenCalledWith( + mockUserWithSiteSessionData + ) + }) + }) + describe("getSiteInfo", () => { it("returns the site's info", async () => { const siteInfo = { diff --git a/src/routes/v2/authenticated/sites.ts b/src/routes/v2/authenticated/sites.ts index d8e18e857..e03771b87 100644 --- a/src/routes/v2/authenticated/sites.ts +++ b/src/routes/v2/authenticated/sites.ts @@ -71,7 +71,26 @@ export class SitesRouter { if (possibleStagingUrl instanceof BaseIsomerError) { return res.status(404).json({ message: possibleStagingUrl.message }) } - return res.status(200).json({ possibleStagingUrl }) + return res.status(200).json({ stagingUrl: possibleStagingUrl }) + } + + getSiteUrl: RequestHandler< + { siteName: string }, + unknown, + never, + never, + { userWithSiteSessionData: UserWithSiteSessionData } + > = async (req, res) => { + const { userWithSiteSessionData } = res.locals + const possibleSiteUrl = await this.sitesService.getSiteUrl( + userWithSiteSessionData + ) + + // Check for error and throw + if (possibleSiteUrl instanceof BaseIsomerError) { + return res.status(404).json({ message: possibleSiteUrl.message }) + } + return res.status(200).json({ siteUrl: possibleSiteUrl }) } getSiteInfo: RequestHandler< @@ -108,6 +127,11 @@ export class SitesRouter { attachSiteHandler, attachReadRouteHandlerWrapper(this.getStagingUrl) ) + router.get( + "/:siteName/siteUrl", + attachSiteHandler, + attachReadRouteHandlerWrapper(this.getSiteUrl) + ) router.get( "/:siteName/info", attachSiteHandler, diff --git a/src/services/identity/SitesService.ts b/src/services/identity/SitesService.ts index c5a6cb11c..6d1dedf14 100644 --- a/src/services/identity/SitesService.ts +++ b/src/services/identity/SitesService.ts @@ -330,6 +330,21 @@ class SitesService { return staging } + async getSiteUrl( + sessionData: UserWithSiteSessionData + ): Promise { + const siteUrls = await this.getUrlsOfSite(sessionData) + if (siteUrls instanceof NotFoundError) { + return new NotFoundError( + `${sessionData.siteName} does not have a site url` + ) + } + + const { prod } = siteUrls + + return prod + } + async create( createParams: Partial & { name: Site["name"] diff --git a/src/services/identity/__tests__/SitesService.spec.ts b/src/services/identity/__tests__/SitesService.spec.ts index 829cb941a..6fae455ab 100644 --- a/src/services/identity/__tests__/SitesService.spec.ts +++ b/src/services/identity/__tests__/SitesService.spec.ts @@ -502,6 +502,51 @@ describe("SitesService", () => { }) }) + describe("getSiteUrl", () => { + const stagingUrl = "https://repo-staging.netlify.app" + const productionUrl = "https://repo-prod.netlify.app" + + it("should return the site URL if it is available", async () => { + // Arrange + const mockSiteWithDeployment = { + ...mockSite, + deployment: { stagingUrl, productionUrl }, + } + + MockRepository.findOne.mockResolvedValueOnce(mockSiteWithDeployment) + + // Act + const actual = await SitesService.getSiteUrl( + mockSessionDataEmailUserWithSite + ) + + // Assert + expect(actual).toEqual(productionUrl) + expect(MockRepository.findOne).toHaveBeenCalled() + }) + + it("should return an error when the site url for a repo is not found", async () => { + // Arrange + MockRepository.findOne.mockResolvedValueOnce(null) + MockConfigYmlService.read.mockResolvedValueOnce({ + content: {}, + }) + MockGithubService.getRepoInfo.mockResolvedValueOnce({ + description: "", + }) + + // Act + await expect( + SitesService.getSiteUrl(mockUserWithSiteSessionData) + ).resolves.toBeInstanceOf(NotFoundError) + + // Assert + expect(MockRepository.findOne).toHaveBeenCalled() + expect(MockConfigYmlService.read).toHaveBeenCalled() + expect(MockGithubService.getRepoInfo).toHaveBeenCalled() + }) + }) + describe("getSiteInfo", () => { const stagingUrl = "https://repo-staging.netlify.app" const productionUrl = "https://repo-prod.netlify.app"