Skip to content

Commit

Permalink
refactor(applications): make deletion error static (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewwylde authored Feb 27, 2024
1 parent 0e57cbc commit f72d273
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 78 deletions.
154 changes: 123 additions & 31 deletions cypress/e2e/specs/application_registration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,46 +481,116 @@ describe('Application Registration', () => {
cy.get(submitButton).click()
cy.contains(apps[0].name + 'z')
})
it('can delete an existing application', () => {
cy.mockApplications(apps, 4)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0])
describe('Delete Application', () => {
it('can delete an existing application', () => {
cy.mockApplications(apps, 4)
cy.visit('/my-apps')

cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 4)
.contains(apps[0].name)
.click()
mockApplicationWithCredAndReg(apps[0])

cy.get('[data-testid="application-update-button"]').click()
cy.get('header h1').should('contain', 'Update Application')
cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 4)
.contains(apps[0].name)
.click()

// Delete and cancel during confirmation
cy.get('[data-testid="application-delete-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-cancel-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('not.exist')
cy.get('[data-testid="application-update-button"]').click()
cy.get('header h1').should('contain', 'Update Application')

cy.intercept('DELETE', `api/v2/applications/${apps[0].id}`, {
statusCode: 200
}).as('deleteApplication')
// Delete and cancel during confirmation
cy.get('[data-testid="application-delete-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-cancel-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('not.exist')

cy.mockApplications([...apps.slice(1)], 2)
cy.intercept('DELETE', `api/v2/applications/${apps[0].id}`, {
statusCode: 200
}).as('deleteApplication')

// Delete and confirm deletion
cy.get('[data-testid="application-delete-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-confirm-button"]').click()
cy.mockApplications([...apps.slice(1)], 2)

cy.get('.toaster-container-outer .message').should(
'contain',
'Application successfully deleted'
)
// Delete and confirm deletion
cy.get('[data-testid="application-delete-button"]').click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-confirm-button"]').click()

cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 3)
.contains(apps[0].name)
.should('not.exist')
cy.get('.toaster-container-outer .message').should(
'contain',
'Application successfully deleted'
)

cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 3)
.contains(apps[0].name)
.should('not.exist')
})
it('can delete an existing application from actions dropdown', () => {
cy.mockApplications(apps, 4)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0])

cy.intercept('DELETE', `api/v2/applications/${apps[0].id}`, {
statusCode: 200
}).as('deleteApplication')

// Delete and confirm deletion
cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 4)
.contains(apps[0].name)
.get(`[data-testid="actions-dropdown-${apps[0].id}"]`)
.click()

cy.mockApplications([...apps.slice(1)], 2)

cy.get(`[data-testid="actions-dropdown-${apps[0].id}"] [data-testid="dropdown-delete-application"]`).click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-confirm-button"]').click()

cy.get('.toaster-container-outer .message').should(
'contain',
'Application successfully deleted'
)

cy.wait('@getApplications')

cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 3)
.contains(apps[0].name)
.should('not.exist')
})
it('handles error when deleting an existing application', () => {
cy.mockApplications(apps, 4)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0])

cy.intercept('DELETE', `api/v2/applications/${apps[0].id}`, {
statusCode: 500,
body: { message: 'Error deleting application' }
}).as('deleteApplication')

// Delete and confirm deletion
cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 4)
.contains(apps[0].name)
.get(`[data-testid="actions-dropdown-${apps[0].id}"]`)
.click()

cy.get(`[data-testid="actions-dropdown-${apps[0].id}"] [data-testid="dropdown-delete-application"]`).click()
cy.get('[data-testid="application-delete-modal"]').should('exist')
cy.get('[data-testid="application-delete-confirm-button"]').click()

cy.get('[data-testid="delete-error-alert"]').should(
'contain',
'Error deleting application'
)

cy.get('[data-testid="applications-table"] tbody tr')
.should('have.length', 4)
.contains(apps[0].name)
.should('exist')
})
})

