-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat: Support multiple organizations API key. #68
Changes from 4 commits
7ca2170
85590ce
542b3d1
ff5fdee
ad0a7b3
b1adc4d
4c8a496
ca64d88
19cf61c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,11 +38,7 @@ function repositoriesEqual(rep1: string, rep2: string): boolean { | |
export async function getEnvironmentsForBranch() { | ||
let environments: EnvironmentModel[] = []; | ||
|
||
const organizationId = await getOrganizationId(); | ||
|
||
if (organizationId) { | ||
environments = await getEnvironments(organizationId); | ||
} | ||
environments = await getEnvironments(); | ||
|
||
if (environments.length > 0) { | ||
const { currentBranch, repository } = getGitRepoAndBranch(); | ||
|
@@ -64,17 +60,12 @@ export async function getEnvironmentsForBranch() { | |
return environments; | ||
} | ||
|
||
async function getEnvironments(organizationId: string) { | ||
async function getEnvironments() { | ||
try { | ||
return apiClient.getEnvironments(organizationId); | ||
return apiClient.getEnvironments(); | ||
} catch (e) { | ||
console.log(e); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where do console logs go in a vs code extension? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was just asking for general knowledge 👍🏻 |
||
} | ||
|
||
return []; | ||
} | ||
|
||
async function getOrganizationId() { | ||
const organizations = await apiClient.getOrganizations(); | ||
return organizations[0]?.id; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import * as jestMock from "jest-mock"; | ||
import * as vscode from "vscode"; | ||
|
||
let quickPickSpy: jestMock.SpyInstance<any>; | ||
export const spyOnQuickPick = () => { | ||
quickPickSpy = jestMock.spyOn(vscode.window, "showQuickPick"); | ||
return quickPickSpy; | ||
}; | ||
|
||
export const resetSpyOnQuickPick = () => { | ||
quickPickSpy?.mockReset?.(); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,9 +18,9 @@ import { | |
import * as jestMock from "jest-mock"; | ||
import * as vscode from "vscode"; | ||
import expect from "expect"; | ||
import { afterEach, beforeEach } from "mocha"; | ||
import { afterEach } from "mocha"; | ||
import { resetSpyOnQuickPick, spyOnQuickPick } from "../mocks/quick-pick"; | ||
|
||
const orgId = "org-id"; | ||
const envName = "my env"; | ||
const auth = { keyId: "key-id", secret: "key-secret" }; | ||
const environmentMock = getEnvironmentMock( | ||
|
@@ -30,25 +30,28 @@ const environmentMock = getEnvironmentMock( | |
name: envName, | ||
} | ||
); | ||
const selectedOrg = { name: "my org", id: "org-id" }; | ||
const initMocksAndLogin = async (moreOrgs: typeof selectedOrg[] = []) => { | ||
mockGetOrganization([selectedOrg, ...moreOrgs], auth); | ||
mockGetEnvironment(selectedOrg.id, [environmentMock], auth); | ||
mockGitRepoAndBranch("main", "[email protected]:user/repo.git"); | ||
mockGetDeploymentStepsApiResponse(); | ||
await login(auth); | ||
|
||
await waitFor(() => expect(getFirstEnvStatus()).toContain("ACTIVE")); | ||
}; | ||
|
||
suite("authentication", function () { | ||
this.timeout(1000 * 10); | ||
beforeEach(async () => { | ||
mockGetOrganization(orgId, auth); | ||
mockGetEnvironment(orgId, [environmentMock], auth); | ||
mockGitRepoAndBranch("main", "[email protected]:user/repo.git"); | ||
mockGetDeploymentStepsApiResponse(); | ||
|
||
await login(auth); | ||
await waitFor(() => expect(getFirstEnvStatus()).toContain("ACTIVE")); | ||
}); | ||
|
||
afterEach(async () => { | ||
await logout(); | ||
await resetExtension(); | ||
resetSpyOnQuickPick(); | ||
}); | ||
|
||
test("should call redeploy with the credentials provided on login", async () => { | ||
await initMocksAndLogin(); | ||
const onRedeployCalled = jestMock.fn(); | ||
mockRedeployApiResponse(environmentMock.id, auth, onRedeployCalled); | ||
|
||
|
@@ -57,13 +60,14 @@ suite("authentication", function () { | |
}); | ||
|
||
test("should call redeploy with updated credentials when logout and login again ", async () => { | ||
await initMocksAndLogin(); | ||
await logout(); | ||
const newAuthData = { | ||
keyId: "different-key-id", | ||
secret: "different-key-secret", | ||
}; | ||
mockGetOrganization(orgId, newAuthData); | ||
mockGetEnvironment(orgId, [environmentMock], newAuthData); | ||
mockGetOrganization([selectedOrg], newAuthData); | ||
mockGetEnvironment(selectedOrg.id, [environmentMock], newAuthData); | ||
|
||
await login(newAuthData); | ||
await waitFor(() => expect(getFirstEnvStatus()).toContain("ACTIVE")); | ||
|
@@ -75,11 +79,47 @@ suite("authentication", function () { | |
}); | ||
|
||
test("should show login message when logout", async () => { | ||
await initMocksAndLogin(); | ||
await logout(); | ||
await waitFor(() => | ||
expect(getEnvironmentsView().message).toContain( | ||
"you are logged out. in order to log in, run the command 'env0.login'" | ||
) | ||
); | ||
}); | ||
|
||
test("should show pick organization message when login", async () => { | ||
const onQuickPick = spyOnQuickPick(); | ||
|
||
const secondOrg = { name: "second org", id: "second-org-id" }; | ||
initMocksAndLogin([secondOrg]); | ||
await waitFor(() => | ||
expect(onQuickPick).toHaveBeenCalledWith( | ||
[selectedOrg, secondOrg].map((org) => ({ | ||
label: org.name, | ||
description: org.id, | ||
})), | ||
{ | ||
placeHolder: "Select an organization", | ||
} | ||
) | ||
); | ||
}); | ||
|
||
test("should show environments for the selected org", async () => { | ||
const secondOrg = { name: "second org", id: "second-org-id" }; | ||
const onQuickPick = spyOnQuickPick(); | ||
onQuickPick.mockImplementationOnce(() => | ||
Promise.resolve({ label: secondOrg.name, description: secondOrg.id }) | ||
); | ||
mockGetOrganization([selectedOrg, secondOrg], auth); | ||
mockGetEnvironment(secondOrg.id, [environmentMock], auth); | ||
mockGitRepoAndBranch("main", "[email protected]:user/repo.git"); | ||
mockGetDeploymentStepsApiResponse(); | ||
await login(auth); | ||
|
||
await waitFor(() => | ||
expect(getFirstEnvironment().name).toBe(environmentMock.name) | ||
); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,11 +41,12 @@ import { | |
} from "../mocks/notification-message"; | ||
|
||
const auth = { keyId: "key-id", secret: "key-secret" }; | ||
const orgId = "org-id"; | ||
const organization = { name: "my org", id: "org-id" }; | ||
const orgId = organization.id; | ||
|
||
const initTest = async (environments: EnvironmentModel[]) => { | ||
mockGetOrganization(orgId, auth); | ||
mockGetEnvironment(orgId, environments, auth); | ||
mockGetOrganization([organization], auth); | ||
mockGetEnvironment(organization.id, environments, auth); | ||
mockGitRepoAndBranch("main", "[email protected]:user/repo.git"); | ||
mockGetDeploymentStepsApiResponse(); | ||
spyOnShowMessage(); | ||
|
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.
why hold the this id in 2 different places, shouldn't there be a single source of truth? ( probably here and not in api client )
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.
I completely agree. I chose this approach because it aligns with our existing method of managing user credentials.
When I was creating the auth service, my intention was to pass an instance of it to the API client to avoid this very issue. However, I received this comment
4c8a496
also saved selected org id in store
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.
I think its up to you 👍🏻
this was the only important comment approving 👍🏻