Skip to content

Commit

Permalink
[Storage] Add and delete a storage api key test (#2240)
Browse files Browse the repository at this point in the history
* add and delete a storage api key test

* fix navigate to api keys page in mobile context

* Update packages/storage-ui/cypress/support/page-objects/apiKeysPage.ts

Co-authored-by: Andrew Snaith <[email protected]>

* Update packages/storage-ui/src/Components/Modules/ApiKeys.tsx

Co-authored-by: Andrew Snaith <[email protected]>

* fix sort bucket test

Co-authored-by: Michael Yankelev <[email protected]>
Co-authored-by: Andrew Snaith <[email protected]>
  • Loading branch information
3 people authored Aug 16, 2022
1 parent 3a13489 commit dbb3031
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 29 deletions.
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

0 comments on commit dbb3031

Please sign in to comment.