diff options
Diffstat (limited to 'spec/features/invites_spec.rb')
-rw-r--r-- | spec/features/invites_spec.rb | 319 |
1 files changed, 180 insertions, 139 deletions
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb index e9960802378..a72cf033d61 100644 --- a/spec/features/invites_spec.rb +++ b/spec/features/invites_spec.rb @@ -3,18 +3,16 @@ require 'spec_helper' RSpec.describe 'Group or Project invitations', :aggregate_failures do - let(:user) { create(:user, email: 'user@example.com') } - let(:owner) { create(:user, name: 'John Doe') } - let(:group) { create(:group, name: 'Owned') } - let(:project) { create(:project, :repository, namespace: group) } + let_it_be(:owner) { create(:user, name: 'John Doe') } + let_it_be(:group) { create(:group, name: 'Owned') } + let_it_be(:project) { create(:project, :repository, namespace: group) } + let(:group_invite) { group.group_members.invite.last } before do stub_application_setting(require_admin_approval_after_user_signup: false) project.add_maintainer(owner) group.add_owner(owner) - group.add_developer('user@example.com', owner) - group_invite.generate_invite_token! end def confirm_email(new_user) @@ -23,13 +21,13 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do visit user_confirmation_path(confirmation_token: new_user_token) end - def fill_in_sign_up_form(new_user) + def fill_in_sign_up_form(new_user, submit_button_text = 'Register') fill_in 'new_user_first_name', with: new_user.first_name fill_in 'new_user_last_name', with: new_user.last_name fill_in 'new_user_username', with: new_user.username fill_in 'new_user_email', with: new_user.email fill_in 'new_user_password', with: new_user.password - click_button 'Register' + click_button submit_button_text end def fill_in_sign_in_form(user) @@ -44,46 +42,128 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do click_button 'Get started!' end - context 'when signed out' do + context 'when inviting a registered user' do + let(:invite_email) { 'user@example.com' } + before do - visit invite_path(group_invite.raw_invite_token) + group.add_developer(invite_email, owner) + group_invite.generate_invite_token! end - it 'renders sign in page with sign in notice' do - expect(current_path).to eq(new_user_registration_path) - expect(page).to have_content('To accept this invitation, create an account or sign in') - end + context 'when signed out' do + context 'when analyzing the redirects and forms from invite link click' do + before do + visit invite_path(group_invite.raw_invite_token) + end - it 'pre-fills the "Username or email" field on the sign in box with the invite_email from the invite' do - click_link 'Sign in' + it 'renders sign up page with sign up notice' do + expect(current_path).to eq(new_user_registration_path) + expect(page).to have_content('To accept this invitation, create an account or sign in') + end - expect(find_field('Username or email').value).to eq(group_invite.invite_email) - end + it 'pre-fills the "Username or email" field on the sign in box with the invite_email from the invite' do + click_link 'Sign in' - it 'pre-fills the Email field on the sign up box with the invite_email from the invite' do - expect(find_field('Email').value).to eq(group_invite.invite_email) - end + expect(find_field('Username or email').value).to eq(group_invite.invite_email) + end - it 'sign in, grants access and redirects to group page' do - click_link 'Sign in' + it 'pre-fills the Email field on the sign up box with the invite_email from the invite' do + expect(find_field('Email').value).to eq(group_invite.invite_email) + end + end - fill_in_sign_in_form(user) + context 'when invite is sent before account is created - ldap or social sign in for manual acceptance edge case' do + let(:user) { create(:user, email: 'user@example.com') } - expect(current_path).to eq(group_path(group)) - expect(page).to have_content('You have been granted Developer access to group Owned.') - end - end + context 'when invite clicked and not signed in' do + before do + visit invite_path(group_invite.raw_invite_token) + end - context 'when signed in as an existing member' do - before do - sign_in(owner) - end + it 'sign in, grants access and redirects to group activity page' do + click_link 'Sign in' - it 'shows message user already a member' do - visit invite_path(group_invite.raw_invite_token) + fill_in_sign_in_form(user) + + expect(current_path).to eq(activity_group_path(group)) + end + end + + context 'when signed in and an invite link is clicked' do + context 'when an invite email is a secondary email for the user' do + let(:invite_email) { 'user_secondary@example.com' } + + before do + sign_in(user) + visit invite_path(group_invite.raw_invite_token) + end + + it 'sends user to the invite url and allows them to decline' do + expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(page).to have_content("Note that this invitation was sent to #{invite_email}") + expect(page).to have_content("but you are signed in as #{user.to_reference} with email #{user.email}") + + click_link('Decline') + + expect(page).to have_content('You have declined the invitation') + expect(current_path).to eq(dashboard_projects_path) + expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound + end + + it 'sends uer to the invite url and allows them to accept' do + expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(page).to have_content("Note that this invitation was sent to #{invite_email}") + expect(page).to have_content("but you are signed in as #{user.to_reference} with email #{user.email}") + + click_link('Accept invitation') + + expect(page).to have_content('You have been granted') + expect(current_path).to eq(activity_group_path(group)) + end + end + + context 'when user is an existing member' do + before do + sign_in(owner) + visit invite_path(group_invite.raw_invite_token) + end + + it 'shows message user already a member' do + expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(page).to have_link(owner.name, href: user_url(owner)) + expect(page).to have_content('However, you are already a member of this group.') + end + end + end + + context 'when declining the invitation from invitation reminder email' do + context 'when signed in' do + before do + sign_in(user) + visit decline_invite_path(group_invite.raw_invite_token) + end + + it 'declines application and redirects to dashboard' do + expect(current_path).to eq(dashboard_projects_path) + expect(page).to have_content('You have declined the invitation to join group Owned.') + expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound + end + end + + context 'when signed out with signup onboarding' do + before do + visit decline_invite_path(group_invite.raw_invite_token) + end - expect(page).to have_link(owner.name, href: user_url(owner)) - expect(page).to have_content('However, you are already a member of this group.') + it 'declines application and redirects to sign in page' do + expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token)) + expect(page).not_to have_content('You have declined the invitation to join') + expect(page).to have_content('You successfully declined the invitation') + expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound + end + end + end + end end end @@ -91,12 +171,15 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do let(:new_user) { build_stubbed(:user) } let(:invite_email) { new_user.email } let(:group_invite) { create(:group_member, :invited, group: group, invite_email: invite_email, created_by: owner) } - let!(:project_invite) { create(:project_member, :invited, project: project, invite_email: invite_email) } + let(:send_email_confirmation) { true } + + before do + stub_application_setting(send_user_confirmation_email: send_email_confirmation) + end context 'when registering using invitation email' do before do - stub_application_setting(send_user_confirmation_email: send_email_confirmation) - visit invite_path(group_invite.raw_invite_token) + visit invite_path(group_invite.raw_invite_token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE) end context 'with admin approval required enabled' do @@ -104,8 +187,6 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do stub_application_setting(require_admin_approval_after_user_signup: true) end - let(:send_email_confirmation) { true } - it 'does not sign the user in' do fill_in_sign_up_form(new_user) @@ -117,79 +198,42 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do context 'email confirmation disabled' do let(:send_email_confirmation) { false } - it 'signs up and redirects to the dashboard page with all the projects/groups invitations automatically accepted' do + it 'signs up and redirects to the most recent membership activity page with all the projects/groups invitations automatically accepted' do fill_in_sign_up_form(new_user) fill_in_welcome_form - expect(current_path).to eq(dashboard_projects_path) - expect(page).to have_content(project.full_name) - - visit group_path(group) - - expect(page).to have_content(group.full_name) + expect(current_path).to eq(activity_group_path(group)) + expect(page).to have_content('You have been granted Owner access to group Owned.') end context 'the user sign-up using a different email address' do let(:invite_email) { build_stubbed(:user).email } - it 'signs up and redirects to the invitation page' do + it 'signs up and redirects to the activity page' do fill_in_sign_up_form(new_user) fill_in_welcome_form - expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(current_path).to eq(activity_group_path(group)) end end end context 'email confirmation enabled' do - let(:send_email_confirmation) { true } - - context 'when soft email confirmation is not enabled' do - before do - allow(User).to receive(:allow_unconfirmed_access_for).and_return 0 - end + context 'with members/invite_email experiment', :experiment do + it 'tracks the accepted invite' do + expect(experiment('members/invite_email')).to track(:accepted) + .with_context(actor: group_invite) + .on_next_instance - it 'signs up and redirects to root page with all the project/groups invitation automatically accepted' do fill_in_sign_up_form(new_user) - confirm_email(new_user) - fill_in_sign_in_form(new_user) - fill_in_welcome_form - - expect(current_path).to eq(root_path) - expect(page).to have_content(project.full_name) - - visit group_path(group) - - expect(page).to have_content(group.full_name) end end - context 'when soft email confirmation is enabled' do - before do - allow(User).to receive(:allow_unconfirmed_access_for).and_return 2.days - end - - it 'signs up and redirects to root page with all the project/groups invitation automatically accepted' do - fill_in_sign_up_form(new_user) - fill_in_welcome_form - confirm_email(new_user) - - expect(current_path).to eq(root_path) - expect(page).to have_content(project.full_name) - - visit group_path(group) - - expect(page).to have_content(group.full_name) - end - end - - it "doesn't accept invitations until the user confirms their email" do + it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do fill_in_sign_up_form(new_user) fill_in_welcome_form - sign_in(owner) - visit project_project_members_path(project) - expect(page).to have_content 'Invited' + expect(current_path).to eq(activity_group_path(group)) end context 'the user sign-up using a different email address' do @@ -201,13 +245,13 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do allow(User).to receive(:allow_unconfirmed_access_for).and_return 0 end - it 'signs up and redirects to the invitation page' do + it 'signs up and redirects to the group activity page' do fill_in_sign_up_form(new_user) confirm_email(new_user) fill_in_sign_in_form(new_user) fill_in_welcome_form - expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(current_path).to eq(activity_group_path(group)) end end @@ -217,78 +261,75 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do allow(User).to receive(:allow_unconfirmed_access_for).and_return 2.days end - it 'signs up and redirects to the invitation page' do + it 'signs up and redirects to the group activity page' do fill_in_sign_up_form(new_user) fill_in_welcome_form - expect(current_path).to eq(invite_path(group_invite.raw_invite_token)) + expect(current_path).to eq(activity_group_path(group)) end end end end end - context 'when declining the invitation' do - let(:send_email_confirmation) { true } + context 'with invite_signup_page_interaction experiment on', :experiment do + context 'with control experience' do + before do + stub_experiments(invite_signup_page_interaction: :control) + end - context 'as an existing user' do - let(:group_invite) { create(:group_member, user: user, group: group, created_by: owner) } + it 'lands on invite sign up page and tracks the accepted invite' do + expect(experiment(:invite_signup_page_interaction)).to track(:view) + .with_context(actor: group_invite) + .on_next_instance - context 'when signed in' do - before do - sign_in(user) - visit decline_invite_path(group_invite.raw_invite_token) - end + visit invite_path(group_invite.raw_invite_token) - it 'declines application and redirects to dashboard' do - expect(current_path).to eq(dashboard_projects_path) - expect(page).to have_content('You have declined the invitation to join group Owned.') - expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound - end - end + expect(current_path).to eq(new_user_registration_path) - context 'when signed out' do - before do - visit decline_invite_path(group_invite.raw_invite_token) - end + expect(experiment(:invite_signup_page_interaction)).to track(:form_submission) + .with_context(actor: group_invite) + .on_next_instance - it 'declines application and redirects to sign in page' do - expect(current_path).to eq(new_user_session_path) - expect(page).to have_content('You have declined the invitation to join group Owned.') - expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound - end + fill_in_sign_up_form(new_user, 'Register') + + expect(current_path).to eq(users_sign_up_welcome_path) end end - context 'as a non-existing user' do + context 'with candidate experience on .com' do before do - visit decline_invite_path(group_invite.raw_invite_token) + allow(Gitlab).to receive(:dev_env_or_com?).and_return(true) + stub_experiments(invite_signup_page_interaction: :candidate) end - it 'declines application and shows a decline page' do - expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token)) - expect(page).to have_content('You successfully declined the invitation') - expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound - end - end - end + it 'lands on invite sign up page and tracks the accepted invite' do + expect(experiment(:invite_signup_page_interaction)).to track(:view) + .with_context(actor: group_invite) + .on_next_instance - context 'when accepting the invitation' do - let(:send_email_confirmation) { true } + visit invite_path(group_invite.raw_invite_token) - before do - sign_in(user) - visit invite_path(group_invite.raw_invite_token) - end + expect(current_path).to eq(new_users_sign_up_invite_path) + + expect(experiment(:invite_signup_page_interaction)).to track(:form_submission) + .with_context(actor: group_invite) + .on_next_instance + + fill_in_sign_up_form(new_user, 'Continue') - it 'grants access and redirects to group page' do - expect(group.users.include?(user)).to be false + expect(current_path).to eq(users_sign_up_welcome_path) + end + end + end - page.click_link 'Accept invitation' + context 'when declining the invitation from invitation reminder email' do + it 'declines application and shows a decline page' do + visit decline_invite_path(group_invite.raw_invite_token) - expect(current_path).to eq(group_path(group)) - expect(page).to have_content('You have been granted Owner access to group Owned.') - expect(group.users.include?(user)).to be true + expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token)) + expect(page).to have_content('You successfully declined the invitation') + expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound end end end |