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

Fix context missing for test cases #19521

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 15 additions & 3 deletions components/server/src/auth/auth-provider-service.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Experiments } from "@gitpod/gitpod-protocol/lib/experiments/configcat-s
import * as chai from "chai";
import { Container } from "inversify";
import "mocha";
import { createTestContainer, withTestCtx } from "../test/service-testing-container-module";
import { createTestContainer, withTestCtx, withTestCtxProxy } from "../test/service-testing-container-module";
import { resetDB } from "@gitpod/gitpod-db/lib/test/reset-db";
import { UserService } from "../user/user-service";
import { AuthProviderService } from "./auth-provider-service";
Expand Down Expand Up @@ -113,7 +113,16 @@ describe("AuthProviderService", async () => {
Experiments.configureTestingClient({
centralizedPermissions: true,
});
service = container.get(AuthProviderService);
const realService = container.get(AuthProviderService);
service = withTestCtxProxy(realService, {
0: [
"createOrgAuthProvider",
"getAuthProvider",
"createAuthProviderOfUser",
"updateOrgAuthProvider",
"updateAuthProviderOfUser",
],
});
userService = container.get<UserService>(UserService);
currentUser = await userService.createUser({
identity: {
Expand All @@ -122,7 +131,10 @@ describe("AuthProviderService", async () => {
authProviderId: "public-github",
},
});
orgService = container.get<OrganizationService>(OrganizationService);
const realOrgService = container.get<OrganizationService>(OrganizationService);
orgService = withTestCtxProxy(realOrgService, {
0: ["getOrCreateInvite"],
});
org = await orgService.createOrganization(currentUser.id, "myorg");
});

Expand Down
14 changes: 8 additions & 6 deletions components/server/src/auth/bearer-authenticator.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,18 @@ describe("BearerAuth", () => {
authorization: `Bearer `, // missing
},
} as Request;
await expectError(async () => bearerAuth.authExpressRequest(req), "missing bearer token header");
await expectError(async () => bearerAuth.authExpressRequest(req), "missing Bearer token");
});

it("authExpressRequest should fail to authenticate with missing BearerToken from DB (PAT)", async () => {
const patNotStored = "gitpod_pat_GrvGthczSRf3ypqFhNtcRiN5fK6CV7rdCkkPLfpbc_4";
const patNotStored = "gitpod_pat_GrvGthczSRf3ypqFhNtcRiN5fK6CV7rdCkkPLfpbc_4.value";

const req = {
headers: {
authorization: `Bearer ${patNotStored}`,
},
} as Request;
await expectError(async () => bearerAuth.authExpressRequest(req), "cannot find token");
await expectError(async () => bearerAuth.authExpressRequest(req), "Invalid personal access token");
});

