aboutsummaryrefslogtreecommitdiffstats
path: root/core/src/views/Setup.cy.ts
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/views/Setup.cy.ts')
-rw-r--r--core/src/views/Setup.cy.ts369
1 files changed, 369 insertions, 0 deletions
diff --git a/core/src/views/Setup.cy.ts b/core/src/views/Setup.cy.ts
new file mode 100644
index 00000000000..f252801c4d8
--- /dev/null
+++ b/core/src/views/Setup.cy.ts
@@ -0,0 +1,369 @@
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+import type { SetupConfig, SetupLinks } from '../install'
+import SetupView from './Setup.vue'
+
+import '../../css/guest.css'
+
+const defaultConfig = Object.freeze({
+ adminlogin: '',
+ adminpass: '',
+ dbuser: '',
+ dbpass: '',
+ dbname: '',
+ dbtablespace: '',
+ dbhost: '',
+ dbtype: '',
+ databases: {
+ sqlite: 'SQLite',
+ mysql: 'MySQL/MariaDB',
+ pgsql: 'PostgreSQL',
+ },
+ directory: '',
+ hasAutoconfig: false,
+ htaccessWorking: true,
+ serverRoot: '/var/www/html',
+ errors: [],
+}) as SetupConfig
+
+const links = {
+ adminInstall: 'https://docs.nextcloud.com/server/32/go.php?to=admin-install',
+ adminSourceInstall: 'https://docs.nextcloud.com/server/32/go.php?to=admin-source_install',
+ adminDBConfiguration: 'https://docs.nextcloud.com/server/32/go.php?to=admin-db-configuration',
+} as SetupLinks
+
+describe('Default setup page', () => {
+ beforeEach(() => {
+ cy.mockInitialState('core', 'links', links)
+ })
+
+ afterEach(() => cy.unmockInitialState())
+
+ it('Renders default config', () => {
+ cy.mockInitialState('core', 'config', defaultConfig)
+ cy.mount(SetupView)
+
+ cy.get('[data-cy-setup-form]').scrollIntoView()
+ cy.get('[data-cy-setup-form]').should('be.visible')
+
+ // Single note is the footer help
+ cy.get('[data-cy-setup-form-note]')
+ .should('have.length', 1)
+ .should('be.visible')
+ cy.get('[data-cy-setup-form-note]').should('contain', 'See the documentation')
+
+ // DB radio selectors
+ cy.get('[data-cy-setup-form-field^="dbtype"]')
+ .should('exist')
+ .find('input')
+ .should('be.checked')
+
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"]').should('exist')
+ cy.get('[data-cy-setup-form-field="dbtype-pgsql"]').should('exist')
+ cy.get('[data-cy-setup-form-field="dbtype-oci"]').should('not.exist')
+
+ // Sqlite warning
+ cy.get('[data-cy-setup-form-db-note="sqlite"]')
+ .should('be.visible')
+
+ // admin login, password, data directory and 3 DB radio selectors
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 6)
+ })
+
+ it('Renders single DB sqlite', () => {
+ const config = {
+ ...defaultConfig,
+ databases: {
+ sqlite: 'SQLite',
+ },
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // No DB radio selectors if only sqlite
+ cy.get('[data-cy-setup-form-field^="dbtype"]')
+ .should('not.exist')
+
+ // Two warnings: sqlite and single db support
+ cy.get('[data-cy-setup-form-db-note="sqlite"]')
+ .should('be.visible')
+ cy.get('[data-cy-setup-form-db-note="single-db"]')
+ .should('be.visible')
+
+ // Admin login, password and data directory
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 3)
+ })
+
+ it('Renders single DB mysql', () => {
+ const config = {
+ ...defaultConfig,
+ databases: {
+ mysql: 'MySQL/MariaDB',
+ },
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // No DB radio selectors if only mysql
+ cy.get('[data-cy-setup-form-field^="dbtype"]')
+ .should('not.exist')
+
+ // Single db support warning
+ cy.get('[data-cy-setup-form-db-note="single-db"]')
+ .should('be.visible')
+ .invoke('html')
+ .should('contains', links.adminSourceInstall)
+
+ // No SQLite warning
+ cy.get('[data-cy-setup-form-db-note="sqlite"]')
+ .should('not.exist')
+
+ // Admin login, password, data directory, db user,
+ // db password, db name and db host
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 7)
+ })
+
+ it('Changes fields from sqlite to mysql then oci', () => {
+ const config = {
+ ...defaultConfig,
+ databases: {
+ sqlite: 'SQLite',
+ mysql: 'MySQL/MariaDB',
+ pgsql: 'PostgreSQL',
+ oci: 'Oracle',
+ },
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // SQLite selected
+ cy.get('[data-cy-setup-form-field="dbtype-sqlite"]')
+ .should('be.visible')
+ .find('input')
+ .should('be.checked')
+
+ // Admin login, password, data directory and 4 DB radio selectors
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 7)
+
+ // Change to MySQL
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"]').click()
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"] input').should('be.checked')
+
+ // Admin login, password, data directory, db user, db password,
+ // db name, db host and 4 DB radio selectors
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 11)
+
+ // Change to Oracle
+ cy.get('[data-cy-setup-form-field="dbtype-oci"]').click()
+ cy.get('[data-cy-setup-form-field="dbtype-oci"] input').should('be.checked')
+
+ // Admin login, password, data directory, db user, db password,
+ // db name, db table space, db host and 4 DB radio selectors
+ cy.get('[data-cy-setup-form-field]')
+ .should('be.visible')
+ .should('have.length', 12)
+ cy.get('[data-cy-setup-form-field="dbtablespace"]')
+ .should('be.visible')
+ })
+})
+
+describe('Setup page with errors and warning', () => {
+ beforeEach(() => {
+ cy.mockInitialState('core', 'links', links)
+ })
+
+ afterEach(() => cy.unmockInitialState())
+
+ it('Renders error from backend', () => {
+ const config = {
+ ...defaultConfig,
+ errors: [
+ {
+ error: 'Error message',
+ hint: 'Error hint',
+ },
+ ],
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // Error message and hint
+ cy.get('[data-cy-setup-form-note="error"]')
+ .should('be.visible')
+ .should('have.length', 1)
+ .should('contain', 'Error message')
+ .should('contain', 'Error hint')
+ })
+
+ it('Renders errors from backend', () => {
+ const config = {
+ ...defaultConfig,
+ errors: [
+ 'Error message 1',
+ {
+ error: 'Error message',
+ hint: 'Error hint',
+ },
+ ],
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // Error message and hint
+ cy.get('[data-cy-setup-form-note="error"]')
+ .should('be.visible')
+ .should('have.length', 2)
+ cy.get('[data-cy-setup-form-note="error"]').eq(0)
+ .should('contain', 'Error message 1')
+ cy.get('[data-cy-setup-form-note="error"]').eq(1)
+ .should('contain', 'Error message')
+ .should('contain', 'Error hint')
+ })
+
+ it('Renders all the submitted fields on error', () => {
+ const config = {
+ ...defaultConfig,
+ adminlogin: 'admin',
+ adminpass: 'password',
+ dbname: 'nextcloud',
+ dbtype: 'mysql',
+ dbuser: 'nextcloud',
+ dbpass: 'password',
+ dbhost: 'localhost',
+ directory: '/var/www/html/nextcloud',
+ } as SetupConfig
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ cy.get('input[data-cy-setup-form-field="adminlogin"]')
+ .should('have.value', 'admin')
+ cy.get('input[data-cy-setup-form-field="adminpass"]')
+ .should('have.value', 'password')
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"] input')
+ .should('be.checked')
+ cy.get('input[data-cy-setup-form-field="dbname"]')
+ .should('have.value', 'nextcloud')
+ cy.get('input[data-cy-setup-form-field="dbuser"]')
+ .should('have.value', 'nextcloud')
+ cy.get('input[data-cy-setup-form-field="dbpass"]')
+ .should('have.value', 'password')
+ cy.get('input[data-cy-setup-form-field="dbhost"]')
+ .should('have.value', 'localhost')
+ cy.get('input[data-cy-setup-form-field="directory"]')
+ .should('have.value', '/var/www/html/nextcloud')
+ })
+
+ it('Renders the htaccess warning', () => {
+ const config = {
+ ...defaultConfig,
+ htaccessWorking: false,
+ }
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ cy.get('[data-cy-setup-form-note="htaccess"]')
+ .should('be.visible')
+ .should('contain', 'Security warning')
+ .invoke('html')
+ .should('contains', links.adminInstall)
+ })
+})
+
+describe('Setup page with autoconfig', () => {
+ beforeEach(() => {
+ cy.mockInitialState('core', 'links', links)
+ })
+
+ afterEach(() => cy.unmockInitialState())
+
+ it('Renders autoconfig', () => {
+ const config = {
+ ...defaultConfig,
+ hasAutoconfig: true,
+ dbname: 'nextcloud',
+ dbtype: 'mysql',
+ dbuser: 'nextcloud',
+ dbpass: 'password',
+ dbhost: 'localhost',
+ directory: '/var/www/html/nextcloud',
+ } as SetupConfig
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // Autoconfig info note
+ cy.get('[data-cy-setup-form-note="autoconfig"]')
+ .should('be.visible')
+ .should('contain', 'Autoconfig file detected')
+
+ // Database and storage section is hidden as already set in autoconfig
+ cy.get('[data-cy-setup-form-advanced-config]').should('be.visible')
+ .invoke('attr', 'open')
+ .should('equal', undefined)
+
+ // Oracle tablespace is hidden
+ cy.get('[data-cy-setup-form-field="dbtablespace"]')
+ .should('not.exist')
+ })
+})
+
+describe('Submit a full form sends the data', () => {
+ beforeEach(() => {
+ cy.mockInitialState('core', 'links', links)
+ })
+
+ afterEach(() => cy.unmockInitialState())
+
+ it('Submits a full form', () => {
+ const config = {
+ ...defaultConfig,
+ adminlogin: 'admin',
+ adminpass: 'password',
+ dbname: 'nextcloud',
+ dbtype: 'mysql',
+ dbuser: 'nextcloud',
+ dbpass: 'password',
+ dbhost: 'localhost',
+ dbtablespace: 'tablespace',
+ directory: '/var/www/html/nextcloud',
+ } as SetupConfig
+
+ cy.intercept('POST', '**', {
+ delay: 2000,
+ }).as('setup')
+
+ cy.mockInitialState('core', 'config', config)
+ cy.mount(SetupView)
+
+ // Not chaining breaks the test as the POST prevents the element from being retrieved twice
+ // eslint-disable-next-line cypress/unsafe-to-chain-command
+ cy.get('[data-cy-setup-form-submit]')
+ .click()
+ .invoke('attr', 'disabled')
+ .should('equal', 'disabled', { timeout: 500 })
+
+ cy.wait('@setup')
+ .its('request.body')
+ .should('deep.equal', new URLSearchParams({
+ adminlogin: 'admin',
+ adminpass: 'password',
+ directory: '/var/www/html/nextcloud',
+ dbtype: 'mysql',
+ dbuser: 'nextcloud',
+ dbpass: 'password',
+ dbname: 'nextcloud',
+ dbhost: 'localhost',
+ }).toString())
+ })
+})