From 705d07f60e09d377c68009132fb17923e91e97b5 Mon Sep 17 00:00:00 2001 From: zmagod Date: Wed, 13 Sep 2017 17:11:51 +0200 Subject: [PATCH] adds remove team action --- .../client_api/teams/teams_controller.rb | 1 - .../client_api/users/user_teams_controller.rb | 13 +++ app/javascript/packs/app/routes.js | 1 + app/javascript/packs/locales/messages.js | 9 ++ .../team/SettingsTeamPageContainer.jsx | 2 +- .../team/components/RemoveUserModal.jsx | 99 +++++++++++++++++++ .../team/components/TeamsMembers.jsx | 37 ++++++- app/services/client_api/user_team_service.rb | 4 +- config/routes.rb | 1 + ...oller.rb => user_teams_controller_spec.rb} | 0 .../client_api/user_team_service_spec.rb | 56 +++++++++++ 11 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 app/javascript/packs/src/settings/components/team/components/RemoveUserModal.jsx rename spec/controllers/client_api/users/{user_teams_controller.rb => user_teams_controller_spec.rb} (100%) create mode 100644 spec/services/client_api/user_team_service_spec.rb diff --git a/app/controllers/client_api/teams/teams_controller.rb b/app/controllers/client_api/teams/teams_controller.rb index 45e295bc0..c38ae0fad 100644 --- a/app/controllers/client_api/teams/teams_controller.rb +++ b/app/controllers/client_api/teams/teams_controller.rb @@ -31,7 +31,6 @@ module ClientApi current_user: current_user, params: team_params) team_service.update_team! - success_response('/client_api/teams/update_details', team_service.single_team_details_data) rescue ClientApi::CustomTeamError => error diff --git a/app/controllers/client_api/users/user_teams_controller.rb b/app/controllers/client_api/users/user_teams_controller.rb index 5ad2ad18d..bf66fa4ff 100644 --- a/app/controllers/client_api/users/user_teams_controller.rb +++ b/app/controllers/client_api/users/user_teams_controller.rb @@ -29,6 +29,19 @@ module ClientApi unsuccess_response(error.to_s) end + def remove_user + ut_service = ClientApi::UserTeamService.new( + user: current_user, + team_id: params[:team], + user_team_id: params[:user_team] + ) + ut_service.destroy_user_team_and_assign_new_team_owner! + success_response('/client_api/teams/team_users', + ut_service.team_users_data) + rescue ClientApi::CustomUserTeamError => error + unsuccess_response(error.to_s) + end + private def success_response(template, locals) diff --git a/app/javascript/packs/app/routes.js b/app/javascript/packs/app/routes.js index dec11c714..4d8f1dae9 100644 --- a/app/javascript/packs/app/routes.js +++ b/app/javascript/packs/app/routes.js @@ -27,6 +27,7 @@ export const CONTACT_US_LINK = // user teams export const LEAVE_TEAM_PATH = "/client_api/users/leave_team"; export const UPDATE_USER_TEAM_ROLE_PATH = "/client_api/users/update_role"; +export const REMOVE_USER_FROM_TEAM_PATH = "/client_api/users/remove_user"; // settings export const SETTINGS_ACCOUNT_PROFILE = "/settings/account/profile"; diff --git a/app/javascript/packs/locales/messages.js b/app/javascript/packs/locales/messages.js index 9989ee23f..548a26733 100644 --- a/app/javascript/packs/locales/messages.js +++ b/app/javascript/packs/locales/messages.js @@ -70,6 +70,15 @@ export default { warning_message_three: "all repository protocols in the team belonging to you will be reassigned onto a new owner from team administrators.", leave_team: "Leave" }, + remove_user_modal: { + title: "Remove user {user} from team {team}", + subtitle: "Are you sure you wish to remove user {user} from team {team}?", + warnings: "Removing user from team has following consequences:", + warning_message_one: "user will lose access to all content belonging to the team (including projects, tasks, protocols and activities);", + warning_message_two: "all projects in the team where user was the sole Owner will be reassigned onto you as a new owner;", + warning_message_three: "all repository protocols in the team belonging to user will be reassigned onto you.", + remove_user: "Remove user" + }, update_team_description_modal: { title: "Edit team description", label: "Description" diff --git a/app/javascript/packs/src/settings/components/team/SettingsTeamPageContainer.jsx b/app/javascript/packs/src/settings/components/team/SettingsTeamPageContainer.jsx index eb19963d4..921af9d21 100644 --- a/app/javascript/packs/src/settings/components/team/SettingsTeamPageContainer.jsx +++ b/app/javascript/packs/src/settings/components/team/SettingsTeamPageContainer.jsx @@ -163,7 +163,7 @@ class SettingsTeamPageContainer extends Component { { + this.props.updateUsersCallback(response.data.team_users); + this.props.hideModal(); + }) + .catch(error => console.log(error)); + } + + render() { + const { teamName, userName } = this.props.userToRemove; + return ( + + + + + + + +

