From f7bd75cf32321d688fab435c1e1dd48bc7ed6608 Mon Sep 17 00:00:00 2001 From: Arit Amana <32520970+msarit@users.noreply.github.com> Date: Wed, 3 Feb 2021 15:31:55 -0500 Subject: [PATCH] Cypress tests for `/admin/config` Authentication Section (#12539) * write tests for invite-only mode and auth-providers * text edits * modify specs in light of new e2e database setup * Still working things out * Added the admin user name to the e2e fixture data. * Added testid for config sections. * Fixed up test to use cypress-testing-library APIs. * Fixed unsetting invite only mode, still need to reset it at end of test. * Small fix for local e2e development. * Complete all tests; generalize updateAdminConfig cypress command * correct spec * Complete implementation * Address code review comments * address code review comments #2 Co-authored-by: Nick Taylor --- app/views/admin/configs/show.html.erb | 6 +- bin/e2e | 1 + bin/e2e-setup | 1 - cypress/fixtures/users/adminUser.json | 5 + .../config/authenticationSection.spec.js | 137 ++++++++++++++++++ cypress/support/commands.js | 78 ++++++++++ 6 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 cypress/fixtures/users/adminUser.json create mode 100644 cypress/integration/adminFlows/config/authenticationSection.spec.js diff --git a/app/views/admin/configs/show.html.erb b/app/views/admin/configs/show.html.erb index 93bfe250b..60970345e 100644 --- a/app/views/admin/configs/show.html.erb +++ b/app/views/admin/configs/show.html.erb @@ -147,7 +147,7 @@ <% end %> - <%= form_for(SiteConfig.new, url: admin_config_path, html: { data: { action: "submit->config#configUpdatePrecheck", "config-target": "authSectionForm" } }) do |f| %> + <%= form_for(SiteConfig.new, url: admin_config_path, html: { data: { action: "submit->config#configUpdatePrecheck", "config-target": "authSectionForm", "testid": "authSectionForm" } }) do |f| %>
<%= render partial: "admin/shared/card_header", locals: { @@ -200,7 +200,7 @@
" data-config-target="enabledIndicator"> - <%= inline_svg_tag("checkmark.svg", aria: true, class: "crayons-icon admin-config-checkmark", title: "Checkmark") %> + <%= inline_svg_tag("checkmark.svg", aria: true, class: "crayons-icon admin-config-checkmark", title: "Email enabled") %> Enabled
@@ -324,7 +324,7 @@
"> - <%= inline_svg_tag("checkmark.svg", aria: true, class: "crayons-icon admin-config-checkmark", title: "Checkmark") %> + <%= inline_svg_tag("checkmark.svg", aria: true, class: "crayons-icon admin-config-checkmark", title: "#{provider.official_name} enabled") %> Enabled
diff --git a/bin/e2e b/bin/e2e index 55a5dfe78..c0564bcc3 100755 --- a/bin/e2e +++ b/bin/e2e @@ -16,4 +16,5 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then RAILS_ENV=test E2E=true bin/e2e-setup fi +bundle exec rails assets:precompile; CYPRESS_RAILS_CYPRESS_OPTS="--config-file cypress.dev.json" RAILS_ENV=test E2E=true bundle exec rake cypress:open diff --git a/bin/e2e-setup b/bin/e2e-setup index 498f88800..ac3f55775 100755 --- a/bin/e2e-setup +++ b/bin/e2e-setup @@ -6,4 +6,3 @@ fi bundle exec rails db:drop; bundle exec rails db:create; bundle exec rails db:schema:load; -bundle exec rails assets:precompile; diff --git a/cypress/fixtures/users/adminUser.json b/cypress/fixtures/users/adminUser.json new file mode 100644 index 000000000..064d75c7f --- /dev/null +++ b/cypress/fixtures/users/adminUser.json @@ -0,0 +1,5 @@ +{ + "username": "admin_mcadmin", + "email": "admin@forem.local", + "password": "password" +} diff --git a/cypress/integration/adminFlows/config/authenticationSection.spec.js b/cypress/integration/adminFlows/config/authenticationSection.spec.js new file mode 100644 index 000000000..586564798 --- /dev/null +++ b/cypress/integration/adminFlows/config/authenticationSection.spec.js @@ -0,0 +1,137 @@ +describe('Authentication Section', () => { + beforeEach(() => { + cy.testSetup(); + cy.fixture('users/adminUser.json').as('user'); + + cy.get('@user').then((user) => { + cy.loginUser(user).then(() => { + cy.updateAdminAuthConfig(user.username); + }); + }); + }); + + describe('invite-only mode setting', () => { + it('should disable email registration and all authorization providers when enabled', () => { + cy.fixture('users/adminUser.json').as('user'); + + cy.get('@user').then(({ username }) => { + cy.updateAdminAuthConfig(username, { + authProvidersToEnable: 'facebook', + facebookKey: 'somekey', + facebookSecret: 'somesecret', + }).then(() => { + cy.visit('/admin/config'); + cy.findByTestId('authSectionForm').as('authSectionForm'); + + cy.get('@authSectionForm').findByText('Authentication').click(); + cy.get('@authSectionForm') + .findByLabelText('Invite-only mode') + .should('not.be.checked') + .check(); + + cy.get('@authSectionForm') + .findByPlaceholderText('Confirmation text') + .type( + `My username is @${username} and this action is 100% safe and appropriate.`, + ); + cy.get('@authSectionForm') + .findByText('Update Site Configuration') + .click(); + + cy.url().should('contains', '/admin/config'); + + // Page reloaded so need to get a new reference to the form. + cy.findByTestId('authSectionForm').as('authSectionForm'); + + cy.findByText('Site configuration was successfully updated.').should( + 'be.visible', + ); + + cy.get('@authSectionForm').findByText('Authentication').click(); + + cy.get('@authSectionForm') + .findByLabelText('Invite-only mode') + .should('be.checked'); + + // Ensure that none of the authentication providers are enabled. + cy.findByLabelText('Email enabled').should('not.be.visible'); + cy.findByLabelText('Facebook enabled').should('not.be.visible'); + cy.findByLabelText('GitHub enabled').should('not.be.visible'); + cy.findByLabelText('Twitter enabled').should('not.be.visible'); + }); + }); + cy.visit('/signout_confirm'); + + cy.findByText('Yes, sign out').click(); + cy.findByText('Create account').click(); + + cy.findByLabelText('Sign up with Email').should('not.exist'); + cy.findByLabelText('Sign up with Facebook').should('not.exist'); + cy.contains('invite only').should('be.visible'); + }); + }); + + describe('authentication providers settings', () => { + it('should display warning modal if provider keys are missing', () => { + cy.fixture('users/adminUser.json').as('user'); + cy.get('@user').then(() => { + cy.visit('/admin/config'); + cy.findByTestId('authSectionForm').as('authSectionForm'); + + cy.get('@authSectionForm').findByText('Authentication').click(); + cy.get('#facebook-auth-btn').click(); + cy.get('@user').then(({ username }) => { + cy.get('@authSectionForm') + .findByPlaceholderText('Confirmation text') + .type( + `My username is @${username} and this action is 100% safe and appropriate.`, + ); + }); + cy.get('@authSectionForm') + .findByText('Update Site Configuration') + .click(); + + cy.findByText('Setup not complete').should('be.visible'); + cy.get('.crayons-modal__box__body > ul > li') + .contains('facebook') + .should('be.visible'); + }); + }); + + it('should not display warning modal if provider keys present', () => { + cy.fixture('users/adminUser.json').as('user'); + + cy.get('@user').then(() => { + cy.visit('/admin/config'); + cy.findByTestId('authSectionForm').as('authSectionForm'); + + cy.get('@authSectionForm').findByText('Authentication').click(); + cy.get('#facebook-auth-btn').click(); + cy.get('#site_config_facebook_key').type('randomkey'); + cy.get('#site_config_facebook_secret').type('randomsecret'); + cy.get('@user').then(({ username }) => { + cy.get('@authSectionForm') + .findByPlaceholderText('Confirmation text') + .type( + `My username is @${username} and this action is 100% safe and appropriate.`, + ); + }); + cy.get('@authSectionForm') + .findByText('Update Site Configuration') + .click(); + + cy.url().should('contains', '/admin/config'); + + cy.findByText('Site configuration was successfully updated.').should( + 'be.visible', + ); + + // Page reloaded so need to get a new reference to the form. + cy.findByTestId('authSectionForm').as('authSectionForm'); + cy.get('@authSectionForm').findByText('Authentication').click(); + + cy.findByLabelText('Facebook enabled').should('be.visible'); + }); + }); + }); +}); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index bbb3ca996..a2c55a394 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -62,3 +62,81 @@ Cypress.Commands.add('loginUser', ({ email, password }) => { `utf8=%E2%9C%93&user%5Bemail%5D=${encodedEmail}&user%5Bpassword%5D=${encodedPassword}&user%5Bremember_me%5D=0&user%5Bremember_me%5D=1&commit=Continue`, ); }); + +const toPayload = (isEnabled) => (isEnabled ? '1' : '0'); + +const DEFAULT_AUTH_CONFIG = { + inviteOnlyMode: false, + emailRegistration: true, + allowedEmailDomains: '', + publicEmailDomainList: false, + requireRecaptcha: false, + recaptchaSiteKey: '', + recaptchaSecretKey: '', + authProvidersToEnable: '', + facebookKey: '', + facebookSecret: '', + githubKey: '', + githubSecret: '', + twitterKey: '', + twitterSecret: '', +}; + +/** + * Sets default values of SiteConfig atrributes relevant to Authentication Section. + * + * @param username {string} The username used in the test + * @param siteConfig + * @param siteConfig.inviteOnlyMode {boolean} + * @param siteConfig.emailRegistration {boolean} + * @param siteConfig.allowedEmailDomains {string} + * @param siteConfig.publicEmailDomainList {boolean} + * @param siteConfig.requireRecaptcha {boolean} + * @param siteConfig.recaptchaSiteKey {string} + * @param siteConfig.recaptchaSecretKey {string} + * @param siteConfig.authProvidersToEnable {string} Comma-separated string of providers to be enabled + * @param siteConfig.facebookKey {string} + * @param siteConfig.facebookSecret {string} + * @param siteConfig.githubKey {string} + * @param siteConfig.githubSecret {string} + * @param siteConfig.twitterKey {string} + * @param siteConfig.twitterSecret {string} + * + * @returns {Cypress.Chainable} A cypress request for setting SiteConfig values for the Authentication Section. + */ +Cypress.Commands.add( + 'updateAdminAuthConfig', + ( + username = 'admin_mcadmin', + { + inviteOnlyMode = false, + emailRegistration = true, + allowedEmailDomains, + publicEmailDomainList = false, + requireRecaptcha = false, + recaptchaSiteKey, + recaptchaSecretKey, + authProvidersToEnable, + facebookKey, + facebookSecret, + githubKey, + githubSecret, + twitterKey, + twitterSecret, + } = DEFAULT_AUTH_CONFIG, + ) => { + return cy.request( + 'POST', + '/admin/config', + `utf8=%E2%9C%93&site_config%5Binvite_only_mode%5D=${toPayload( + inviteOnlyMode, + )}&site_config%5Ballow_email_password_registration%5D=${toPayload( + emailRegistration, + )}&site_config%5Ballowed_registration_email_domains%5D=${allowedEmailDomains}&site_config%5Bdisplay_email_domain_allow_list_publicly%5D=${toPayload( + publicEmailDomainList, + )}&site_config%5Brequire_captcha_for_email_password_registration%5D=${toPayload( + requireRecaptcha, + )}&site_config%5Brecaptcha_site_key%5D=${recaptchaSiteKey}&site_config%5Brecaptcha_secret_key%5D=${recaptchaSecretKey}&site_config%5Bauth_providers_to_enable%5D=${authProvidersToEnable}&site_config%5Bfacebook_key%5D=${facebookKey}&site_config%5Bfacebook_secret%5D=${facebookSecret}&site_config%5Bgithub_key%5D=${githubKey}&site_config%5Bgithub_secret%5D=${githubSecret}&site_config%5Btwitter_key%5D=${twitterKey}&site_config%5Btwitter_secret%5D=${twitterSecret}&confirmation=My+username+is+%40${username}+and+this+action+is+100%25+safe+and+appropriate.&commit=Update+Site+Configuration`, + ); + }, +);