Skip to content

Commit 14ce19b

Browse files
committed
whoohoo end-to-end test of kicking off cloud build
1 parent bc60124 commit 14ce19b

File tree

3 files changed

+100
-9
lines changed

3 files changed

+100
-9
lines changed

src/deploy.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ const BUILD_AGE_WARNING_MS = 1000 * 60 * 5;
3838

3939
const OBSERVABLE_UI_ORIGIN = getObservableUiOrigin();
4040

41-
export function formatGitUrl(url: string) {
42-
return new URL(url).pathname.slice(1).replace(/\.git$/, "");
43-
}
44-
4541
function settingsUrl(deployTarget: DeployTargetInfo) {
4642
if (deployTarget.create) {
4743
throw new Error("Incorrect deploy target state");

test/deploy-test.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,12 @@ describe("deploy", () => {
231231
workspaceLogin: DEPLOY_CONFIG.workspaceLogin,
232232
projects: []
233233
})
234-
.handlePostProject({projectId: DEPLOY_CONFIG.projectId})
234+
.handlePostProject({projectId: DEPLOY_CONFIG.projectId, slug: DEPLOY_CONFIG.projectSlug})
235235
.start();
236236
const effects = new MockDeployEffects();
237237
effects.clack.inputs.push(
238238
true, // No apps found. Do you want to create a new app?
239-
"cloud-deployed-app", // What slug do you want to use?
239+
DEPLOY_CONFIG.projectSlug, // What slug do you want to use?
240240
"public", // Who is allowed to access your app?
241241
true // Do you want to enable continuous deployment?
242242
);
@@ -250,6 +250,39 @@ describe("deploy", () => {
250250

251251
effects.close();
252252
});
253+
254+
it("starts cloud build when continuous deployment is enabled and repo is valid", async () => {
255+
const deployId = "deploy123";
256+
getCurrentObservableApi()
257+
.handleGetCurrentUser()
258+
.handleGetWorkspaceProjects({
259+
workspaceLogin: DEPLOY_CONFIG.workspaceLogin,
260+
projects: []
261+
})
262+
.handlePostProject({projectId: DEPLOY_CONFIG.projectId, slug: DEPLOY_CONFIG.projectSlug})
263+
.handleGetRepository()
264+
.handlePostProjectEnvironment()
265+
.handlePostProjectBuild()
266+
.handleGetProject({...DEPLOY_CONFIG, latestCreatedDeployId: deployId})
267+
.handleGetDeploy({deployId, deployStatus: "uploaded"})
268+
.start();
269+
const effects = new MockDeployEffects();
270+
effects.clack.inputs.push(
271+
true, // No apps found. Do you want to create a new app?
272+
DEPLOY_CONFIG.projectSlug, // What slug do you want to use?
273+
"public", // Who is allowed to access your app?
274+
true // Do you want to enable continuous deployment?
275+
);
276+
277+
await promisify(exec)(
278+
"touch readme.md; git add .; git commit -m 'initial'; git remote add origin [email protected]:observablehq/test.git"
279+
);
280+
281+
await deploy(TEST_OPTIONS, effects);
282+
283+
effects.close();
284+
});
285+
253286
});
254287

255288
describe("in isolated directory without git repo", () => {
@@ -267,7 +300,7 @@ describe("deploy", () => {
267300
const effects = new MockDeployEffects();
268301
effects.clack.inputs.push(
269302
true, // No apps found. Do you want to create a new app?
270-
"cloud-deployed-app", // What slug do you want to use?
303+
DEPLOY_CONFIG.projectSlug, // What slug do you want to use?
271304
"public", // Who is allowed to access your app?
272305
true // Do you want to enable continuous deployment?
273306
);

test/mocks/observableApi.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class ObservableApiMock {
149149
projectId = "project123",
150150
title = "Build test case",
151151
accessLevel = "private",
152+
latestCreatedDeployId = null,
152153
status = 200
153154
}: {
154155
workspaceLogin: string;
@@ -157,6 +158,7 @@ class ObservableApiMock {
157158
title?: string;
158159
accessLevel?: string;
159160
status?: number;
161+
latestCreatedDeployId?: null | string;
160162
}): ObservableApiMock {
161163
const response =
162164
status === 200
@@ -167,8 +169,8 @@ class ObservableApiMock {
167169
title,
168170
creator: {id: "user-id", login: "user-login"},
169171
owner: {id: "workspace-id", login: "workspace-login"},
170-
latestCreatedDeployId: null,
171-
automatic_builds_enabled: null,
172+
latestCreatedDeployId,
173+
automatic_builds_enabled: true,
172174
build_environment_id: "abc123",
173175
source: null
174176
} satisfies GetProjectResponse)
@@ -432,6 +434,66 @@ class ObservableApiMock {
432434
);
433435
return this;
434436
}
437+
438+
handleGetRepository({status = 200}: {status?: number} = {}) {
439+
const response =
440+
status === 200
441+
? JSON.stringify({
442+
provider: "github",
443+
provider_id: "123:456",
444+
url: "https://github.com/observablehq/test.git",
445+
default_branch: "main",
446+
name: "test",
447+
linked_projects: []
448+
})
449+
: emptyErrorBody;
450+
const headers = authorizationHeader(status !== 401);
451+
this._handlers.push((pool) =>
452+
pool
453+
.intercept({path: "/cli/github/repository?owner=observablehq&repo=test", headers: headersMatcher(headers)})
454+
.reply(status, response, {headers: {"content-type": "application/json"}})
455+
);
456+
return this;
457+
}
458+
459+
handlePostProjectEnvironment({status = 200}: {status?: number} = {}) {
460+
const response =
461+
status === 200
462+
? JSON.stringify({
463+
automatic_builds_enabled: true,
464+
build_environment_id: "abc123",
465+
source: {
466+
provider: "github",
467+
provider_id: "123:456",
468+
url: "https://github.com/observablehq/test.git",
469+
branch: "main"
470+
}
471+
})
472+
: emptyErrorBody;
473+
const headers = authorizationHeader(status !== 401);
474+
this._handlers.push((pool) =>
475+
pool
476+
.intercept({path: "/cli/project/project123/environment", method: "POST", headers: headersMatcher(headers)})
477+
.reply(status, response, {headers: {"content-type": "application/json"}})
478+
);
479+
return this;
480+
}
481+
482+
handlePostProjectBuild({status = 200}: {status?: number} = {}) {
483+
const response =
484+
status === 200
485+
? JSON.stringify({
486+
id: "abc123"
487+
})
488+
: emptyErrorBody;
489+
const headers = authorizationHeader(status !== 401);
490+
this._handlers.push((pool) =>
491+
pool
492+
.intercept({path: "/cli/project/project123/build", method: "POST", headers: headersMatcher(headers)})
493+
.reply(status, response, {headers: {"content-type": "application/json"}})
494+
);
495+
return this;
496+
}
435497
}
436498

437499
function authorizationHeader(valid: boolean) {

0 commit comments

Comments
 (0)