it("tryAuthFromHeaders should successfully authenticate BearerToken (PAT)", async () => {
Expand All @@ -132,17 +132,19 @@ describe("BearerAuth", () => {
});

it("tryAuthFromHeaders should fail to authenticate with missing BearerToken from DB (PAT)", async () => {
const patNotStored = "gitpod_pat_GrvGthczSRf3ypqFhNtcRiN5fK6CV7rdCkkPLfpbc_4";
const patNotStored = "gitpod_pat_GrvGthczSRf3ypqFhNtcRiN5fK6CV7rdCkkPLfpbc_4.value";

const headers = new Headers();
headers.set("authorization", `Bearer ${patNotStored}`);
await expectError(async () => bearerAuth.tryAuthFromHeaders(headers), "cannot find token");
await expectError(async () => bearerAuth.tryAuthFromHeaders(headers), "Invalid personal access token");
});

async function expectError(fun: () => Promise<any>, message: string) {
try {
await fun();
fail(`Expected error: ${message}`);
} catch (err) {}
} catch (err) {
expect(err.message).to.include(message);
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ describe("CachingSpiceDBAuthorizer", async () => {
const ws1 = await withTestCtx(userA, () => createTestWorkspace(org1, userA));

expect(
await withTestCtx(SYSTEM_USER, () => authorizer.hasPermissionOnWorkspace(userA.id, "read_info", ws1.id)),
await withTestCtx(userA, () => authorizer.hasPermissionOnWorkspace(userA.id, "read_info", ws1.id)),
"userA should have read_info after removal of userB",
).to.be.true;
expect(
Expand Down
18 changes: 16 additions & 2 deletions components/server/src/orgs/organization-service.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
import * as chai from "chai";
import { Container } from "inversify";
import "mocha";
import { createTestContainer, withTestCtx } from "../test/service-testing-container-module";
import { createTestContainer, withTestCtx, withTestCtxProxy } from "../test/service-testing-container-module";
import { OrganizationService } from "./organization-service";
import { resetDB } from "@gitpod/gitpod-db/lib/test/reset-db";
import { expectError } from "../test/expect-utils";
Expand Down Expand Up @@ -48,7 +48,21 @@ describe("OrganizationService", async () => {
await validateDefaultWorkspaceImage(userId, imageRef);
}
});
os = container.get(OrganizationService);
const realOs = container.get(OrganizationService);
os = withTestCtxProxy(realOs, {
0: [
"getSettings",
"updateSettings",
"listMembers",
"getOrganization",
"addOrUpdateMember",
"getOrCreateInvite",
"listOrganizations",
"removeOrganizationMember",
"resetInvite",
"deleteOrganization",
],
});
userService = container.get<UserService>(UserService);
owner = await userService.createUser({
identity: {
Expand Down
5 changes: 4 additions & 1 deletion components/server/src/orgs/organization-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { InstallationService } from "../auth/installation-service";
import { getExperimentsClientForBackend } from "@gitpod/gitpod-protocol/lib/experiments/configcat-server";
import { runWithSubjectId } from "../util/request-context";
import { IDEService } from "../ide-service";
import { SubjectId } from "../auth/subject-id";

@injectable()
export class OrganizationService {
Expand Down Expand Up @@ -319,7 +320,9 @@ export class OrganizationService {
// we can remove the built-in installation admin if we have added an owner
if (!hasOtherRegularOwners && members.some((m) => m.userId === BUILTIN_INSTLLATION_ADMIN_USER_ID)) {
try {
await this.removeOrganizationMember(memberId, orgId, BUILTIN_INSTLLATION_ADMIN_USER_ID, txCtx);
await runWithSubjectId(SubjectId.fromUserId(memberId), () =>
this.removeOrganizationMember(memberId, orgId, BUILTIN_INSTLLATION_ADMIN_USER_ID, txCtx),
);
} catch (error) {
log.warn("Failed to remove built-in installation admin from organization.", error);
}
Expand Down
33 changes: 24 additions & 9 deletions components/server/src/orgs/usage-service.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import * as chai from "chai";
import { Container } from "inversify";
import "mocha";
import { Mock } from "../test/mocks/mock";
import { createTestContainer, withTestCtx } from "../test/service-testing-container-module";
import { createTestContainer, withTestCtx, withTestCtxProxy } from "../test/service-testing-container-module";
import { OrganizationService } from "./organization-service";
import { UsageService } from "./usage-service";
import { resetDB } from "@gitpod/gitpod-db/lib/test/reset-db";
Expand All @@ -47,7 +47,10 @@ describe("UsageService", async () => {
Experiments.configureTestingClient({
centralizedPermissions: true,
});
os = container.get(OrganizationService);
const realOs = container.get(OrganizationService);
os = withTestCtxProxy(realOs, {
0: ["getOrCreateInvite", "joinOrganization", "createOrganization"],
});
const userService = container.get<UserService>(UserService);
owner = await userService.createUser({
identity: {
Expand Down Expand Up @@ -83,14 +86,26 @@ describe("UsageService", async () => {
authId: "1234",
},
});
await userService.updateRoleOrPermission(BUILTIN_INSTLLATION_ADMIN_USER_ID, admin.id, [
{
role: "admin",
add: true,
},
]);
await withTestCtx(BUILTIN_INSTLLATION_ADMIN_USER_ID, () =>
userService.updateRoleOrPermission(BUILTIN_INSTLLATION_ADMIN_USER_ID, admin.id, [
{
role: "admin",
add: true,
},
]),
);

us = container.get<UsageService>(UsageService);
const realUs = container.get<UsageService>(UsageService);
us = withTestCtxProxy(realUs, {
0: [
"getCostCenter",
"setUsageLimit",
"listUsage",
"getCurrentBalance",
"addCreditNote",
"checkUsageLimitReached",
],
});
await us.getCostCenter(owner.id, org.id);
usageServiceMock = container.get(UsageServiceDefinition.name);
});
Expand Down
38 changes: 22 additions & 16 deletions components/server/src/projects/projects-service.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Container } from "inversify";
import "mocha";
import { OrganizationService } from "../orgs/organization-service";
import { expectError } from "../test/expect-utils";
import { createTestContainer, withTestCtx } from "../test/service-testing-container-module";
import { createTestContainer, withTestCtx, withTestCtxProxy } from "../test/service-testing-container-module";
import { OldProjectSettings, ProjectsService } from "./projects-service";
import { daysBefore } from "@gitpod/gitpod-protocol/lib/util/timeutil";
import { SYSTEM_USER } from "../authorization/authorizer";
Expand All @@ -28,6 +28,7 @@ describe("ProjectsService", async () => {
let stranger: User;
let org: Organization;
let anotherOrg: Organization;
let ps: ProjectsService;

beforeEach(async () => {
container = createTestContainer();
Expand All @@ -41,17 +42,33 @@ describe("ProjectsService", async () => {

// create the org
const orgService = container.get(OrganizationService);
org = await orgService.createOrganization(owner.id, "my-org");
anotherOrg = await orgService.createOrganization(owner.id, "another-org");

org = await withTestCtx(owner.id, () => orgService.createOrganization(owner.id, "my-org"));

anotherOrg = await withTestCtx(owner.id, () => orgService.createOrganization(owner.id, "another-org"));

// create and add a member
member = await userDB.newUser();
const invite = await orgService.getOrCreateInvite(owner.id, org.id);
const invite = await withTestCtx(owner.id, () => orgService.getOrCreateInvite(owner.id, org.id));
await withTestCtx(SYSTEM_USER, () => orgService.joinOrganization(member.id, invite.id));

const anotherInvite = await orgService.getOrCreateInvite(owner.id, anotherOrg.id);
const anotherInvite = await withTestCtx(owner.id, () => orgService.getOrCreateInvite(owner.id, anotherOrg.id));
await withTestCtx(SYSTEM_USER, () => orgService.joinOrganization(member.id, anotherInvite.id));

const realPs = container.get(ProjectsService);
ps = withTestCtxProxy(realPs, {
0: [
"getProject",
"getProjects",
"deleteProject",
"updateProject",
"findProjects",
"findProjectsByCloneUrl",
"setVisibility",
],
1: ["createProject"],
});

// create a stranger
stranger = await userDB.newUser();
});
Expand All @@ -64,7 +81,6 @@ describe("ProjectsService", async () => {
});

it("should getProject and getProjects", async () => {
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner);

let foundProject = await ps.getProject(owner.id, project.id);
Expand All @@ -84,7 +100,6 @@ describe("ProjectsService", async () => {
});

it("should setVisibility", async () => {
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner);

await expectError(ErrorCodes.NOT_FOUND, () => ps.getProject(stranger.id, project.id));
Expand All @@ -98,7 +113,6 @@ describe("ProjectsService", async () => {
});

it("should deleteProject", async () => {
const ps = container.get(ProjectsService);
const project1 = await createTestProject(ps, org, owner);

await ps.deleteProject(member.id, project1.id);
Expand All @@ -114,7 +128,6 @@ describe("ProjectsService", async () => {
});

it("should updateProject", async () => {
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner);

await ps.updateProject(owner, {
Expand Down Expand Up @@ -173,7 +186,6 @@ describe("ProjectsService", async () => {
it("should install webhook on new projects", async () => {
const webhooks = container.get<Set<String>>("webhooks");
webhooks.clear();
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner); // using new default settings
await ps.updateProject(owner, {
id: project.id,
Expand All @@ -188,7 +200,6 @@ describe("ProjectsService", async () => {
const webhooks = container.get<Set<String>>("webhooks");
webhooks.clear();
const cloneUrl = "https://github.com/gitpod-io/gitpod.git";
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner, {
name: "test-pro",
cloneUrl,
Expand All @@ -205,7 +216,6 @@ describe("ProjectsService", async () => {
});

it("should findProjects", async () => {
const ps = container.get(ProjectsService);
const project = await createTestProject(ps, org, owner);
await createTestProject(ps, org, owner, { name: "my-project-2", cloneUrl: "https://host/account/repo.git" });
await createTestProject(ps, org, member, { name: "my-project-3", cloneUrl: "https://host/account/repo.git" });
Expand All @@ -226,7 +236,6 @@ describe("ProjectsService", async () => {
});

it("prebuild settings migration / old and inactive project / uses defaults", async () => {
const ps = container.get(ProjectsService);
const cloneUrl = "https://github.com/gitpod-io/gitpod.git";
const oldProject = await createTestProject(ps, org, owner, {
name: "my-project",
Expand All @@ -251,7 +260,6 @@ describe("ProjectsService", async () => {
});

it("prebuild settings migration / inactive project / uses defaults", async () => {
const ps = container.get(ProjectsService);
const cloneUrl = "https://github.com/gitpod-io/gitpod.git";
const oldProject = await createTestProject(ps, org, owner, {
name: "my-project",
Expand All @@ -276,7 +284,6 @@ describe("ProjectsService", async () => {
});

it("prebuild settings migration / new and active project / updated settings", async () => {
const ps = container.get(ProjectsService);
const cloneUrl = "https://github.com/gitpod-io/gitpod.git";
const oldProject = await createTestProject(ps, org, owner, {
name: "my-project",
Expand Down Expand Up @@ -305,7 +312,6 @@ describe("ProjectsService", async () => {
});

it("should find projects by clone url", async () => {
const ps = container.get(ProjectsService);
const cloneUrl = "https://github.com/gitpod-io/gitpod.git";

await createTestProject(ps, org, owner, { name: "my-project", cloneUrl });
Expand Down
7 changes: 5 additions & 2 deletions components/server/src/scm/scm-service.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Experiments } from "@gitpod/gitpod-protocol/lib/experiments/configcat-s
import * as chai from "chai";
import { Container } from "inversify";
import "mocha";
import { createTestContainer } from "../test/service-testing-container-module";
import { createTestContainer, withTestCtxProxy } from "../test/service-testing-container-module";
import { resetDB } from "@gitpod/gitpod-db/lib/test/reset-db";
import { UserService } from "../user/user-service";
import { Config } from "../config";
Expand Down Expand Up @@ -43,7 +43,10 @@ describe("ScmService", async () => {
Experiments.configureTestingClient({
centralizedPermissions: true,
});
service = container.get(ScmService);
const realService = container.get(ScmService);
service = withTestCtxProxy(realService, {
0: ["getToken"],
});
userService = container.get<UserService>(UserService);
currentUser = await userService.createUser({
identity: {
Expand Down
23 changes: 23 additions & 0 deletions components/server/src/test/service-testing-container-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,26 @@ export function withTestCtx<T>(subject: Subject | User, p: () => Promise<T>): Pr
p,
);
}

export function withTestCtxProxy<T extends object>(
realTarget: T,
subjectLocation: { [location: number]: (keyof T)[] },
) {
const locationMap = new Map<keyof T, number>();
for (const location in subjectLocation) {
for (const name of subjectLocation[location]) {
locationMap.set(name, parseInt(location));
}
}
return new Proxy(realTarget, {
get: (target, prop) => {
const has = locationMap.has(prop as keyof T);
if (!has) {
return realTarget[prop as keyof T];
}
const location = locationMap.get(prop as keyof T)!;
return (...args: any) =>
withTestCtx(args[location] as string, () => (realTarget[prop as keyof T] as any)(...args));
},
});
}
Loading
Loading