forked from quay/quay
-
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.
ui: Add organization and user account settings (PROJQUAY-4553)
- This PR adds settings pages to the organization and user organization pages. - Admin users can edit their preferences, billing, and organization type - Updated cypress version to address bug cypress-io/cypress#25397
- Loading branch information
1 parent
38fd992
commit 2556a17
Showing
18 changed files
with
1,444 additions
and
298 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
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,103 @@ | ||
/// <reference types="cypress" /> | ||
|
||
describe('Account Settings Page', () => { | ||
beforeEach(() => { | ||
cy.exec('npm run quay:seed'); | ||
cy.visit('/signin'); | ||
cy.request('GET', `${Cypress.env('REACT_QUAY_APP_API_URL')}/csrf_token`) | ||
.then((response) => response.body.csrf_token) | ||
.then((token) => { | ||
cy.loginByCSRF(token); | ||
}); | ||
cy.intercept('GET', '/config', {fixture: 'config.json'}).as('getConfig'); | ||
cy.intercept('GET', '/api/v1/plans/', {fixture: 'plans.json'}).as( | ||
'getPlans', | ||
); | ||
}); | ||
|
||
it('General Settings', () => { | ||
cy.visit('/organization/user1?tab=Settings'); | ||
|
||
// Type a bad e-mail | ||
cy.get('#org-settings-email').clear(); | ||
cy.get('#org-settings-email').type('this is not a good e-mail'); | ||
cy.contains('Please enter a valid email address'); | ||
|
||
// Leave empty | ||
cy.get('#org-settings-email').clear(); | ||
cy.contains('Please enter email associate with namespace'); | ||
|
||
// check is disabled | ||
cy.get('#save-org-settings').should('be.disabled'); | ||
cy.get('#org-settings-email').clear(); | ||
|
||
// Type a good content | ||
cy.get('#org-settings-email').type('good-email@redhat.com'); | ||
cy.get('#org-settings-fullname').type('Joe Smith'); | ||
cy.get('#org-settings-location').type('Raleigh, NC'); | ||
cy.get('#org-settings-company').type('Red Hat'); | ||
cy.get('#save-org-settings').click(); | ||
|
||
// refresh page and check if email is saved | ||
cy.reload(); | ||
cy.get('#org-settings-email').should('have.value', 'good-email@redhat.com'); | ||
cy.get('#org-settings-fullname').should('have.value', 'Joe Smith'); | ||
cy.get('#org-settings-location').should('have.value', 'Raleigh, NC'); | ||
cy.get('#org-settings-company').should('have.value', 'Red Hat'); | ||
}); | ||
|
||
it('Billing Information', () => { | ||
cy.visit('/organization/user1?tab=Settings'); | ||
|
||
// navigate to billing tab | ||
cy.get('#pf-tab-1-billinginformation').click(); | ||
|
||
// Type a bad e-mail | ||
cy.get('#billing-settings-invoice-email').clear(); | ||
cy.get('#billing-settings-invoice-email').type('this is not a good e-mail'); | ||
|
||
// check is disabled | ||
cy.get('#save-billing-settings').should('be.disabled'); | ||
cy.get('#billing-settings-invoice-email').clear(); | ||
|
||
// Type a good e-mail and save | ||
cy.get('#billing-settings-invoice-email').type('invoice-email@redhat.com'); | ||
|
||
// check save receipts | ||
cy.get('#checkbox').should('not.be.checked'); | ||
cy.get('#checkbox').click(); | ||
|
||
// Save | ||
cy.get('#save-billing-settings').click(); | ||
|
||
// refresh page, navigate to billing tab and check if email is saved | ||
cy.reload(); | ||
cy.get('#pf-tab-1-billinginformation').click(); | ||
cy.get('#billing-settings-invoice-email').should( | ||
'have.value', | ||
'invoice-email@redhat.com', | ||
); | ||
cy.get('#checkbox').should('be.checked'); | ||
}); | ||
|
||
it('CLI Token', () => { | ||
cy.visit('/organization/user1?tab=Settings'); | ||
|
||
// navigate to CLI Tab | ||
cy.get('#pf-tab-2-cliconfig').click(); | ||
|
||
// Click generate password | ||
cy.get('#cli-password-button').click(); | ||
|
||
// Wrong password | ||
cy.get('#delete-confirmation-input').type('wrongpassword'); | ||
cy.get('#submit').click(); | ||
cy.contains('Invalid Username or Password'); | ||
|
||
// Correct password | ||
cy.get('#delete-confirmation-input').clear(); | ||
cy.get('#delete-confirmation-input').type('password'); | ||
cy.get('#submit').click(); | ||
cy.contains('Your encrypted password is'); | ||
}); | ||
}); |
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,83 @@ | ||
/// <reference types="cypress" /> | ||
|
||
describe('Org Settings Page', () => { | ||
beforeEach(() => { | ||
cy.exec('npm run quay:seed'); | ||
cy.visit('/signin'); | ||
cy.request('GET', `${Cypress.env('REACT_QUAY_APP_API_URL')}/csrf_token`) | ||
.then((response) => response.body.csrf_token) | ||
.then((token) => { | ||
cy.loginByCSRF(token); | ||
}); | ||
cy.intercept('GET', '/config', {fixture: 'config.json'}).as('getConfig'); | ||
cy.intercept('GET', '/api/v1/plans/', {fixture: 'plans.json'}).as( | ||
'getPlans', | ||
); | ||
}); | ||
|
||
it('General Settings', () => { | ||
cy.visit('/organization/projectquay?tab=Settings'); | ||
|
||
// Type a bad e-mail | ||
cy.get('#org-settings-email').clear(); | ||
cy.get('#org-settings-email').type('this is not a good e-mail'); | ||
cy.contains('Please enter a valid email address'); | ||
|
||
// Leave empty | ||
cy.get('#org-settings-email').clear(); | ||
cy.contains('Please enter email associate with namespace'); | ||
|
||
// check is disabled | ||
cy.get('#save-org-settings').should('be.disabled'); | ||
cy.get('#org-settings-email').clear(); | ||
|
||
// Type a good e-mail and save | ||
cy.get('#org-settings-email').type('good-email@redhat.com'); | ||
cy.get('#save-org-settings').click(); | ||
|
||
// refresh page and check if email is saved | ||
cy.reload(); | ||
cy.get('#org-settings-email').should('have.value', 'good-email@redhat.com'); | ||
}); | ||
|
||
it('Billing Information', () => { | ||
cy.visit('/organization/projectquay?tab=Settings'); | ||
|
||
// navigate to billing tab | ||
cy.get('#pf-tab-1-billinginformation').click(); | ||
|
||
// Type a bad e-mail | ||
cy.get('#billing-settings-invoice-email').clear(); | ||
cy.get('#billing-settings-invoice-email').type('this is not a good e-mail'); | ||
|
||
// check is disabled | ||
cy.get('#save-billing-settings').should('be.disabled'); | ||
cy.get('#billing-settings-invoice-email').clear(); | ||
|
||
// Type a good e-mail and save | ||
cy.get('#billing-settings-invoice-email').type('invoice-email@redhat.com'); | ||
|
||
// check save receipts | ||
cy.get('#checkbox').should('not.be.checked'); | ||
cy.get('#checkbox').click(); | ||
|
||
// Save | ||
cy.get('#save-billing-settings').click(); | ||
|
||
// refresh page, navigate to billing tab and check if email is saved | ||
cy.reload(); | ||
cy.get('#pf-tab-1-billinginformation').click(); | ||
cy.get('#billing-settings-invoice-email').should( | ||
'have.value', | ||
'invoice-email@redhat.com', | ||
); | ||
cy.get('#checkbox').should('be.checked'); | ||
}); | ||
|
||
it('Cli Token Invisible', () => { | ||
cy.visit('/organization/projectquay?tab=Settings'); | ||
|
||
// ensure cli token tab is not on page | ||
cy.get('#pf-tab-2-cliconfig').should('not.exist'); | ||
}); | ||
}); |
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
82 changes: 82 additions & 0 deletions
82
web/src/components/modals/GenerateEncryptedPasswordModal.tsx
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,82 @@ | ||
import {Modal, ModalVariant, Button, TextInput} from '@patternfly/react-core'; | ||
import {useState} from 'react'; | ||
import FormError from 'src/components/errors/FormError'; | ||
import {addDisplayError} from 'src/resources/ErrorHandling'; | ||
import {useCreateClientKey} from 'src/hooks/UseCreateClientKey'; | ||
|
||
export function GenerateEncryptedPassword(props: ConfirmationModalProps) { | ||
const [err, setErr] = useState<string>(); | ||
|
||
const [password, setPassword] = useState(''); | ||
const [step, setStep] = useState(1); | ||
const {createClientKey, clientKey} = useCreateClientKey({ | ||
onError: (error) => { | ||
console.error(error); | ||
setErr(addDisplayError('Error', error)); | ||
}, | ||
onSuccess: () => { | ||
setStep(step + 1); | ||
}, | ||
}); | ||
|
||
const handleModalConfirm = async () => { | ||
createClientKey(password); | ||
}; | ||
|
||
return ( | ||
<Modal | ||
variant={ModalVariant.small} | ||
title={props.title} | ||
isOpen={props.modalOpen} | ||
onClose={props.toggleModal} | ||
actions={ | ||
step == 1 | ||
? [ | ||
<Button | ||
key="confirm" | ||
variant="primary" | ||
onClick={handleModalConfirm} | ||
id="submit" | ||
> | ||
{props.buttonText} | ||
</Button>, | ||
<Button key="cancel" variant="link" onClick={props.toggleModal}> | ||
Cancel | ||
</Button>, | ||
] | ||
: [ | ||
<Button key="cancel" variant="link" onClick={props.toggleModal}> | ||
Done | ||
</Button>, | ||
] | ||
} | ||
> | ||
{step == 1 && ( | ||
<> | ||
<FormError message={err} setErr={setErr} /> | ||
<TextInput | ||
id="delete-confirmation-input" | ||
value={password} | ||
type="password" | ||
onChange={(_, value) => setPassword(value)} | ||
aria-label="text input example" | ||
label="Password" | ||
/> | ||
Please enter your password in order to generate | ||
</> | ||
)} | ||
{step == 2 && ( | ||
<> | ||
Your encrypted password is: <br /> {clientKey} | ||
</> | ||
)} | ||
</Modal> | ||
); | ||
} | ||
|
||
type ConfirmationModalProps = { | ||
title: string; | ||
modalOpen: boolean; | ||
buttonText: string; | ||
toggleModal: () => void; | ||
}; |
Oops, something went wrong.