it('shows granted scopes if present ', () => {
Expand Down Expand Up @@ -1483,6 +1553,28 @@ describe('Application Registration', () => {
cy.get('[data-testid="application-secret-token-modal"]').should('not.exist')
})

it('handles failure to refresh token of existing application with dcr', () => {
cy.mockDcrPortal()
cy.mockApplications([{ ...apps[0] }], 1)
cy.visit('/my-apps')

cy.get('[data-testid="applications-table"] tbody tr .actions-badge')
.should('have.length', 1)
.click()

cy.intercept('POST', `api/v2/applications/${apps[0].id}/refresh-token`, {
statusCode: 500,
body: { error: 'Internal Server Error' }
}).as('refreshToken')

cy.get('[data-testid="dropdown-delete-application"]').should('exist')
cy.get('[data-testid="dropdown-refresh-application-dcr-token"]').should('exist').click()

cy.wait('@refreshToken')

cy.get('[data-testid="refresh-error-alert"]').should('exist').should('contain', 'Failed to refresh secret')
})

it('can refresh token of existing application with dcr from application page', () => {
cy.mockApplications([{ ...apps[0], created_at: '2022-11-02T18:59:30.789Z' }], 1)
mockApplicationWithCredAndReg({ ...apps[0], created_at: '2022-11-02T18:59:30.789Z' })
Expand Down
7 changes: 6 additions & 1 deletion src/locales/ca_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,18 +300,23 @@ export const ca_ES: I18nType = {
},
myApp: {
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
authStrategyFetchError: (errString: string) => translationNeeded(en.myApp.authStrategyFetchError(errString)),
newApp: 'Nova aplicació',
plus: 'Més',
myApps: 'Les meves aplicacions',
refreshSecret: 'Actualitzar secret',
refreshSecretSuccess: translationNeeded(en.myApp.refreshSecretSuccess),
refreshSecretFailure: (error: string) => translationNeeded(en.myApp.refreshSecretFailure(error)),
noSearchResults: translationNeeded(en.myApp.noSearchResults),
searchPlaceholder: translationNeeded(en.myApp.searchPlaceholder),
delete: 'Eliminar',
cancel: 'Cancel·lar',
noApp: 'Sense aplicacions',
create: 'Crear una nova aplicació',
getStarted: ' per començar',
deleteDialog: (name: string) => `Segur que voleu eliminar ${name}?Aquesta acció no es pot desfer.`
deleteDialog: (name: string) => `Segur que voleu eliminar ${name}?Aquesta acció no es pot desfer.`,
deleteSuccess: translationNeeded(en.myApp.deleteSuccess),
deleteFailure: (str: string) => translationNeeded(en.myApp.deleteFailure(str))
},
router: {
portalTitle: 'Portal del desenvolupador',
Expand Down
7 changes: 6 additions & 1 deletion src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,18 +300,23 @@ export const de: I18nType = {
},
myApp: {
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
authStrategyFetchError: (errString: string) => translationNeeded(en.myApp.authStrategyFetchError(errString)),
newApp: 'Neue Applikation',
plus: 'Plus',
myApps: 'Meine Applikationen',
refreshSecret: 'Secret erneuern',
refreshSecretSuccess: translationNeeded(en.myApp.refreshSecretSuccess),
refreshSecretFailure: (error: string) => translationNeeded(en.myApp.refreshSecretFailure(error)),
noSearchResults: translationNeeded(en.myApp.noSearchResults),
searchPlaceholder: translationNeeded(en.myApp.searchPlaceholder),
delete: 'Löschen',
cancel: 'Abbrechen',
noApp: 'Keine Applikationen',
create: 'Neue Applikation anlegen',
getStarted: ' um loszulegen',
deleteDialog: (name: string) => `Sind Sie sicher, dass Sie ${name} löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.`
deleteDialog: (name: string) => `Sind Sie sicher, dass Sie ${name} löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.`,
deleteSuccess: translationNeeded(en.myApp.deleteSuccess),
deleteFailure: (str: string) => translationNeeded(en.myApp.deleteFailure(str))
},
router: {
portalTitle: 'Entwicklerportal',
Expand Down
7 changes: 6 additions & 1 deletion src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,18 +296,23 @@ export const en = {
},
myApp: {
authStrategyWarning: 'You cannot create an application as this developer portal has no available application auth strategies. Please contact a developer portal admin.',
authStrategyFetchError: (errString: string) => `Error fetching auth strategies: ${errString}`,
newApp: 'New App',
plus: 'Plus',
myApps: 'My Apps',
refreshSecret: 'Refresh secret',
refreshSecretSuccess: 'Successfully refreshed secret',
refreshSecretFailure: (str: string) => `Failed to refresh secret: ${str}`,
delete: 'Delete',
cancel: 'Cancel',
noApp: 'No Applications',
searchPlaceholder: 'Search applications',
noSearchResults: 'No Applications Found',
create: 'Create a new app',
getStarted: ' to get started',
deleteDialog: (name: string) => `Are you sure you want to delete ${name}? This action cannot be undone.`
deleteDialog: (name: string) => `Are you sure you want to delete ${name}? This action cannot be undone.`,
deleteSuccess: 'Application successfully deleted',
deleteFailure: (str: string) => `Failed to delete application: ${str}`
},
router: {
portalTitle: 'Developer Portal',
Expand Down
7 changes: 6 additions & 1 deletion src/locales/es_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,18 +300,23 @@ export const es_ES: I18nType = {
},
myApp: {
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
authStrategyFetchError: (errString: string) => translationNeeded(en.myApp.authStrategyFetchError(errString)),
newApp: 'Nueva aplicación',
plus: 'Plus',
myApps: 'Mis aplicaciones',
refreshSecret: 'Refrescar clave secreta',
refreshSecretSuccess: translationNeeded(en.myApp.refreshSecretSuccess),
refreshSecretFailure: (error: string) => translationNeeded(en.myApp.refreshSecretFailure(error)),
noSearchResults: translationNeeded(en.myApp.noSearchResults),
searchPlaceholder: translationNeeded(en.myApp.searchPlaceholder),
delete: 'Eliminar',
cancel: 'Cancelar',
noApp: 'No hay aplicaciones',
create: 'Crear una nueva aplicación',
getStarted: ' para empezar',
deleteDialog: (name: string) => `¿Estas seguro que quieres borrar ${name}? Esta acción no se puede deshacer.`
deleteDialog: (name: string) => `¿Estas seguro que quieres borrar ${name}? Esta acción no se puede deshacer.`,
deleteSuccess: translationNeeded(en.myApp.deleteSuccess),
deleteFailure: (str: string) => translationNeeded(en.myApp.deleteFailure(str))
},
router: {
portalTitle: 'Portal de desarrolladores',
Expand Down
7 changes: 6 additions & 1 deletion src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,18 +300,23 @@ export const fr: I18nType = {
},
myApp: {
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
authStrategyFetchError: (errString: string) => translationNeeded(en.myApp.authStrategyFetchError(errString)),
newApp: 'Nouvelle application',
plus: 'Plus',
myApps: 'Mes applications',
refreshSecret: 'Actualiser le secret',
refreshSecretSuccess: translationNeeded(en.myApp.refreshSecretSuccess),
refreshSecretFailure: (error: string) => translationNeeded(en.myApp.refreshSecretFailure(error)),
noSearchResults: translationNeeded(en.myApp.noSearchResults),
searchPlaceholder: translationNeeded(en.myApp.searchPlaceholder),
delete: 'Supprimer',
cancel: 'Annuler',
noApp: 'Aucune application',
create: 'Créer une nouvelle application',
getStarted: ' pour commencer',
deleteDialog: (name: string) => `Voulez-vous vraiment supprimer ${name} ? Cette action est irréversible.`
deleteDialog: (name: string) => `Voulez-vous vraiment supprimer ${name} ? Cette action est irréversible.`,
deleteSuccess: translationNeeded(en.myApp.deleteSuccess),
deleteFailure: (str: string) => translationNeeded(en.myApp.deleteFailure(str))
},
router: {
portalTitle: 'Portail développeur',
Expand Down
5 changes: 5 additions & 0 deletions src/locales/i18n-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,13 @@ export interface I18nType {
};
myApp: {
authStrategyWarning: string;
authStrategyFetchError: (errString: string) => string;
newApp: string;
plus: string;
myApps: string;
refreshSecret: string;
refreshSecretSuccess: string;
refreshSecretFailure: (error:string) => string;
delete: string;
cancel: string;
searchPlaceholder: string;
Expand All @@ -308,6 +311,8 @@ export interface I18nType {
create: string;
getStarted: string;
deleteDialog: (name: string) => string;
deleteSuccess: string;
deleteFailure: (str: string) => string;
};
router: {
portalTitle: string;
Expand Down
28 changes: 0 additions & 28 deletions src/mixins/toaster.ts

This file was deleted.

Loading

0 comments on commit f72d273

Please sign in to comment.