-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds testing for all commands except SSH.
- Loading branch information
Showing
18 changed files
with
366 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export const getAuth = jest.fn().mockReturnValue({}); | ||
|
||
export const signInWithCredential = jest.fn(); | ||
|
||
export const SignInMethod = { | ||
GOOGLE: "google.com", | ||
}; | ||
|
||
export class OAuthProvider { | ||
credential() { | ||
return "test-credential"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`login organization exists should write the user's identity to the file system 1`] = ` | ||
[ | ||
[ | ||
"/path/to/home/.p0", | ||
"{ | ||
"credential": { | ||
"access_token": "test-access-token", | ||
"id_token": "test-id-token", | ||
"token_type": "oidc", | ||
"scope": "oidc", | ||
"expires_in": 3600, | ||
"refresh_token": "test-refresh-token", | ||
"device_secret": "test-device-secret", | ||
"expires_at": 1600003599 | ||
}, | ||
"org": { | ||
"slug": "test-org", | ||
"tenantId": "test-tenant", | ||
"ssoProvider": "google" | ||
} | ||
}", | ||
{ | ||
"mode": "600", | ||
}, | ||
], | ||
] | ||
`; | ||
|
||
exports[`login organization exists validates authentication 1`] = ` | ||
[ | ||
[ | ||
{ | ||
"tenantId": "test-tenant", | ||
}, | ||
"test-credential", | ||
], | ||
] | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { pluginLoginMap } from "../../plugins/login"; | ||
import { mockGetDoc } from "../../testing/firestore"; | ||
import { login } from "../login"; | ||
import { signInWithCredential } from "firebase/auth"; | ||
import { readFile, writeFile } from "fs/promises"; | ||
|
||
jest.spyOn(Date, "now").mockReturnValue(1.6e12); | ||
jest.mock("fs/promises"); | ||
jest.mock("../../drivers/auth", () => ({ | ||
...jest.requireActual("../../drivers/auth"), | ||
IDENTITY_FILE_PATH: "/path/to/home/.p0", | ||
})); | ||
jest.mock("../../drivers/stdio"); | ||
jest.mock("../../plugins/login"); | ||
|
||
const mockReadFile = readFile as jest.Mock; | ||
const mockWriteFile = writeFile as jest.Mock; | ||
|
||
describe("login", () => { | ||
it("prints a friendly error if the org is not found", async () => { | ||
mockGetDoc(undefined); | ||
await expect(login({ org: "test-org" })).rejects.toMatchInlineSnapshot( | ||
`"Could not find organization"` | ||
); | ||
}); | ||
it("should print a friendly error if unsupported login", async () => { | ||
mockGetDoc({ | ||
slug: "test-org", | ||
tenantId: "test-tenant", | ||
ssoProvider: "microsoft", | ||
}); | ||
await expect(login({ org: "test-org" })).rejects.toMatchInlineSnapshot( | ||
`"Unsupported login for your organization"` | ||
); | ||
}); | ||
describe("organization exists", () => { | ||
let credentialData: string = ""; | ||
mockReadFile.mockImplementation(async () => | ||
Buffer.from(credentialData, "utf-8") | ||
); | ||
mockWriteFile.mockImplementation(async (_path, data) => { | ||
credentialData = data; | ||
}); | ||
beforeEach(() => { | ||
credentialData = ""; | ||
jest.clearAllMocks(); | ||
mockGetDoc({ | ||
slug: "test-org", | ||
tenantId: "test-tenant", | ||
ssoProvider: "google", | ||
}); | ||
}); | ||
it("should call the provider's login function", async () => { | ||
await login({ org: "test-org" }); | ||
expect(pluginLoginMap.google).toHaveBeenCalled(); | ||
}); | ||
it("should write the user's identity to the file system", async () => { | ||
await login({ org: "test-org" }); | ||
expect(mockWriteFile.mock.calls).toMatchSnapshot(); | ||
}); | ||
it("validates authentication", async () => { | ||
await login({ org: "test-org" }); | ||
expect((signInWithCredential as jest.Mock).mock.calls).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const samlResponse = `<html> | ||
<body> | ||
<input name="SAMLResponse" type="hidden" value="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KIDxzYW1sMnA6UmVzcG9uc2UgeG1sbnM6c2FtbDJwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgRGVzdGluYXRpb249Imh0dHBzOi8vc2lnbmluLmF3cy5hbWF6b24uY29tL3NhbWwiIElEPSJhYmMiIElzc3VlSW5zdGFudD0iMjAyNC0wMS0wMVQwMDowMDowMC4wMDBaIiBWZXJzaW9uPSIyLjAiPgogIDxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwOi8vd3d3Lm9rdGEuY29tL2FiY2RlZjwvc2FtbDI6SXNzdWVyPgogIDxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogICAgPGRzOlNpZ25lZEluZm8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8+CiAgICAgIDxkczpSZWZlcmVuY2UgVVJJPSIjYWJjIj4KICAgICAgICA8ZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPgogICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyI+CiAgICAgICAgICAgIDxlYzpJbmNsdXNpdmVOYW1lc3BhY2VzIHhtbG5zOmVjPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiIFByZWZpeExpc3Q9InhzIi8+CiAgICAgICAgICA8L2RzOlRyYW5zZm9ybT4KICAgICAgICA8L2RzOlRyYW5zZm9ybXM+CiAgICAgICAgPGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPgogICAgICAgIDxkczpEaWdlc3RWYWx1ZT5kaWdlc3Q8L2RzOkRpZ2VzdFZhbHVlPgogICAgICA8L2RzOlJlZmVyZW5jZT4KICAgIDwvZHM6U2lnbmVkSW5mbz4KICAgIDxkczpTaWduYXR1cmVWYWx1ZT5zaWduYXR1cmU8L2RzOlNpZ25hdHVyZVZhbHVlPgogICAgPGRzOktleUluZm8+CiAgICAgIDxkczpYNTA5RGF0YT4KICAgICAgICA8ZHM6WDUwOUNlcnRpZmljYXRlPmNlcnRpZmljYXRlPC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgIDwvZHM6WDUwOURhdGE+CiAgICA8L2RzOktleUluZm8+CiAgPC9kczpTaWduYXR1cmU+CiAgPHNhbWwycDpTdGF0dXMgeG1sbnM6c2FtbDJwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPgogICAgPHNhbWwycDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz4KICA8L3NhbWwycDpTdGF0dXM+CiAgPHNhbWwyOkFzc2VydGlvbiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiBJRD0iYWJjIiBJc3N1ZUluc3RhbnQ9IjIwMjQtMDEtMDFUMDA6MDA6MDAuMDAwWiIgVmVyc2lvbj0iMi4wIj4KICAgIDxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwOi8vd3d3Lm9rdGEuY29tL2FiY2RlZjwvc2FtbDI6SXNzdWVyPgogICAgPGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+CiAgICAgIDxkczpTaWduZWRJbmZvPgogICAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz4KICAgICAgICA8ZHM6UmVmZXJlbmNlIFVSST0iI2lkODQ3NzcyOTk3NzUzMjMwMTkyNzA4ODcwOCI+CiAgICAgICAgICA8ZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+CiAgICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiPgogICAgICAgICAgICAgIDxlYzpJbmNsdXNpdmVOYW1lc3BhY2VzIHhtbG5zOmVjPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiIFByZWZpeExpc3Q9InhzIi8+CiAgICAgICAgICAgIDwvZHM6VHJhbnNmb3JtPgogICAgICAgICAgPC9kczpUcmFuc2Zvcm1zPgogICAgICAgICAgPGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPgogICAgICAgICAgPGRzOkRpZ2VzdFZhbHVlPmRpZ2VzdDwvZHM6RGlnZXN0VmFsdWU+CiAgICAgICAgPC9kczpSZWZlcmVuY2U+CiAgICAgIDwvZHM6U2lnbmVkSW5mbz4KICAgICAgPGRzOlNpZ25hdHVyZVZhbHVlPnNpZ25hdHVyZTwvZHM6U2lnbmF0dXJlVmFsdWU+CiAgICAgIDxkczpLZXlJbmZvPgogICAgICAgIDxkczpYNTA5RGF0YT4KICAgICAgICAgIDxkczpYNTA5Q2VydGlmaWNhdGU+Y2VydGlmaWNhdGU8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4KICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICA8L2RzOktleUluZm8+CiAgICA8L2RzOlNpZ25hdHVyZT4KICAgIDxzYW1sMjpTdWJqZWN0IHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj4KICAgICAgPHNhbWwyOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj50ZXN0LXVzZXJAdGVzdC5jb208L3NhbWwyOk5hbWVJRD4KICAgICAgPHNhbWwyOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4KICAgICAgICA8c2FtbDI6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDI0LTAxLTAxVDAwOjAwOjAwLjAwMFoiIFJlY2lwaWVudD0iaHR0cHM6Ly9zaWduaW4uYXdzLmFtYXpvbi5jb20vc2FtbCIvPgogICAgICA8L3NhbWwyOlN1YmplY3RDb25maXJtYXRpb24+CiAgICA8L3NhbWwyOlN1YmplY3Q+CiAgICA8c2FtbDI6Q29uZGl0aW9ucyB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgTm90QmVmb3JlPSIyMDI0LTAxLTAxVDAwOjAwOjAwLjAwMFoiIE5vdE9uT3JBZnRlcj0iMjAyNC0wMS0wMVQwMDowMDowMC4wMDBaIj4KICAgICAgPHNhbWwyOkF1ZGllbmNlUmVzdHJpY3Rpb24+CiAgICAgICAgPHNhbWwyOkF1ZGllbmNlPnVybjphbWF6b246d2Vic2VydmljZXM8L3NhbWwyOkF1ZGllbmNlPgogICAgICA8L3NhbWwyOkF1ZGllbmNlUmVzdHJpY3Rpb24+CiAgICA8L3NhbWwyOkNvbmRpdGlvbnM+CiAgICA8c2FtbDI6QXV0aG5TdGF0ZW1lbnQgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIEF1dGhuSW5zdGFudD0iMjAyNC0wMS0wMVQwMDowMDowMC4wMDBaIiBTZXNzaW9uSW5kZXg9ImFiYyI+CiAgICAgIDxzYW1sMjpBdXRobkNvbnRleHQ+CiAgICAgICAgPHNhbWwyOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0PC9zYW1sMjpBdXRobkNvbnRleHRDbGFzc1JlZj4KICAgICAgPC9zYW1sMjpBdXRobkNvbnRleHQ+CiAgICA8L3NhbWwyOkF1dGhuU3RhdGVtZW50PgogICAgPHNhbWwyOkF0dHJpYnV0ZVN0YXRlbWVudCB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+CiAgICAgIDxzYW1sMjpBdHRyaWJ1dGUgTmFtZT0iaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9TQU1ML0F0dHJpYnV0ZXMvUm9sZSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1cmkiPgogICAgICAgIDxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmFybjphd3M6aWFtOjoxOnNhbWwtcHJvdmlkZXIvdGVzdF9va3RhLGFybjphd3M6aWFtOjoxOnJvbGUvUm9sZTE8L3NhbWwyOkF0dHJpYnV0ZVZhbHVlPgogICAgICAgIDxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmFybjphd3M6aWFtOjoxOnNhbWwtcHJvdmlkZXIvdGVzdF9va3RhLGFybjphd3M6aWFtOjoxOnJvbGUvUm9sZTI8L3NhbWwyOkF0dHJpYnV0ZVZhbHVlPgogICAgICA8L3NhbWwyOkF0dHJpYnV0ZT4KICAgICAgPHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJodHRwczovL2F3cy5hbWF6b24uY29tL1NBTUwvQXR0cmlidXRlcy9Sb2xlU2Vzc2lvbk5hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPgogICAgICAgIDxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnRlc3QtdXNlckB0ZXN0LmNvbTwvc2FtbDI6QXR0cmlidXRlVmFsdWU+CiAgICAgIDwvc2FtbDI6QXR0cmlidXRlPgogICAgICA8c2FtbDI6QXR0cmlidXRlIE5hbWU9Imh0dHBzOi8vYXdzLmFtYXpvbi5jb20vU0FNTC9BdHRyaWJ1dGVzL1Nlc3Npb25EdXJhdGlvbiIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+CiAgICAgICAgPHNhbWwyOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI+MzYwMDwvc2FtbDI6QXR0cmlidXRlVmFsdWU+CiAgICAgIDwvc2FtbDI6QXR0cmlidXRlPgogICAgICA8c2FtbDI6QXR0cmlidXRlIE5hbWU9Imh0dHBzOi8vYXdzLmFtYXpvbi5jb20vU0FNTC9BdHRyaWJ1dGVzL1ByaW5jaXBhbFRhZzpvcmciIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPgogICAgICAgIDxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnRlc3Q8L3NhbWwyOkF0dHJpYnV0ZVZhbHVlPgogICAgICA8L3NhbWwyOkF0dHJpYnV0ZT4KICAgICAgPHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJodHRwczovL2F3cy5hbWF6b24uY29tL1NBTUwvQXR0cmlidXRlcy9Tb3VyY2VJZGVudGl0eSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1cmkiPgogICAgICAgIDxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnRlc3QtdXNlckB0ZXN0LmNvbTwvc2FtbDI6QXR0cmlidXRlVmFsdWU+CiAgICAgIDwvc2FtbDI6QXR0cmlidXRlPgogICAgPC9zYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ+CiAgPC9zYW1sMjpBc3NlcnRpb24+Cjwvc2FtbDJwOlJlc3BvbnNlPg==" /> | ||
</body> | ||
</html>`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
export const stsResponse = `<AssumeRoleWithSAMLResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/"> | ||
<AssumeRoleWithSAMLResult> | ||
<Audience>https://signin.aws.amazon.com/saml</Audience> | ||
<AssumedRoleUser> | ||
<AssumedRoleId>ABCDEFGHIJLMNOPQRST:test-user@test.com</AssumedRoleId> | ||
<Arn>arn:aws:sts::1:assumed-role/Role1/test-user@test.com</Arn> | ||
</AssumedRoleUser> | ||
<Credentials> | ||
<AccessKeyId>test-access-key</AccessKeyId> | ||
<SecretAccessKey>secret-access-key</SecretAccessKey> | ||
<SessionToken>session-token</SessionToken> | ||
<Expiration>2024-02-22T00:18:21Z</Expiration> | ||
</Credentials> | ||
<Subject>test-user@test.com</Subject> | ||
<NameQualifier>abcdefghijklmnop</NameQualifier> | ||
<SourceIdentity>test-user@test.com</SourceIdentity> | ||
<PackedPolicySize>2</PackedPolicySize> | ||
<SubjectType>unspecified</SubjectType> | ||
<Issuer>http://www.okta.com/abc</Issuer> | ||
</AssumeRoleWithSAMLResult> | ||
<ResponseMetadata> | ||
<RequestId>f5b94ad4-f322-4d7b-b568-84f2ec184cd7</RequestId> | ||
</ResponseMetadata> | ||
</AssumeRoleWithSAMLResponse>`; |
44 changes: 44 additions & 0 deletions
44
src/commands/aws/__tests__/__snapshots__/role.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`aws role a single installed account with Okta SAML assume should assume a role 1`] = ` | ||
[ | ||
[ | ||
"Execute the following commands: | ||
", | ||
], | ||
[ | ||
" | ||
Or, populate these environment variables using BASH command substitution: | ||
$(p0 aws role assume undefined) | ||
", | ||
], | ||
] | ||
`; | ||
|
||
exports[`aws role a single installed account with Okta SAML assume should assume a role 2`] = ` | ||
[ | ||
[ | ||
" export AWS_ACCESS_KEY_ID=test-access-key | ||
export AWS_SECRET_ACCESS_KEY=secret-access-key | ||
export AWS_SESSION_TOKEN=session-token", | ||
], | ||
] | ||
`; | ||
|
||
exports[`aws role a single installed account with Okta SAML ls lists roles 1`] = ` | ||
[ | ||
[ | ||
"Your available roles for account 1:", | ||
], | ||
] | ||
`; | ||
|
||
exports[`aws role a single installed account with Okta SAML ls lists roles 2`] = ` | ||
[ | ||
[ | ||
" Role1 | ||
Role2", | ||
], | ||
] | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { awsCommand } from ".."; | ||
import { print1, print2 } from "../../../drivers/stdio"; | ||
import { mockGetDoc } from "../../../testing/firestore"; | ||
import { failure } from "../../../testing/yargs"; | ||
import { samlResponse } from "./__input__/saml-response"; | ||
import { stsResponse } from "./__input__/sts-response"; | ||
import yargs from "yargs"; | ||
|
||
jest.mock("fs/promises"); | ||
jest.mock("../../../drivers/auth"); | ||
jest.mock("../../../drivers/stdio"); | ||
jest.mock("typescript", () => ({ | ||
...jest.requireActual("typescript"), | ||
sys: { | ||
writeOutputIsTTY: () => true, | ||
}, | ||
})); | ||
|
||
const mockFetch = jest.spyOn(global, "fetch"); | ||
const mockPrint1 = print1 as jest.Mock; | ||
const mockPrint2 = print2 as jest.Mock; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
mockFetch.mockImplementation( | ||
async (url: RequestInfo | URL) => | ||
({ | ||
ok: true, | ||
// This is the token response from fetchSsoWebToken | ||
json: async () => ({}), | ||
// This is the XML response from fetchSamlResponse or stsAssumeRole | ||
text: async () => | ||
(url as string).match(/okta.com/) ? samlResponse : stsResponse, | ||
}) as Response | ||
); | ||
}); | ||
|
||
describe("aws role", () => { | ||
describe("a single installed account", () => { | ||
const item = { | ||
account: { | ||
id: "1", | ||
description: "1 (test)", | ||
}, | ||
state: "installed", | ||
}; | ||
describe("without Okta SAML", () => { | ||
mockGetDoc({ workflows: { items: [item] } }); | ||
describe.each([ | ||
["ls", "aws role ls"], | ||
["assume", "aws role assume Role1"], | ||
])("%s", (_, command) => { | ||
it("should print a friendly error message", async () => { | ||
const error = await failure(awsCommand(yargs), command); | ||
expect(error).toMatchInlineSnapshot( | ||
`"Account 1 (test) is not configured for Okta SAML login."` | ||
); | ||
}); | ||
}); | ||
}); | ||
describe("with Okta SAML", () => { | ||
beforeEach(() => { | ||
mockGetDoc({ | ||
workflows: { | ||
items: [{ ...item, uidLocation: { id: "okta_saml_sso" } }], | ||
}, | ||
}); | ||
}); | ||
describe("assume", () => { | ||
it("should assume a role", async () => { | ||
await awsCommand(yargs).parse("aws role assume Role1"); | ||
expect(mockPrint2.mock.calls).toMatchSnapshot(); | ||
expect(mockPrint1.mock.calls).toMatchSnapshot(); | ||
}); | ||
}); | ||
describe("ls", () => { | ||
const command = "aws role ls"; | ||
it("lists roles", async () => { | ||
await awsCommand(yargs).parse(command); | ||
expect(mockPrint2.mock.calls).toMatchSnapshot(); | ||
expect(mockPrint1.mock.calls).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.