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

[Storage] Add and delete a storage api key test #2240

Merged
merged 10 commits into from
Aug 16, 2022
8 changes: 7 additions & 1 deletion packages/storage-ui/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface Web3LoginOptions {
deleteFpsBuckets?: boolean
withNewSession?: boolean
createFpsBuckets?: { name: string; type: FileSystemType }[]
deleteApiKeys?: boolean
}

Cypress.Commands.add("clearPins", apiTestHelper.clearPins)
Expand All @@ -61,7 +62,8 @@ Cypress.Commands.add(
withNewUser = true,
deleteFpsBuckets = false,
withNewSession = false,
createFpsBuckets
createFpsBuckets,
deleteApiKeys = false
}: Web3LoginOptions = {}) => {

cy.on("window:before:load", (win) => {
Expand Down Expand Up @@ -117,6 +119,10 @@ Cypress.Commands.add(
apiTestHelper.createBucket(bucket.name, bucket.type)
})
}

if(deleteApiKeys) {
apiTestHelper.deleteApiKeys()
}
}
)

Expand Down
21 changes: 21 additions & 0 deletions packages/storage-ui/cypress/support/page-objects/apiKeysPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Only add things here that could be applicable to the api keys page

import { basePage } from "./basePage"

export const apiKeysPage = {
...basePage,

// main api keys elements
apiKeysHeaderLabel: () => cy.get("[data-cy=header-api-keys]", { timeout: 20000 }),
addApiKeyButton: () => cy.get("[data-cy=button-add-api-key]"),
addS3KeyButton: () => cy.get("[data-cy=button-add-s3-key]"),

// api keys table row elements
apiKeyIdCell: () => cy.get("[data-cy=cell-api-keys-id]"),
apiKeyTypeCell: () => cy.get("[data-cy=cell-api-keys-type]"),
apiKeyStatusCell: () => cy.get("[data-cy=cell-api-keys-status]"),
apiKeyRowKebabButton: () => cy.get("[data-testid=dropdown-title-api-keys-kebab]"),

// kebab menu elements
deleteMenuOption: () => cy.get("[data-cy=menu-delete]")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const newKeyModal = {
keyIdLabel: () => cy.get("[data-cy=label-new-key-modal-key-id]"),
secretLabel: () => cy.get("[data-cy=label-new-key-modal-secret]"),
closeButton: () => cy.get("[data-cy=button-new-key-modal-close]")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const navigationMenu = {
homeNavButton: () => cy.get("[data-cy=home-nav]"),
cidsNavButton: () => cy.get("[data-cy=cids-nav]"),
bucketsNavButton: () => cy.get("[data-cy=buckets-nav]"),
APIKeysNavButton: () => cy.get("[data-cy=api-keys-nav]"),
apiKeysNavButton: () => cy.get("[data-cy=api-keys-nav]"),
// settingsNavButton: () => cy.get("[data-cy=settings-nav]"),
// docsNavButton: () => cy.get("[data-cy=docs-nav]"),
spaceUsedLabel: () => cy.get("[data-cy=label-space-used]"),
Expand Down
19 changes: 19 additions & 0 deletions packages/storage-ui/cypress/support/utils/apiTestHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,24 @@ export const apiTestHelper = {
resolve()
})
})
},
deleteApiKeys() {
const apiClient = getApiClient()
return new Cypress.Promise(async (resolve) => {
cy.window()
.then(async (win) => {
const tokens = await apiClient.getRefreshToken({ refresh: win.localStorage.getItem(REFRESH_TOKEN_KEY) || "" })

await apiClient.setToken(tokens.access_token.token)
const keys = await apiClient.listAccessKeys()
cy.log(keys.length.toString())
keys.forEach(async (key) => {
cy.log(`Deleting api key: "${key.id}""`)
await apiClient.deleteAccessKey(key.id)
})
cy.log("Done deleting api keys.")
resolve()
})
})
}
}
39 changes: 39 additions & 0 deletions packages/storage-ui/cypress/tests/api-keys-management.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { navigationMenu } from "../support/page-objects/navigationMenu"
import { apiKeysPage } from "../support/page-objects/apiKeysPage"
import { newKeyModal } from "../support/page-objects/modals/newKeyModal"