+ +

+ +   + +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+ + + + +
+ ); + } +} + +RemoveUserModal.propTypes = { + showModal: bool.isRequired, + hideModal: func.isRequired, + userToRemove: PropTypes.shape({ + userName: string.isRequired, + team_user_id: number.isRequired, + teamName: string.isRequired, + team_id: number.isRequired + }).isRequired, + updateUsersCallback: func.isRequired +}; + +export default RemoveUserModal; diff --git a/app/javascript/packs/src/settings/components/team/components/TeamsMembers.jsx b/app/javascript/packs/src/settings/components/team/components/TeamsMembers.jsx index 8d71dbce4..510067d8b 100644 --- a/app/javascript/packs/src/settings/components/team/components/TeamsMembers.jsx +++ b/app/javascript/packs/src/settings/components/team/components/TeamsMembers.jsx @@ -10,13 +10,22 @@ import { import { FormattedMessage } from "react-intl"; import axios from "../../../../../app/axios"; +import RemoveUserModal from "./RemoveUserModal"; import DataTable from "../../../../../shared/data_table"; import { UPDATE_USER_TEAM_ROLE_PATH } from "../../../../../app/routes"; +const initalUserToRemove = { + userName: "", + team_user_id: 0, + teamName: "", + team_id: 0 +}; class TeamsMembers extends Component { constructor(params) { super(params); + this.state = { showModal: false, userToRemove: initalUserToRemove }; this.memberAction = this.memberAction.bind(this); + this.hideModal = this.hideModal.bind(this); } currentRole(memberRole, role) { @@ -26,7 +35,7 @@ class TeamsMembers extends Component { updateRole(userTeamId, role) { axios .put(UPDATE_USER_TEAM_ROLE_PATH, { - team: this.props.teamId, + team: this.props.team.id, user_team: userTeamId, role }) @@ -36,7 +45,13 @@ class TeamsMembers extends Component { .catch(error => console.log(error)); } - removeUser(userTeamId) {} + hideModal() { + this.setState({ showModal: false, userToRemove: initalUserToRemove }); + } + + userToRemove(userToRemove) { + this.setState({ showModal: true, userToRemove }); + } memberAction(data, row) { return ( @@ -83,7 +98,12 @@ class TeamsMembers extends Component { { - this.removeUser(data.team_user_id); + this.userToRemove({ + userName: row.name, + team_user_id: data.team_user_id, + teamName: this.props.team.name, + team_id: this.props.team.id + }); }} > @@ -155,6 +175,12 @@ class TeamsMembers extends Component { + ); } @@ -162,7 +188,10 @@ class TeamsMembers extends Component { TeamsMembers.propTypes = { updateUsersCallback: func.isRequired, - teamId: number.isRequired, + team: PropTypes.shape({ + id: number.isRequired, + name: string.isRequired + }).isRequired, members: PropTypes.arrayOf( PropTypes.shape({ id: number.isRequired, diff --git a/app/services/client_api/user_team_service.rb b/app/services/client_api/user_team_service.rb index e9764e1ca..d101a331e 100644 --- a/app/services/client_api/user_team_service.rb +++ b/app/services/client_api/user_team_service.rb @@ -9,10 +9,10 @@ module ClientApi @user = parsed_args.fetch(:user) @user_team = UserTeam.find_by_id(parsed_args.fetch(:user_team_id).to_i) @role = args.fetch(:role) { false } - raise ClientApi::CustomUserTeamError unless @user_team && @user && @team end def destroy_user_team_and_assign_new_team_owner! + binding.pry raise ClientApi::CustomUserTeamError unless user_cant_leave? new_owner = @team.user_teams .where(role: 2) @@ -59,7 +59,7 @@ module ClientApi end def user_cant_leave? - @user.teams.includes @team && + @user.teams.includes(@team) && @user_team.admin? && @team.user_teams.where(role: 2).count <= 1 end diff --git a/config/routes.rb b/config/routes.rb index d3f87d562..2315114a9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -29,6 +29,7 @@ Rails.application.routes.draw do get '/current_user_info', to: 'users#current_user_info' namespace :users do + delete '/remove_user', to: 'user_teams#remove_user' delete '/leave_team', to: 'user_teams#leave_team' put '/update_role', to: 'user_teams#update_role' end diff --git a/spec/controllers/client_api/users/user_teams_controller.rb b/spec/controllers/client_api/users/user_teams_controller_spec.rb similarity index 100% rename from spec/controllers/client_api/users/user_teams_controller.rb rename to spec/controllers/client_api/users/user_teams_controller_spec.rb diff --git a/spec/services/client_api/user_team_service_spec.rb b/spec/services/client_api/user_team_service_spec.rb new file mode 100644 index 000000000..d6d87cf11 --- /dev/null +++ b/spec/services/client_api/user_team_service_spec.rb @@ -0,0 +1,56 @@ +require 'rails_helper' + +describe ClientApi::UserTeamService do + let(:team_one) { create :team } + let(:user_one) { create :user, email: Faker::Internet.email } + let(:user_team) { create :user_team, user: user_one, team: team_one } + + it 'should raise ClientApi::CustomUserTeamError if user is not assigned' do + expect { + ClientApi::UserTeamService.new( + team_id: team_one.id, + user_team_id: user_team.id + ) + }.to raise_error(ClientApi::CustomUserTeamError) + end + + it 'should raise ClientApi::CustomUserTeamError if team is not assigned' do + expect { + ClientApi::UserTeamService.new(user: user_one, user_team_id: user_team.id) + }.to raise_error(ClientApi::CustomUserTeamError) + end + + it 'should raise ClientApi::CustomUserTeamError if ' \ + 'user_team is not assigned' do + expect { + ClientApi::UserTeamService.new(user: user_one, team_id: team_one.id) + }.to raise_error(ClientApi::CustomUserTeamError) + end + + describe '#destroy_user_team_and_assign_new_team_owner!' do + let(:user_two) { create :user, email: Faker::Internet.email } + + it 'should raise ClientApi::CustomUserTeamError if user ' \ + 'can\'t leave the team' do + ut_service = ClientApi::UserTeamService.new( + team_id: team_one.id, + user_team_id: user_team.id, + user: user_one + ) + expect { + ut_service.destroy_user_team_and_assign_new_team_owner! + }.to raise_error(ClientApi::CustomUserTeamError) + end + + it 'should destroy the user_team relation' do + new_user_team = create :user_team, team: team_one, user: user_two + ut_service = ClientApi::UserTeamService.new( + team_id: team_one.id, + user_team_id: new_user_team.id, + user: user_two + ) + ut_service.destroy_user_team_and_assign_new_team_owner! + expect(new_user_team).to_not exist + end + end +end