diff --git a/app/controllers/project_comments_controller.rb b/app/controllers/project_comments_controller.rb
index 03b4e22e4..b0d789c00 100644
--- a/app/controllers/project_comments_controller.rb
+++ b/app/controllers/project_comments_controller.rb
@@ -51,17 +51,7 @@ class ProjectCommentsController < ApplicationController
respond_to do |format|
if @comment.save
project_comment_annotation_notification
- # Generate activity
- Activity.create(
- type_of: :add_comment_to_project,
- user: current_user,
- project: @project,
- message: t(
- 'activities.add_comment_to_project',
- user: current_user.full_name,
- project: @project.name
- )
- )
+ log_activity(:add_comment_to_project)
format.json {
render json: {
@@ -107,19 +97,9 @@ class ProjectCommentsController < ApplicationController
respond_to do |format|
format.json do
if @comment.save
-
project_comment_annotation_notification(old_text)
- # Generate activity
- Activity.create(
- type_of: :edit_project_comment,
- user: current_user,
- project: @project,
- message: t(
- 'activities.edit_project_comment',
- user: current_user.full_name,
- project: @project.name
- )
- )
+ log_activity(:edit_project_comment)
+
message = custom_auto_link(@comment.message, team: current_team)
render json: { comment: message }, status: :ok
else
@@ -134,17 +114,8 @@ class ProjectCommentsController < ApplicationController
respond_to do |format|
format.json do
if @comment.destroy
- # Generate activity
- Activity.create(
- type_of: :delete_project_comment,
- user: current_user,
- project: @project,
- message: t(
- 'activities.delete_project_comment',
- user: current_user.full_name,
- project: @project.name
- )
- )
+ log_activity(:delete_project_comment)
+
# 'counter' and 'linked_id' are used for counter badge
render json: { linked_id: @project.id,
counter: @project.project_comments.count },
@@ -198,4 +169,14 @@ class ProjectCommentsController < ApplicationController
project: link_to(@project.name, project_url(@project)))
)
end
+
+ def log_activity(type_of)
+ Activities::CreateActivityService
+ .call(activity_type: type_of,
+ owner: current_user,
+ subject: @project,
+ team: @project.team,
+ project: @project,
+ message_items: { project: @project.id })
+ end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index eac0a39af..e171cf911 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -102,14 +102,7 @@ class ProjectsController < ApplicationController
project: @project
)
up.save
-
- Activities::CreateActivityService
- .call(activity_type: :create_project,
- owner: current_user,
- subject: @project,
- team: @project.team,
- project: @project,
- message_items: { project: @project.id })
+ log_activity(:create_project)
message = t('projects.create.success_flash', name: @project.name)
respond_to do |format|
@@ -164,43 +157,32 @@ class ProjectsController < ApplicationController
message_visibility = nil
if (project_params.include? :name) &&
(project_params[:name] != @project.name)
- message_renamed = t(
- 'activities.rename_project',
- user: current_user.full_name,
- project_old: @project.name,
- project_new: project_params[:name]
- )
+ message_renamed = true
end
if (project_params.include? :visibility) &&
(project_params[:visibility] != @project.visibility)
- message_visibility = t(
- 'activities.change_project_visibility',
- user: current_user.full_name,
- project: @project.name,
- visibility: project_params[:visibility] == "visible" ?
- t("general.public") :
- t("general.private")
- )
+ message_visibility = if project_params[:visibility] == 'visible'
+ t('projects.activity.visibility_visible')
+ else
+ t('projects.activity.visibility_hidden')
+ end
end
@project.last_modified_by = current_user
if !return_error && @project.update(project_params)
# Add activities if needed
if message_visibility.present?
- Activity.create(
- type_of: :change_project_visibility,
- user: current_user,
- project: @project,
- message: message_visibility
- )
+ Activities::CreateActivityService
+ .call(activity_type: :change_project_visibility,
+ owner: current_user,
+ subject: @project,
+ team: @project.team,
+ project: @project,
+ message_items: { project: @project.id,
+ visibility: message_visibility })
end
if message_renamed.present?
- Activity.create(
- type_of: :rename_project,
- owner: current_user,
- project: @project,
- message: message_renamed
- )
+ log_activity(:rename_project)
end
flash_success = t('projects.update.success_flash', name: @project.name)
@@ -216,34 +198,12 @@ class ProjectsController < ApplicationController
# The project should be restored
unless @project.archived
@project.restore(current_user)
-
- # "Restore project" activity
- Activity.create(
- type_of: :restore_project,
- user: current_user,
- project: @project,
- message: t(
- 'activities.restore_project',
- user: current_user.full_name,
- project: @project.name
- )
- )
+ log_activity(:restore_project)
end
elsif @project.archived
# The project should be archived
@project.archive(current_user)
-
- # "Archive project" activity
- Activity.create(
- type_of: :archive_project,
- user: current_user,
- project: @project,
- message: t(
- 'activities.archive_project',
- user: current_user.full_name,
- project: @project.name
- )
- )
+ log_activity(:archive_project)
end
redirect_to projects_path
flash[:success] = flash_success
@@ -388,4 +348,14 @@ class ProjectsController < ApplicationController
def check_manage_permissions
render_403 unless can_manage_project?(@project)
end
+
+ def log_activity(type_of)
+ Activities::CreateActivityService
+ .call(activity_type: type_of,
+ owner: current_user,
+ subject: @project,
+ team: @project.team,
+ project: @project,
+ message_items: { project: @project.id })
+ end
end
diff --git a/app/controllers/user_projects_controller.rb b/app/controllers/user_projects_controller.rb
index f9fcd219e..fafa0aaac 100644
--- a/app/controllers/user_projects_controller.rb
+++ b/app/controllers/user_projects_controller.rb
@@ -52,19 +52,7 @@ class UserProjectsController < ApplicationController
@up.assigned_by = current_user
if @up.save
- # Generate activity
- Activity.create(
- type_of: :assign_user_to_project,
- user: current_user,
- project: @project,
- message: t(
- "activities.assign_user_to_project",
- assigned_user: @up.user.full_name,
- role: @up.role_str,
- project: @project.name,
- assigned_by_user: current_user.full_name
- )
- )
+ log_activity(:assign_user_to_project)
respond_to do |format|
format.json do
@@ -90,19 +78,7 @@ class UserProjectsController < ApplicationController
@up.role = up_params[:role]
if @up.save
- # Generate activity
- Activity.create(
- type_of: :change_user_role_on_project,
- user: current_user,
- project: @project,
- message: t(
- "activities.change_user_role_on_project",
- actor: current_user.full_name,
- user: @up.user.full_name,
- project: @project.name,
- role: @up.role_str
- )
- )
+ log_activity(:change_user_role_on_project)
respond_to do |format|
format.json do
@@ -123,20 +99,12 @@ class UserProjectsController < ApplicationController
def destroy
if @up.destroy
- # Generate activity
- Activity.create(
- type_of: :unassign_user_from_project,
- user: current_user,
- project: @project,
- message: t(
- "activities.unassign_user_from_project",
- unassigned_user: @up.user.full_name,
- project: @project.name,
- unassigned_by_user: current_user.full_name
- )
- )
- generate_notification(current_user, @up.user, false, false, @project)
-
+ log_activity(:unassign_user_from_project)
+ generate_notification(current_user,
+ @up.user,
+ false,
+ @up.role_str,
+ @project)
respond_to do |format|
format.json do
redirect_to project_users_edit_path(format: :json),
@@ -191,4 +159,16 @@ class UserProjectsController < ApplicationController
def up_params
params.require(:user_project).permit(:user_id, :project_id, :role)
end
+
+ def log_activity(type_of)
+ Activities::CreateActivityService
+ .call(activity_type: type_of,
+ owner: current_user,
+ subject: @project,
+ team: @project.team,
+ project: @project,
+ message_items: { project: @project.id,
+ user_target: @up.user.id,
+ role: @up.role_str })
+ end
end
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index f41eb90ac..c834a56b5 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -32,9 +32,10 @@ module NotificationsHelper
message = "#{I18n.t('search.index.team')} #{team.name}"
elsif project
title = I18n.t('activities.unassign_user_from_project',
- unassigned_user: target_user.full_name,
+ user_target: target_user.full_name,
project: project.name,
- unassigned_by_user: user.full_name)
+ user: user.full_name,
+ role: role)
message = "#{I18n.t('search.index.project')} #{@project.name}"
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2f5322d16..85e0902cf 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -319,6 +319,9 @@ en:
users: "Users"
experiments: "Experiments"
tasks: "Tasks"
+ activity:
+ visibility_hidden: "Project members only"
+ visibility_visible: "All team members"
create:
success_flash: "Project %{name} successfully created."
update:
@@ -1314,13 +1317,13 @@ en:
modal:
modal_title: "Activities"
create_project: "%{user} created project %{project}."
- rename_project: "%{user} renamed project %{project_old} to %{project_new}."
+ rename_project: "%{user} renamed project %{project}."
change_project_visibility: "%{user} changed project %{project}'s visibility to %{visibility}."
archive_project: "%{user} moved project %{project} to archive."
restore_project: "%{user} restored project %{project} from archive."
- assign_user_to_project: "%{assigned_user} was added as %{role} to project %{project} by %{assigned_by_user}."
- change_user_role_on_project: "%{actor} changed %{user}'s role on project %{project} to %{role}."
- unassign_user_from_project: "%{unassigned_user} was removed from project %{project} by %{unassigned_by_user}."
+ assign_user_to_project: "%{user} assigned user %{user_target} with user role %{role} to project %{project}."
+ change_user_role_on_project: "%{user} changed %{user_target}'s role on project %{project} to %{role}."
+ unassign_user_from_project: "%{user} removed user %{user_target} with user role %{role} from project %{project}."
create_module: "%{user} created task %{module}."
assign_user_to_module: "%{assigned_user} was added to task %{module} by %{assigned_by_user}."
unassign_user_from_module: "%{unassigned_user} was removed from task %{module} by %{unassigned_by_user}."
diff --git a/spec/controllers/project_comments_controller_spec.rb b/spec/controllers/project_comments_controller_spec.rb
new file mode 100644
index 000000000..121b9491d
--- /dev/null
+++ b/spec/controllers/project_comments_controller_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe ProjectCommentsController, type: :controller do
+ login_user
+
+ let(:user) { User.first }
+ let(:team) { create :team, created_by: user }
+ let(:user_team) { create :user_team, team: team, user: user }
+ let(:user_project) { create :user_project, :owner, user: user }
+ let(:project) do
+ create :project, team: team, user_projects: [user_project]
+ end
+ let(:project_comment) do
+ create :project_comment, project: project, user: user
+ end
+
+ describe '#create' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ comment: { message: 'test message' } }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :add_comment_to_project))
+
+ post :create, params: params, format: :json
+ end
+ end
+ end
+
+ describe '#update' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ id: project_comment.id,
+ comment: { message: 'test message updated' } }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :edit_project_comment))
+
+ put :update, params: params, format: :json
+ end
+ end
+ end
+
+ describe '#destroy' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ id: project_comment.id }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :delete_project_comment))
+
+ delete :destroy, params: params, format: :json
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 9fe134e77..0db6dfaf2 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -150,8 +150,8 @@ describe ProjectsController, type: :controller do
context 'in HTML format' do
let(:params) do
{ id: project_1.id,
- project: { name: 'test project A1', team_id: team.id,
- visibility: 'visible' } }
+ project: { name: project_1.name, team_id: project_1.team.id,
+ visibility: project_1.visibility } }
end
it 'returns redirect response' do
@@ -159,6 +159,39 @@ describe ProjectsController, type: :controller do
expect(response).to have_http_status(:redirect)
expect(response.content_type).to eq 'text/html'
end
+
+ it 'calls create activity service (change_project_visibility)' do
+ params[:project][:visibility] = 'hidden'
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :change_project_visibility))
+
+ put :update, params: params
+ end
+
+ it 'calls create activity service (rename_project)' do
+ params[:project][:name] = 'test project changed'
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :rename_project))
+
+ put :update, params: params
+ end
+
+ it 'calls create activity service (restore_project)' do
+ project_1.update(archived: true)
+ params[:project][:archived] = false
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :restore_project))
+
+ put :update, params: params
+ end
+
+ it 'calls create activity service (archive_project)' do
+ params[:project][:archived] = true
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :archive_project))
+
+ put :update, params: params
+ end
end
end
diff --git a/spec/controllers/user_projects_controller_spec.rb b/spec/controllers/user_projects_controller_spec.rb
new file mode 100644
index 000000000..fe409ff46
--- /dev/null
+++ b/spec/controllers/user_projects_controller_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe UserProjectsController, type: :controller do
+ login_user
+
+ let(:user) { User.first }
+ let(:user_two) { create :user }
+ let(:target_user) { create :user }
+ let!(:team) { create :team, created_by: user }
+ let!(:user_team) { create :user_team, team: team, user: user }
+ let(:user_project) { create :user_project, :owner, user: user }
+ let(:target_user_project) do
+ create :user_project, :normal_user, user: target_user
+ end
+ let(:project) do
+ create :project, team: team, user_projects: [user_project,
+ target_user_project]
+ end
+
+ describe '#create' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ user_project: { user_id: user_two.id,
+ project_id: project.id,
+ role: :owner } }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :assign_user_to_project))
+
+ post :create, params: params, format: :json
+ end
+ end
+ end
+
+ describe '#update' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ id: target_user_project.id,
+ user_project: { user_id: target_user.id,
+ project_id: project.id,
+ role: :viewer } }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :change_user_role_on_project))
+
+ put :update, params: params, format: :json
+ end
+ end
+ end
+
+ describe '#destroy' do
+ context 'in JSON format' do
+ let(:params) do
+ { project_id: project.id,
+ id: target_user_project.id }
+ end
+
+ it 'calls create activity service' do
+ expect(Activities::CreateActivityService).to receive(:call)
+ .with(hash_including(activity_type: :unassign_user_from_project))
+
+ delete :destroy, params: params, format: :json
+ end
+ end
+ end
+end
diff --git a/spec/factories/project_comments.rb b/spec/factories/project_comments.rb
new file mode 100644
index 000000000..3e0d3992a
--- /dev/null
+++ b/spec/factories/project_comments.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :project_comment do
+ user
+ project
+ message { Faker::Lorem.sentence }
+ end
+end