describe("Main Navigation", () => {

context("desktop", () => {
beforeEach(() => {
cy.web3Login({ deleteApiKeys: true })
})

it("can add and delete a storage api key", () => {
// go to api keys section
navigationMenu.apiKeysNavButton().click()

// add new storage api key
apiKeysPage.addApiKeyButton().click()
newKeyModal.secretLabel().should("be.visible")
newKeyModal.keyIdLabel().invoke("text").as("keyId")
newKeyModal.closeButton().click()

// ensure new key modal is closed and api key button is not enabled
newKeyModal.secretLabel().should("not.exist")
apiKeysPage.addApiKeyButton().should("not.be.enabled")

// ensure key id and status are correct in the table
cy.get<string>("@keyId").then((keyId) => {
apiKeysPage.apiKeyIdCell().should("have.text", keyId)
})
apiKeysPage.apiKeyTypeCell().should("have.text", "storage")

// delete api key
apiKeysPage.apiKeyRowKebabButton().click()
apiKeysPage.deleteMenuOption().click()
apiKeysPage.apiKeyIdCell().should("not.exist")
})
})

})
31 changes: 16 additions & 15 deletions packages/storage-ui/cypress/tests/bucket-management.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,37 +147,38 @@ describe("Bucket management", () => {
// })

it("can sort by name or file system in buckets table", () => {
const chainSafeBucketName = `cs bucket ${Date.now()}`
const ipfsBucketName = `ipfs bucket ${Date.now()}`
const firstChainSafeBucketName = `first cs bucket ${Date.now()}`
const secondChainsafeBucketName = `second ipfs bucket ${Date.now()}`

cy.web3Login({ deleteFpsBuckets: true, createFpsBuckets:
[{ name: chainSafeBucketName, type: "chainsafe" }, { name: ipfsBucketName, type: "ipfs" }]
[{ name: firstChainSafeBucketName, type: "chainsafe" }, { name: secondChainsafeBucketName, type: "chainsafe" }]
})
navigationMenu.bucketsNavButton().click()

// by default should be sort by date uploading in ascending order (oldest first)
bucketsPage.bucketItemName().eq(0).should("have.text", chainSafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", ipfsBucketName)
bucketsPage.bucketItemName().eq(0).should("have.text", firstChainSafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", secondChainsafeBucketName)

// ensure that sort by name in descending order (Z-A)
bucketsPage.bucketsTableHeaderName().click()
bucketsPage.bucketItemName().eq(0).should("have.text", ipfsBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", chainSafeBucketName)
bucketsPage.bucketItemName().eq(0).should("have.text", secondChainsafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", firstChainSafeBucketName)

// ensure that sort by name in ascending order (A-Z)
bucketsPage.bucketsTableHeaderName().click()
bucketsPage.bucketItemName().eq(0).should("have.text", chainSafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", ipfsBucketName)
bucketsPage.bucketItemName().eq(0).should("have.text", firstChainSafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", secondChainsafeBucketName)

// commented because we can't create ipfs buckets right now
// ensure that sort by file system in descending order (Z-A)
bucketsPage.bucketsTableHeaderFileSystem().click()
bucketsPage.bucketItemName().eq(0).should("have.text", ipfsBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", chainSafeBucketName)
// bucketsPage.bucketsTableHeaderFileSystem().click()
// bucketsPage.bucketItemName().eq(0).should("have.text", ipfsBucketName)
// bucketsPage.bucketItemName().eq(1).should("have.text", chainSafeBucketName)

// ensure that sort by file system in ascending order (A-Z)
bucketsPage.bucketsTableHeaderFileSystem().click()
bucketsPage.bucketItemName().eq(0).should("have.text", chainSafeBucketName)
bucketsPage.bucketItemName().eq(1).should("have.text", ipfsBucketName)
// bucketsPage.bucketsTableHeaderFileSystem().click()
// bucketsPage.bucketItemName().eq(0).should("have.text", chainSafeBucketName)
// bucketsPage.bucketItemName().eq(1).should("have.text", ipfsBucketName)
})

// it("can rename a folder inside the ipfs bucket", () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/storage-ui/cypress/tests/main-navigation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe("Main Navigation", () => {
})

it("can navigate to the API keys page", () => {
navigationMenu.APIKeysNavButton().click()
navigationMenu.apiKeysNavButton().click()
cy.url().should("include", "/api-keys")
})

Expand Down Expand Up @@ -54,7 +54,7 @@ describe("Main Navigation", () => {
})

it("can navigate to the API keys page", () => {
navigationMenu.APIKeysNavButton().click()
navigationMenu.apiKeysNavButton().click()
cy.url().should("include", "/api-keys")
})

Expand Down
27 changes: 18 additions & 9 deletions packages/storage-ui/src/Components/Modules/ApiKeys.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ const ApiKeys = () => {
return (
<>
<div className={classes.root}>
<header className={classes.header}>
<header
className={classes.header}
data-cy="header-api-keys">
<Typography
variant="h1"
component="h1"
Expand All @@ -209,7 +211,7 @@ const ApiKeys = () => {
</Typography>
<div className={classes.controls}>
<Button
data-cy="add-s3-api-key-button"
data-cy="button-add-s3-key"
onClick={createS3AccessKey}
variant="outline"
size="large"
Expand All @@ -220,7 +222,7 @@ const ApiKeys = () => {
</span>
</Button>
<Button
data-cy="add-storage-api-key-button"
data-cy="button-add-api-key"
onClick={createStorageAccessKey}
variant="outline"
size="large"
Expand Down Expand Up @@ -278,22 +280,24 @@ const ApiKeys = () => {
key={k.id}
type='grid'
className={classes.tableRow}>
<TableCell align='left'>
<TableCell
align='left'
data-cy="cell-api-keys-id">
<Typography>
{k.id}
</Typography>
</TableCell>
<TableCell>
<TableCell data-cy="cell-api-keys-type">
<Typography>
{k.type}
</Typography>
</TableCell>
<TableCell>
<TableCell data-cy="cell-api-keys-status">
<Typography>
{k.status}
</Typography>
</TableCell>
<TableCell>
<TableCell data-cy="cell-api-keys-created-at">
<Typography>
{dayjs(k.created_at).format("DD MMM YYYY h:mm a")}
</Typography>
Expand All @@ -306,7 +310,7 @@ const ApiKeys = () => {
contents: (
<>
<DeleteSvg className={classes.menuIcon} />
<span data-cy="menu-share">
<span data-cy="menu-delete">
<Trans>Delete Key</Trans>
</span>
</>
Expand All @@ -319,6 +323,7 @@ const ApiKeys = () => {
item: classes.dropdownItem
}}
indicator={MoreIcon}
testId="api-keys-kebab"
/>
</TableCell>
</TableRow>)}
Expand All @@ -344,7 +349,9 @@ const ApiKeys = () => {
<Typography variant='h4'>
<Trans>Key ID</Trans>
</Typography>
<Typography className={classes.field}>{newKey?.id}</Typography>
<Typography
className={classes.field}
data-cy="label-new-key-modal-key-id">{newKey?.id}</Typography>
<Typography variant='h4'>
<Trans>Secret</Trans>
</Typography>
Expand All @@ -367,6 +374,7 @@ const ApiKeys = () => {
variant="body1"
component="p"
className={classes.secret}
data-cy="label-new-key-modal-secret"
>
{newKey?.secret}
</Typography>
Expand All @@ -379,6 +387,7 @@ const ApiKeys = () => {
setIsNewKeyModalOpen(false)
setNewKey(undefined)
}}
data-cy="button-new-key-modal-close"
>
Close
</Button>
Expand Down
2 changes: 1 addition & 1 deletion packages/storage-ui/src/Components/Pages/CidsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ const CidsPage = () => {
<div className={classes.root}>
<header
className={classes.header}
data-cy="header-cids"
data-cy="cids-header"
>
<Typography
variant="h1"
Expand Down