diff --git a/.changeset/curly-rice-travel.md b/.changeset/curly-rice-travel.md new file mode 100644 index 000000000000..05a806c0117f --- /dev/null +++ b/.changeset/curly-rice-travel.md @@ -0,0 +1,5 @@ +--- +"wrangler": minor +--- + +Fix wrangler pages deployment (list|tail) environment filtering. diff --git a/packages/wrangler/src/__tests__/pages/deployment-list.test.ts b/packages/wrangler/src/__tests__/pages/deployment-list.test.ts index 828e2ad00ca2..8d86f743288a 100644 --- a/packages/wrangler/src/__tests__/pages/deployment-list.test.ts +++ b/packages/wrangler/src/__tests__/pages/deployment-list.test.ts @@ -47,20 +47,128 @@ describe("pages deployment list", () => { expect(requests.count).toBe(1); }); + + it("should pass no environment", async () => { + const deployments: Deployment[] = [ + { + id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf", + url: "https://87bbc8fe.images.pages.dev", + environment: "preview", + created_on: "2021-11-17T14:52:26.133835Z", + latest_stage: { + ended_on: "2021-11-17T14:52:26.133835Z", + status: "success", + }, + deployment_trigger: { + metadata: { + branch: "main", + commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6", + }, + }, + project_name: "images", + }, + ]; + + const requests = mockDeploymentListRequest(deployments); + await runWrangler("pages deployment list --project-name=images"); + expect(requests.count).toBe(1); + expect( + requests.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toBeUndefined(); + }); + + it("should pass production environment with flag", async () => { + const deployments: Deployment[] = [ + { + id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf", + url: "https://87bbc8fe.images.pages.dev", + environment: "preview", + created_on: "2021-11-17T14:52:26.133835Z", + latest_stage: { + ended_on: "2021-11-17T14:52:26.133835Z", + status: "success", + }, + deployment_trigger: { + metadata: { + branch: "main", + commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6", + }, + }, + project_name: "images", + }, + ]; + + const requests = mockDeploymentListRequest(deployments); + await runWrangler( + "pages deployment list --project-name=images --environment=production" + ); + expect(requests.count).toBe(1); + expect( + requests.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toStrictEqual(["env", "production"]); + }); + + it("should pass preview environment with flag", async () => { + const deployments: Deployment[] = [ + { + id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf", + url: "https://87bbc8fe.images.pages.dev", + environment: "preview", + created_on: "2021-11-17T14:52:26.133835Z", + latest_stage: { + ended_on: "2021-11-17T14:52:26.133835Z", + status: "success", + }, + deployment_trigger: { + metadata: { + branch: "main", + commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6", + }, + }, + project_name: "images", + }, + ]; + + const requests = mockDeploymentListRequest(deployments); + await runWrangler( + "pages deployment list --project-name=images --environment=preview" + ); + expect(requests.count).toBe(1); + expect( + requests.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toStrictEqual(["env", "preview"]); + }); }); /* -------------------------------------------------- */ /* Helper Functions */ /* -------------------------------------------------- */ -function mockDeploymentListRequest(deployments: unknown[]) { - const requests = { count: 0 }; +/** + * A logger used to check how many times a mock API has been hit. + * Useful as a helper in our testing to check if wrangler is making + * the correct API calls without actually sending any web traffic. + */ +type RequestLogger = { + count: number; + queryParams: [string, string][][]; +}; + +function mockDeploymentListRequest(deployments: unknown[]): RequestLogger { + const requests: RequestLogger = { count: 0, queryParams: [] }; msw.use( http.get( "*/accounts/:accountId/pages/projects/:project/deployments", - ({ params }) => { + ({ request, params }) => { requests.count++; - + const url = new URL(request.url); + requests.queryParams.push(Array.from(url.searchParams.entries())); expect(params.project).toEqual("images"); expect(params.accountId).toEqual("some-account-id"); diff --git a/packages/wrangler/src/__tests__/pages/pages-deployment-tail.test.ts b/packages/wrangler/src/__tests__/pages/pages-deployment-tail.test.ts index f293c051ac33..344792b252f7 100644 --- a/packages/wrangler/src/__tests__/pages/pages-deployment-tail.test.ts +++ b/packages/wrangler/src/__tests__/pages/pages-deployment-tail.test.ts @@ -166,6 +166,63 @@ describe("pages deployment tail", () => { ); await api.closeHelper(); }); + + it("passes default environment to deployments list", async () => { + api = mockTailAPIs(); + expect(api.requests.creation.length).toStrictEqual(0); + + await runWrangler( + "pages deployment tail --project-name mock-project mock-deployment-id" + ); + + await expect(api.ws.connected).resolves.toBeTruthy(); + console.log(api.requests.deployments.queryParams[0]); + expect(api.requests.deployments.count).toStrictEqual(1); + expect( + api.requests.deployments.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toStrictEqual(["env", "production"]); + await api.closeHelper(); + }); + + it("passes production environment to deployments list", async () => { + api = mockTailAPIs(); + expect(api.requests.creation.length).toStrictEqual(0); + + await runWrangler( + "pages deployment tail --project-name mock-project mock-deployment-id --environment production" + ); + + await expect(api.ws.connected).resolves.toBeTruthy(); + console.log(api.requests.deployments.queryParams[0]); + expect(api.requests.deployments.count).toStrictEqual(1); + expect( + api.requests.deployments.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toStrictEqual(["env", "production"]); + await api.closeHelper(); + }); + + it("passes preview environment to deployments list", async () => { + api = mockTailAPIs(); + expect(api.requests.creation.length).toStrictEqual(0); + + await runWrangler( + "pages deployment tail --project-name mock-project mock-deployment-id --environment preview" + ); + + await expect(api.ws.connected).resolves.toBeTruthy(); + console.log(api.requests.deployments.queryParams[0]); + expect(api.requests.deployments.count).toStrictEqual(1); + expect( + api.requests.deployments.queryParams[0].find(([key, _]) => { + return key === "env"; + }) + ).toStrictEqual(["env", "preview"]); + await api.closeHelper(); + }); }); describe("filtering", () => { @@ -783,7 +840,7 @@ function deserializeToJson(message: WebSocket.RawData): string { */ type MockAPI = { requests: { - deployments: RequestCounter; + deployments: RequestLogger; creation: RequestInit[]; deletion: RequestCounter; }; @@ -792,17 +849,29 @@ type MockAPI = { closeHelper: () => Promise; }; +/** + * A logger used to check how many times a mock API has been hit. + * Useful as a helper in our testing to check if wrangler is making + * the correct API calls without actually sending any web traffic. + */ +type RequestLogger = { + count: number; + queryParams: [string, string][][]; +}; + /** * Mock out the API hit during Tail creation * * @returns a `RequestCounter` for counting how many times the API is hit */ -function mockListDeployments(): RequestCounter { - const requests: RequestCounter = { count: 0 }; +function mockListDeployments(): RequestLogger { + const requests: RequestLogger = { count: 0, queryParams: [] }; msw.use( http.get( `*/accounts/:accountId/pages/projects/:projectName/deployments`, - () => { + ({ request }) => { + const url = new URL(request.url); + requests.queryParams.push(Array.from(url.searchParams.entries())); requests.count++; return HttpResponse.json( { @@ -839,15 +908,6 @@ function mockListDeployments(): RequestCounter { return requests; } -/** - * A counter used to check how many times a mock API has been hit. - * Useful as a helper in our testing to check if wrangler is making - * the correct API calls without actually sending any web traffic - */ -type RequestCounter = { - count: number; -}; - /** * Mock out the API hit during Tail creation * @@ -911,6 +971,15 @@ const mockEmailEventTo = "to@example.com"; */ const mockEmailEventSize = 45416; +/** + * A counter used to check how many times a mock API has been hit. + * Useful as a helper in our testing to check if wrangler is making + * the correct API calls without actually sending any web traffic + */ +type RequestCounter = { + count: number; +}; + /** * Mock out the API hit during Tail deletion * @@ -950,7 +1019,7 @@ function mockTailAPIs(): MockAPI { requests: { deletion: { count: 0 }, creation: [], - deployments: { count: 0 }, + deployments: { count: 0, queryParams: [] }, }, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ws: null!, // will be set in the `beforeEach()`. diff --git a/packages/wrangler/src/pages/deployment-tails.ts b/packages/wrangler/src/pages/deployment-tails.ts index 96e2a9646302..9e0e9c0cdc57 100644 --- a/packages/wrangler/src/pages/deployment-tails.ts +++ b/packages/wrangler/src/pages/deployment-tails.ts @@ -163,7 +163,9 @@ export async function Handler({ } const deployments: Array = await fetchResult( - `/accounts/${accountId}/pages/projects/${projectName}/deployments` + `/accounts/${accountId}/pages/projects/${projectName}/deployments`, + {}, + new URLSearchParams({ env: environment }) ); const envDeployments = deployments.filter( diff --git a/packages/wrangler/src/pages/deployments.ts b/packages/wrangler/src/pages/deployments.ts index 2de7612ab9f2..6547d8ae1970 100644 --- a/packages/wrangler/src/pages/deployments.ts +++ b/packages/wrangler/src/pages/deployments.ts @@ -23,10 +23,15 @@ export function ListOptions(yargs: CommonYargsArgv) { description: "The name of the project you would like to list deployments for", }, + environment: { + type: "string", + choices: ["production", "preview"], + description: "Environment type to list deployments for", + }, }); } -export async function ListHandler({ projectName }: ListArgs) { +export async function ListHandler({ projectName, environment }: ListArgs) { const config = getConfigCache(PAGES_CONFIG_CACHE_FILENAME); const accountId = await requireAuth(config); @@ -42,7 +47,11 @@ export async function ListHandler({ projectName }: ListArgs) { } const deployments: Array = await fetchResult( - `/accounts/${accountId}/pages/projects/${projectName}/deployments` + `/accounts/${accountId}/pages/projects/${projectName}/deployments`, + {}, + environment + ? new URLSearchParams({ env: environment }) + : new URLSearchParams({}) ); const titleCase = (word: string) =>