OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/spec/controllers/users_controller_spec.rb

992 lines
28 KiB

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
require 'spec_helper'
require 'work_package'
describe UsersController, type: :controller do
shared_let(:admin) { FactoryBot.create :admin }
shared_let(:anonymous) { User.anonymous }
shared_let(:user_password) { 'bob!' * 4 }
shared_let(:user) do
FactoryBot.create :user,
login: 'bob',
password: user_password,
password_confirmation: user_password
end
describe 'GET new' do
context "without user limit reached" do
before do
as_logged_in_user admin do
get :new
end
end
it 'is success' do
expect(response)
.to have_http_status(200)
end
it 'renders the template' do
expect(response)
.to have_rendered('new')
end
it 'have a user object initialized' do
expect(assigns(:user))
.to be_a(User)
end
end
context "with user limit reached" do
before do
allow(OpenProject::Enterprise).to receive(:user_limit_reached?).and_return(true)
end
context "with fail fast" do
before do
allow(OpenProject::Enterprise).to receive(:fail_fast?).and_return(true)
as_logged_in_user admin do
get :new
end
end
it "shows a user limit error" do
expect(flash[:error]).to match /user limit reached/i
end
it "redirects back to the user index" do
expect(response).to redirect_to users_path
end
end
context "without fail fast" do
before do
as_logged_in_user admin do
get :new
end
end
it "shows a user limit warning" do
expect(flash[:warning]).to match /user limit reached/i
end
it "shows the new user page" do
expect(response).to render_template("users/new")
end
end
end
end
describe 'GET deletion_info' do
describe "WHEN the current user is the requested user
WHEN the setting users_deletable_by_self is set to true" do
let(:params) { { 'id' => user.id.to_s } }
before do
allow(Setting).to receive(:users_deletable_by_self?).and_return(true)
as_logged_in_user user do
get :deletion_info, params: params
end
end
it do
expect(response).to be_successful
end
it do
expect(assigns(:user)).to eq(user)
end
it { expect(response).to render_template('deletion_info') }
end
describe "WHEN the current user is the requested user
WHEN the setting users_deletable_by_self is set to false" do
let(:params) { { 'id' => user.id.to_s } }
before do
allow(Setting).to receive(:users_deletable_by_self?).and_return(false)
as_logged_in_user user do
get :deletion_info, params: params
end
end
it { expect(response.response_code).to eq(404) }
end
describe 'WHEN the current user is the anonymous user' do
let(:params) { { 'id' => anonymous.id.to_s } }
before do
as_logged_in_user anonymous do
get :deletion_info, params: params
end
end
it {
expect(response).to redirect_to(controller: 'account',
action: 'login',
back_url: @controller.url_for(controller: 'users',
action: 'deletion_info'))
}
end
describe "WHEN the current user is admin
WHEN the setting users_deletable_by_admins is set to true" do
let(:params) { { 'id' => user.id.to_s } }
before do
allow(Setting).to receive(:users_deletable_by_admins?).and_return(true)
as_logged_in_user admin do
get :deletion_info, params: params
end
end
it do
expect(response).to be_successful
end
it do
expect(assigns(:user)).to eq(user)
end
it { expect(response).to render_template('deletion_info') }
end
describe "WHEN the current user is admin
WHEN the setting users_deletable_by_admins is set to false" do
let(:params) { { 'id' => user.id.to_s } }
before do
allow(Setting).to receive(:users_deletable_by_admins?).and_return(false)
as_logged_in_user admin do
get :deletion_info, params: params
end
end
it { expect(response.response_code).to eq(404) }
end
end
describe 'POST resend_invitation' do
let(:invited_user) { FactoryBot.create :invited_user }
context 'without admin rights' do
let(:normal_user) { FactoryBot.create :user }
before do
as_logged_in_user normal_user do
post :resend_invitation, params: { id: invited_user.id }
end
end
it 'returns 403 forbidden' do
expect(response.status).to eq 403
end
end
context 'with admin rights' do
before do
expect(ActionMailer::Base.deliveries).to be_empty
as_logged_in_user admin do
perform_enqueued_jobs do
post :resend_invitation, params: { id: invited_user.id }
end
end
end
it 'redirects back to the edit user page' do
expect(response).to redirect_to edit_user_path(invited_user)
end
it 'sends another activation email' do
mail = ActionMailer::Base.deliveries.first.body.parts.first.body.to_s
token = Token::Invitation.find_by user_id: invited_user.id
expect(mail).to include 'activate your account'
expect(mail).to include token.value
end
end
end
describe 'GET edit' do
before do
as_logged_in_user admin do
get :edit, params: { id: user.id }
end
end
it 'is success' do
expect(response)
.to have_http_status(200)
end
it 'renders the template' do
expect(response)
.to have_rendered('edit')
end
it 'have a user object initialized' do
expect(assigns(:user))
.to eql user
end
end
describe 'POST destroy' do
let(:base_params) { { 'id' => user.id.to_s, back_url: my_account_path } }
context 'WHEN the password confirmation is missing' do
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_self?).and_return(true)
as_logged_in_user user do
post :destroy, params: base_params
end
end
it do
expect(response).to redirect_to(controller: 'my', action: 'account')
end
it { expect(flash[:error]).to eq(I18n.t(:notice_password_confirmation_failed)) }
end
context 'WHEN password confirmation is present' do
let(:base_params) do
{ 'id' => user.id.to_s, :_password_confirmation => user_password, back_url: my_account_path }
end
describe "WHEN the current user is the requested one
WHEN the setting users_deletable_by_self is set to true" do
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_self?).and_return(true)
as_logged_in_user user do
post :destroy, params: base_params
end
end
it do
expect(response).to redirect_to(controller: 'account', action: 'login')
end
it { expect(flash[:notice]).to eq(I18n.t('account.deleted')) }
end
describe "WHEN the current user is the requested one
WHEN the setting users_deletable_by_self is set to false" do
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_self?).and_return(false)
as_logged_in_user user do
post :destroy, params: base_params
end
end
it { expect(response.response_code).to eq(404) }
end
describe "WHEN the current user is the anonymous user
EVEN when the setting login_required is set to false" do
before do
allow(@controller).to receive(:find_current_user).and_return(anonymous)
allow(Setting).to receive(:login_required?).and_return(false)
as_logged_in_user anonymous do
post :destroy, params: base_params.merge(id: anonymous.id.to_s)
end
end
# redirecting post is not possible for now
it { expect(response.response_code).to eq(403) }
end
describe "WHEN the current user is the admin
WHEN the given password does not match
WHEN the setting users_deletable_by_admins is set to true" do
shared_let(:admin) { FactoryBot.create :admin }
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_admins?).and_return(true)
as_logged_in_user admin do
post :destroy, params: base_params
end
end
it 'redirects with error' do
expect(response).to redirect_to(controller: 'my', action: 'account')
expect(flash[:notice]).to eq(nil)
expect(flash[:error]).to eq(I18n.t(:notice_password_confirmation_failed))
end
end
describe "WHEN the current user is the admin
WHEN the given password does match
WHEN the setting users_deletable_by_admins is set to true" do
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_admins?).and_return(true)
as_logged_in_user admin do
post :destroy, params: base_params.merge('_password_confirmation': 'adminADMIN!')
end
end
it do
expect(response).to redirect_to(controller: 'users', action: 'index')
end
it { expect(flash[:notice]).to eq(I18n.t('account.deleted')) }
end
describe "WHEN the current user is the admin
WHEN the setting users_deletable_by_admins is set to false" do
shared_let(:admin) { FactoryBot.create :admin }
before do
disable_flash_sweep
allow(Setting).to receive(:users_deletable_by_admins).and_return(false)
as_logged_in_user admin do
post :destroy, params: base_params
end
end
it { expect(response.response_code).to eq(404) }
end
end
end
describe '#change_status_info' do
let!(:registered_user) do
FactoryBot.create(:user, status: User.statuses[:registered])
end
before do
as_logged_in_user admin do
get :change_status_info,
params: {
id: registered_user.id,
change_action: change_action
}
end
end
shared_examples 'valid status info' do
it 'renders the status info' do
expect(response).to be_successful
expect(response).to render_template 'users/change_status_info'
expect(assigns(:user)).to eq(registered_user)
expect(assigns(:status_change)).to eq(change_action)
end
end
describe 'with valid activate' do
let(:change_action) { :activate }
it_behaves_like 'valid status info'
end
describe 'with valid unlock' do
let(:change_action) { :unlock }
it_behaves_like 'valid status info'
end
describe 'with valid lock' do
let(:change_action) { :lock }
it_behaves_like 'valid status info'
end
describe 'bogus status' do
let(:change_action) { :wtf }
it 'renders 400' do
expect(response.status).to eq(400)
expect(response).not_to render_template 'users/change_status_info'
end
end
end
describe '#change_status',
with_settings: {
available_languages: %i(en de),
bcc_recipients: 1
} do
describe 'WHEN activating a registered user' do
let!(:registered_user) do
FactoryBot.create(:user, status: User.statuses[:registered],
language: 'de')
end
let(:user_limit_reached) { false }
before do
allow(OpenProject::Enterprise).to receive(:user_limit_reached?).and_return(user_limit_reached)
as_logged_in_user admin do
post :change_status,
params: {
id: registered_user.id,
user: { status: User.statuses[:active] },
activate: '1'
}
end
end
it 'should activate the user' do
assert registered_user.reload.active?
end
it 'should send an email to the correct user in the correct language' do
5 years ago
perform_enqueued_jobs
mail = ActionMailer::Base.deliveries.last
refute_nil mail
assert_equal [registered_user.mail], mail.to
mail.parts.each do |part|
assert part.body.encoded.include?(I18n.t(:notice_account_activated,
locale: 'de'))
end
end
context "with user limit reached" do
let(:user_limit_reached) { true }
it "shows the user limit reached error and recommends to upgrade" do
expect(flash[:error]).to match /user limit reached.*upgrade/i
end
it "does not activate the user" do
expect(registered_user.reload).not_to be_active
end
end
end
end
describe 'GET #index' do
let(:params) { {} }
before do
as_logged_in_user admin do
get :index, params: params
end
end
it 'to be success' do
expect(response)
.to have_http_status(200)
end
it 'renders the index' do
expect(response)
.to have_rendered('index')
end
it 'assigns users' do
expect(assigns(:users))
.to match_array([user, admin])
end
context 'with a name filter' do
let(:params) { { name: user.firstname } }
it 'assigns users' do
expect(assigns(:users))
.to match_array([user])
end
end
context 'with a group filter' do
let(:group) { FactoryBot.create(:group, members: [user]) }
let(:params) do
{ group_id: group.id }
end
it 'assigns users' do
expect(assigns(:users))
.to match_array([user])
end
end
end
describe 'session lifetime' do
# TODO move this section to a proper place because we test a
# before_action from the application controller
after(:each) do
# reset, so following tests are not affected by the change
User.current = nil
end
shared_examples_for 'index action with disabled session lifetime or inactivity not exceeded' do
it "doesn't logout the user and renders the index action" do
expect(User.current).to eq(admin)
expect(response).to render_template 'index'
end
end
shared_examples_for 'index action with enabled session lifetime and inactivity exceeded' do
it 'logs out the user and redirects with a warning that he has been locked out' do
expect(response.redirect_url).to eq(signin_url + '?back_url=' + CGI::escape(@controller.url_for(controller: 'users',
action: 'index')))
expect(User.current).not_to eq(admin)
expect(flash[:warning]).to eq(I18n.t(:notice_forced_logout, ttl_time: Setting.session_ttl))
end
end
context 'disabled' do
before do
allow(Setting).to receive(:session_ttl_enabled?).and_return(false)
@controller.send(:logged_user=, admin)
get :index
end
it_should_behave_like 'index action with disabled session lifetime or inactivity not exceeded'
end
context 'enabled ' do
before do
allow(Setting).to receive(:session_ttl_enabled?).and_return(true)
allow(Setting).to receive(:session_ttl).and_return('120')
@controller.send(:logged_user=, admin)
end
context 'before 120 min of inactivity' do
before do
session[:updated_at] = Time.now - 1.hours
get :index
end
it_should_behave_like 'index action with disabled session lifetime or inactivity not exceeded'
end
context 'after 120 min of inactivity' do
before do
session[:updated_at] = Time.now - 3.hours
get :index
end
it_should_behave_like 'index action with enabled session lifetime and inactivity exceeded'
end
context 'without last activity time in the session' do
before do
allow(Setting).to receive(:session_ttl).and_return('60')
session[:updated_at] = nil
get :index
end
it_should_behave_like 'index action with enabled session lifetime and inactivity exceeded'
end
context 'with ttl = 0' do
before do
allow(Setting).to receive(:session_ttl).and_return('0')
session[:updated_at] = Time.now - 1.hours
get :index
end
it_should_behave_like 'index action with disabled session lifetime or inactivity not exceeded'
end
context 'with ttl < 0' do
before do
allow(Setting).to receive(:session_ttl).and_return('-60')
session[:updated_at] = Time.now - 1.hours
get :index
end
it_should_behave_like 'index action with disabled session lifetime or inactivity not exceeded'
end
context 'with ttl < 5 > 0' do
before do
allow(Setting).to receive(:session_ttl).and_return('4')
session[:updated_at] = Time.now - 1.hours
get :index
end
it_should_behave_like 'index action with disabled session lifetime or inactivity not exceeded'
end
end
end
describe 'PATCH #update' do
context 'fields' do
current_user { admin }
let(:user) do
[26688] In-app notifications (#9399) * Add bell icon to icon font * Add in app notification in top menu * Add fullscreen modal * Add notification modal and items * Style items * Toggle details of item * Mark all read * Add no results box * wip specification for event api * Add events table, query and index * Send out events from WP notification mailer job There we have the recipients present * Add cleanup job for older events with a setting * Hide bell notification when not logged * Add specs for events API index/show * Fix setting yml key * remove pry in event creation * Fix before hook in events API to after_validation * Fix polymorphic association raising exception for aggregated journals * Fix typo in read_ian * Fix yml entry for mentioned * Add read/unread post actions to event API and add specs * Wire up API to frontend * Fix order on events * Switch to unread in notification * Add event query * rename WPEventService * route wp mail sending over events * rename spec methods * author becomes watcher * correct message call signature * rename events to notifications * renname parameter to reflect notification nature * create author watcher for existing work packages * Merge unreadCount from store * Take a stab at polymorphic representers * Fix link generation in polymorphic resources For journals, no title is being generated however * Fix frontend model for context * Use timer for polling * add notification_setting data layer * Fix show resource spec * Fix duplicate class in notification bell item * Add minimal feature spec for notification * API for notification settings * Persist notifications * adapt work package notification creation to notification settings * extract notified_on_all * consolidate wp#recipients * concentrate wp notification in journal service * simplify methods * Remove unused patch endpoint * Add specs for rendering and parsing notification settings * Contract spec * Update service spec * adapt specs * Angular notifications frontend commit e29dced64699eb5f2443b9307c78343c9a58d1ee Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 17:34:50 2021 +0200 Create Akita store and query for notification settings commit 1a45c26c1a0c147d15393e49d2625aca4851a64d Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 11:09:25 2021 +0200 Remove tabs from notificaition settings page commit 0ea21e90c13a197f8bf2cfba1b60ddcff4e5e827 Author: Oliver Günther <mail@oliverguenther.de> Date: Sun Jun 20 21:55:48 2021 +0200 WIP in app settings * migrate notification data * add project visible filter to project query * Add inline-create and table display grouped by project * Add notifications under admin/users * Remove notifications partial * Rename notififcations store to user preferences store * Add setting for self_notified and hook that up to the backend * Add aria-label to table checkboxes * Restyle table and toolbar * replace remains of mail_notifications attribute * initialize notification settings for new user * adapt my_preferences references * reenable no self notified for documents * adapt specs * Avoid has_many :notifcation_settings Rails magically autosaves the user's preferences when the user gets saved, which somehow also tries to save the notfifications even when unchanged. This breaks some specs such as the avatar upload spec. As we can't update the assocation through rails anyway, just delegate to the user for reading instead. * Restore update method of notification settings * Restore update spec * fix spec syntax * lint scss * linting * Fix content_tag for bell icon * Add feature specs for notification settings * Disable ContentTag cop * use visible filter to get projects for notification The visible filter will reduce the project list down to the set of projects visible to the user provided as a parameter. This includes public projects. * test for actual mail sending * adapt me resource path this.apiV3Service.users.me changed its type in 0d6c0b6bc7620de94e00e72b36d6cbc1ec4c8db4 * Implement changed migration * Linting * Add actor to notification representer * Fix factory creating a duplicate WP journal * Add work packages loading and journal details to notification entry component * IAN basic facets, keep and expanded states. * Fix notification bell spec * Render body separately and add auto updating relative time * Add fixedTime title * Add actor to notification entry * Fix clicking links on work package and project * Tiny styling changes on entry row * Disable count in notification if larger than 99 (wont fit) * Introduce virtual scrolling to entry table * allow delaying & prevent mail sending if ain read Introduces a setting to delay mail sending after a journal aggregation time has expired. That way, users can confirm a notification in app. If they do before the delay expires, no mail is sent out additionally for that user. * consolidate notifications (in&out) into shared admin menu Co-authored-by: ulferts <jens.ulferts@googlemail.com> Co-authored-by: Wieland Lindenthal <w.lindenthal@forkmerge.com>
3 years ago
FactoryBot.create(:user,
firstname: 'Firstname',
admin: true,
[26688] In-app notifications (#9399) * Add bell icon to icon font * Add in app notification in top menu * Add fullscreen modal * Add notification modal and items * Style items * Toggle details of item * Mark all read * Add no results box * wip specification for event api * Add events table, query and index * Send out events from WP notification mailer job There we have the recipients present * Add cleanup job for older events with a setting * Hide bell notification when not logged * Add specs for events API index/show * Fix setting yml key * remove pry in event creation * Fix before hook in events API to after_validation * Fix polymorphic association raising exception for aggregated journals * Fix typo in read_ian * Fix yml entry for mentioned * Add read/unread post actions to event API and add specs * Wire up API to frontend * Fix order on events * Switch to unread in notification * Add event query * rename WPEventService * route wp mail sending over events * rename spec methods * author becomes watcher * correct message call signature * rename events to notifications * renname parameter to reflect notification nature * create author watcher for existing work packages * Merge unreadCount from store * Take a stab at polymorphic representers * Fix link generation in polymorphic resources For journals, no title is being generated however * Fix frontend model for context * Use timer for polling * add notification_setting data layer * Fix show resource spec * Fix duplicate class in notification bell item * Add minimal feature spec for notification * API for notification settings * Persist notifications * adapt work package notification creation to notification settings * extract notified_on_all * consolidate wp#recipients * concentrate wp notification in journal service * simplify methods * Remove unused patch endpoint * Add specs for rendering and parsing notification settings * Contract spec * Update service spec * adapt specs * Angular notifications frontend commit e29dced64699eb5f2443b9307c78343c9a58d1ee Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 17:34:50 2021 +0200 Create Akita store and query for notification settings commit 1a45c26c1a0c147d15393e49d2625aca4851a64d Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 11:09:25 2021 +0200 Remove tabs from notificaition settings page commit 0ea21e90c13a197f8bf2cfba1b60ddcff4e5e827 Author: Oliver Günther <mail@oliverguenther.de> Date: Sun Jun 20 21:55:48 2021 +0200 WIP in app settings * migrate notification data * add project visible filter to project query * Add inline-create and table display grouped by project * Add notifications under admin/users * Remove notifications partial * Rename notififcations store to user preferences store * Add setting for self_notified and hook that up to the backend * Add aria-label to table checkboxes * Restyle table and toolbar * replace remains of mail_notifications attribute * initialize notification settings for new user * adapt my_preferences references * reenable no self notified for documents * adapt specs * Avoid has_many :notifcation_settings Rails magically autosaves the user's preferences when the user gets saved, which somehow also tries to save the notfifications even when unchanged. This breaks some specs such as the avatar upload spec. As we can't update the assocation through rails anyway, just delegate to the user for reading instead. * Restore update method of notification settings * Restore update spec * fix spec syntax * lint scss * linting * Fix content_tag for bell icon * Add feature specs for notification settings * Disable ContentTag cop * use visible filter to get projects for notification The visible filter will reduce the project list down to the set of projects visible to the user provided as a parameter. This includes public projects. * test for actual mail sending * adapt me resource path this.apiV3Service.users.me changed its type in 0d6c0b6bc7620de94e00e72b36d6cbc1ec4c8db4 * Implement changed migration * Linting * Add actor to notification representer * Fix factory creating a duplicate WP journal * Add work packages loading and journal details to notification entry component * IAN basic facets, keep and expanded states. * Fix notification bell spec * Render body separately and add auto updating relative time * Add fixedTime title * Add actor to notification entry * Fix clicking links on work package and project * Tiny styling changes on entry row * Disable count in notification if larger than 99 (wont fit) * Introduce virtual scrolling to entry table * allow delaying & prevent mail sending if ain read Introduces a setting to delay mail sending after a journal aggregation time has expired. That way, users can confirm a notification in app. If they do before the delay expires, no mail is sent out additionally for that user. * consolidate notifications (in&out) into shared admin menu Co-authored-by: ulferts <jens.ulferts@googlemail.com> Co-authored-by: Wieland Lindenthal <w.lindenthal@forkmerge.com>
3 years ago
login: 'testlogin',
force_password_change: false)
end
let(:params) do
{
id: user.id,
user: {
admin: false,
firstname: 'Changed',
login: 'changedlogin',
force_password_change: true
},
pref: {
hide_mail: '1',
comments_sorting: 'desc'
}
}
end
before do
perform_enqueued_jobs do
put :update, params: params
end
end
it 'should redirect to the edit page' do
expect(response).to redirect_to(edit_user_url(user))
end
it 'should be assigned their new values' do
user_from_db = User.find(user.id)
expect(user_from_db.admin).to be_falsey
expect(user_from_db.firstname).to eql('Changed')
expect(user_from_db.login).to eql('changedlogin')
expect(user_from_db.force_password_change).to eql(true)
expect(user_from_db.pref[:hide_mail]).to be_truthy
expect(user_from_db.pref[:comments_sorting]).to eql('desc')
end
it 'sends no mail' do
expect(ActionMailer::Base.deliveries.empty?).to be_truthy
end
context 'when updating the password' do
let(:params) do
{
id: user.id,
user: { password: 'newpassPASS!',
password_confirmation: 'newpassPASS!' },
send_information: '1'
}
end
it 'sends a mail' do
mail = ActionMailer::Base.deliveries.last
expect(mail.to)
.to match_array [user.mail]
expect(mail.body.encoded)
.to include('newpassPASS!')
end
end
context 'with invalid params' do
let(:params) do
{
id: user.id,
user: {
firstname: ''
}
}
end
it 'is success' do
expect(response)
.to have_http_status(200)
end
it 'renders the edit template' do
expect(response)
.to have_rendered('edit')
end
end
end
context 'with external authentication' do
let(:user) { FactoryBot.create(:user, identity_url: 'some:identity') }
before do
as_logged_in_user(admin) do
put :update, params: { id: user.id, user: { force_password_change: 'true' } }
end
user.reload
end
it 'should ignore setting force_password_change' do
expect(user.force_password_change).to eql(false)
end
end
context 'ldap auth source' do
let(:ldap_auth_source) { FactoryBot.create(:ldap_auth_source) }
it 'switchting to internal authentication on a password change' do
user.auth_source = ldap_auth_source
as_logged_in_user admin do
put :update,
params: {
id: user.id,
user: { auth_source_id: '', password: 'newpassPASS!',
password_confirmation: 'newpassPASS!' }
}
end
expect(user.reload.auth_source).to be_nil
expect(user.check_password?('newpassPASS!')).to be_truthy
end
end
context 'with disabled_password_choice' do
before do
expect(OpenProject::Configuration).to receive(:disable_password_choice?).and_return(true)
end
it 'ignores password parameters and leaves the password unchanged' do
as_logged_in_user(admin) do
put :update,
params: {
id: user.id,
user: { password: 'changedpass!', password_confirmation: 'changedpass!' }
}
end
expect(user.reload.check_password?('changedpass!')).to be false
end
end
end
describe 'Anonymous should not be able to create a user' do
it 'should redirect to the login page' do
post :create,
params: {
user: {
login: 'psmith',
firstname: 'Paul',
lastname: 'Smith'
},
password: 'psmithPSMITH09',
password_confirmation: 'psmithPSMITH09'
}
expect(response).to redirect_to '/login?back_url=http%3A%2F%2Ftest.host%2Fusers'
end
end
describe 'GET #show' do
describe 'general' do
let(:current_user) { user }
let(:params) { { id: user.id } }
11 years ago
before do
as_logged_in_user current_user do
get :show, params: params
11 years ago
end
end
it 'responds with success' do
expect(response).to be_successful
11 years ago
end
it 'renders the show template' do
11 years ago
expect(response).to render_template 'show'
end
it 'assigns @user' do
11 years ago
expect(assigns(:user)).to eq(user)
end
context 'when not being logged in' do
let(:current_user) { User.anonymous }
it 'responds with 404' do
expect(response)
.to have_http_status(404)
end
end
context 'when the user is locked for an admin' do
let(:current_user) do
user.locked!
admin
end
it 'responds with 200' do
expect(response)
.to have_http_status(200)
end
end
context 'when the user is locked for an non admin' do
let(:current_user) do
user.locked!
FactoryBot.create(:user)
end
it 'responds with 200' do
expect(response)
.to have_http_status(404)
end
end
context 'for the current user' do
let(:params) { { id: 'current' } }
it 'responds with 200' do
expect(response)
.to have_http_status(200)
end
it 'assigns the user' do
expect(assigns(:user))
.to eq(user)
end
end
end
11 years ago
describe 'for user with Activity' do
render_views
let(:work_package) do
FactoryBot.create(:work_package,
author: user)
end
let!(:member) do
FactoryBot.create(:member,
project: work_package.project,
principal: user,
roles: [FactoryBot.create(:role,
permissions: [:view_work_packages])])
end
let!(:journal_1) do
FactoryBot.create(:work_package_journal,
user: user,
journable_id: work_package.id,
version: Journal.maximum(:version) + 1,
data: FactoryBot.build(:journal_work_package_journal,
subject: work_package.subject,
status_id: work_package.status_id,
type_id: work_package.type_id,
project_id: work_package.project_id))
end
let!(:journal_2) do
FactoryBot.create(:work_package_journal,
user: user,
journable_id: work_package.id,
version: Journal.maximum(:version) + 1,
data: FactoryBot.build(:journal_work_package_journal,
subject: work_package.subject,
status_id: work_package.status_id,
type_id: work_package.type_id,
project_id: work_package.project_id))
end
11 years ago
before do
allow(User).to receive(:current).and_return(user.reload)
allow_any_instance_of(User).to receive(:reported_work_package_count).and_return(42)
11 years ago
get :show, params: { id: user.id }
end
11 years ago
it 'should include the number of reported work packages' do
label = Regexp.escape(I18n.t(:label_reported_work_packages))
expect(response.body).to have_selector('p', text: /#{label}.*42/)
end
it 'should have @events_by_day grouped by day' do
expect(assigns(:events_by_day).keys.first.class).to eq(Date)
end
it 'should have more than one event for today' do
expect(assigns(:events_by_day).first.size).to be > 1
end
end
end
describe 'POST #create' do
current_user { admin }
let(:params) do
{
user: {
firstname: 'John',
lastname: 'Doe',
login: 'jdoe',
password: 'adminADMIN!',
password_confirmation: 'adminADMIN!',
[26688] In-app notifications (#9399) * Add bell icon to icon font * Add in app notification in top menu * Add fullscreen modal * Add notification modal and items * Style items * Toggle details of item * Mark all read * Add no results box * wip specification for event api * Add events table, query and index * Send out events from WP notification mailer job There we have the recipients present * Add cleanup job for older events with a setting * Hide bell notification when not logged * Add specs for events API index/show * Fix setting yml key * remove pry in event creation * Fix before hook in events API to after_validation * Fix polymorphic association raising exception for aggregated journals * Fix typo in read_ian * Fix yml entry for mentioned * Add read/unread post actions to event API and add specs * Wire up API to frontend * Fix order on events * Switch to unread in notification * Add event query * rename WPEventService * route wp mail sending over events * rename spec methods * author becomes watcher * correct message call signature * rename events to notifications * renname parameter to reflect notification nature * create author watcher for existing work packages * Merge unreadCount from store * Take a stab at polymorphic representers * Fix link generation in polymorphic resources For journals, no title is being generated however * Fix frontend model for context * Use timer for polling * add notification_setting data layer * Fix show resource spec * Fix duplicate class in notification bell item * Add minimal feature spec for notification * API for notification settings * Persist notifications * adapt work package notification creation to notification settings * extract notified_on_all * consolidate wp#recipients * concentrate wp notification in journal service * simplify methods * Remove unused patch endpoint * Add specs for rendering and parsing notification settings * Contract spec * Update service spec * adapt specs * Angular notifications frontend commit e29dced64699eb5f2443b9307c78343c9a58d1ee Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 17:34:50 2021 +0200 Create Akita store and query for notification settings commit 1a45c26c1a0c147d15393e49d2625aca4851a64d Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 11:09:25 2021 +0200 Remove tabs from notificaition settings page commit 0ea21e90c13a197f8bf2cfba1b60ddcff4e5e827 Author: Oliver Günther <mail@oliverguenther.de> Date: Sun Jun 20 21:55:48 2021 +0200 WIP in app settings * migrate notification data * add project visible filter to project query * Add inline-create and table display grouped by project * Add notifications under admin/users * Remove notifications partial * Rename notififcations store to user preferences store * Add setting for self_notified and hook that up to the backend * Add aria-label to table checkboxes * Restyle table and toolbar * replace remains of mail_notifications attribute * initialize notification settings for new user * adapt my_preferences references * reenable no self notified for documents * adapt specs * Avoid has_many :notifcation_settings Rails magically autosaves the user's preferences when the user gets saved, which somehow also tries to save the notfifications even when unchanged. This breaks some specs such as the avatar upload spec. As we can't update the assocation through rails anyway, just delegate to the user for reading instead. * Restore update method of notification settings * Restore update spec * fix spec syntax * lint scss * linting * Fix content_tag for bell icon * Add feature specs for notification settings * Disable ContentTag cop * use visible filter to get projects for notification The visible filter will reduce the project list down to the set of projects visible to the user provided as a parameter. This includes public projects. * test for actual mail sending * adapt me resource path this.apiV3Service.users.me changed its type in 0d6c0b6bc7620de94e00e72b36d6cbc1ec4c8db4 * Implement changed migration * Linting * Add actor to notification representer * Fix factory creating a duplicate WP journal * Add work packages loading and journal details to notification entry component * IAN basic facets, keep and expanded states. * Fix notification bell spec * Render body separately and add auto updating relative time * Add fixedTime title * Add actor to notification entry * Fix clicking links on work package and project * Tiny styling changes on entry row * Disable count in notification if larger than 99 (wont fit) * Introduce virtual scrolling to entry table * allow delaying & prevent mail sending if ain read Introduces a setting to delay mail sending after a journal aggregation time has expired. That way, users can confirm a notification in app. If they do before the delay expires, no mail is sent out additionally for that user. * consolidate notifications (in&out) into shared admin menu Co-authored-by: ulferts <jens.ulferts@googlemail.com> Co-authored-by: Wieland Lindenthal <w.lindenthal@forkmerge.com>
3 years ago
mail: 'jdoe@gmail.com'
},
pref: {}
}
end
before do
perform_enqueued_jobs do
post :create, params: params
end
end
it 'is successful' do
expect(response)
.to redirect_to edit_user_path(User.newest.first)
end
it 'creates the user with the provided params' do
expect(User.newest.first.attributes.with_indifferent_access.slice(:firstname, :lastname, :login, :mail))
.to eql params[:user].with_indifferent_access.slice(:firstname, :lastname, :login, :mail)
end
it 'sends an activation mail' do
mail = ActionMailer::Base.deliveries.last
expect(mail.to)
.to match_array [params[:user][:mail]]
activation_link = Regexp.new(
"http://#{Setting.host_name}/account/activate\\?token=[a-f0-9]+",
Regexp::MULTILINE
)
assert(mail.body.encoded =~ activation_link)
end
context 'with invalid parameters' do
let(:params) { { user: { login: 'jdoe' } } }
it 'renders new' do
expect(response)
.to render_template 'new'
end
end
end
end