Feature/send custom message from invite modal (#9222)

* fix malformed i18n key

* sent custom message from invite modal

* cleanup imports
pull/9223/head
ulferts 4 years ago committed by GitHub
parent 022321b560
commit b50298eb30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/views/member_mailer/added_project.text.erb
  2. 5
      frontend/src/app/modules/apiv3/endpoints/memberships/apiv3-memberships-form.ts
  3. 8
      frontend/src/app/modules/apiv3/endpoints/memberships/apiv3-memberships-paths.ts
  4. 3
      frontend/src/app/modules/hal/resources/membership-resource.ts
  5. 3
      frontend/src/app/modules/invite-user-modal/summary/summary.component.ts
  6. 4
      frontend/src/typings/open-project.typings.d.ts
  7. 109
      spec/features/users/invite_user_modal_spec.rb

@ -1,5 +1,5 @@
<%=
I18n.t(:"mail_member_added_project.body.added_by#{@message.present? ? 'with_message' : 'without_message'}",
I18n.t(:"mail_member_added_project.body.added_by.#{@message.present? ? 'with_message' : 'without_message'}",
project: @project.name,
user: User.current.name)
%>

@ -47,6 +47,11 @@ export class Apiv3MembershipsForm extends APIv3FormResource {
project: { href: resource.project.href },
principal: { href: resource.principal.href },
roles: resource.roles.map(role => ({ href: role.href })),
},
_meta: {
notificationMessage: {
raw: resource.notificationMessage.raw
}
}
}
}

@ -34,17 +34,9 @@ import {
Apiv3ListResourceInterface, listParamsString
} from "core-app/modules/apiv3/paths/apiv3-list-resource.interface";
import {Observable} from "rxjs";
import {HalResource} from "core-app/modules/hal/resources/hal-resource";
import {CollectionResource} from "core-app/modules/hal/resources/collection-resource";
import {MembershipResource, MembershipResourceEmbedded} from "core-app/modules/hal/resources/membership-resource";
import {ProjectResource} from 'core-app/modules/hal/resources/project-resource';
import {UserResource} from "core-app/modules/hal/resources/user-resource";
import {GroupResource} from "core-app/modules/hal/resources/group-resource";
import {PlaceholderUserResource} from "core-app/modules/hal/resources/placeholder-user-resource";
import {RoleResource} from 'core-app/modules/hal/resources/role-resource';
import {Apiv3MembershipsForm} from "core-app/modules/apiv3/endpoints/memberships/apiv3-memberships-form";
import {SchemaResource} from "core-app/modules/hal/resources/schema-resource";
import {map, switchMap} from "rxjs/operators";
export class Apiv3MembershipsPaths

@ -27,9 +27,9 @@
//++
import { HalResource } from 'core-app/modules/hal/resources/hal-resource';
import { UserResource } from "core-app/modules/hal/resources/user-resource";
import { RoleResource } from "core-app/modules/hal/resources/role-resource";
import { ProjectResource } from "core-app/modules/hal/resources/project-resource";
import Formattable = api.v3.Formattable;
export interface MembershipResourceLinks {
update(payload:unknown):Promise<unknown>;
@ -41,6 +41,7 @@ export interface MembershipResourceEmbedded {
principal:HalResource;
roles:RoleResource[];
project:ProjectResource;
notificationMessage:Formattable;
}
export class MembershipResource extends HalResource {

@ -71,6 +71,9 @@ export class SummaryComponent {
principal,
project: this.project,
roles: [this.role],
notificationMessage: {
raw: this.message
}
})
.pipe(
mapTo(principal)

@ -57,9 +57,9 @@ declare namespace api {
}
interface Formattable {
format:string;
format?:string;
raw:string;
html:string;
html?:string;
}
}
}

@ -35,28 +35,33 @@ feature 'Invite user modal', type: :feature, js: true do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
let(:global_permissions) { %i[] }
current_user do
FactoryBot.create :user,
member_in_project: project,
member_through_role: role,
global_permissions: global_permissions
let(:modal) do
::Components::Users::InviteUserModal.new project: project,
principal: principal,
role: role,
invite_message: invite_message
end
let!(:role) do
FactoryBot.create :role,
name: 'Member',
permissions: permissions
end
let(:invite_message) { "Welcome to the team. **You'll like it here**."}
let(:mail_membership_recipients) { [] }
let(:mail_invite_recipients) { [] }
let(:modal) do
::Components::Users::InviteUserModal.new project: project,
principal: principal,
role: role
current_user do
FactoryBot.create :user,
member_in_project: project,
member_through_role: role,
global_permissions: global_permissions
end
shared_examples 'invites the principal to the project' do
it 'will invite that principal to the project' do
modal.run_all_steps
it 'invites that principal to the project' do
perform_enqueued_jobs do
modal.run_all_steps
end
assignee_field.expect_inactive!
assignee_field.expect_display_value added_principal.name
@ -64,6 +69,32 @@ feature 'Invite user modal', type: :feature, js: true do
new_member = project.reload.member_principals.find_by(user_id: added_principal.id)
expect(new_member).to be_present
expect(new_member.roles).to eq [role]
# Check that the expected number of emails are sent.
# This includes no mails being sent if the recipient list is empty.
expect(ActionMailer::Base.deliveries.size)
.to eql mail_invite_recipients.size + mail_membership_recipients.size
mail_invite_recipients.each_with_index do |recipient, index|
expect(ActionMailer::Base.deliveries[index].to)
.to match_array [recipient.mail]
expect(ActionMailer::Base.deliveries[index].body.encoded)
.to include "Welcome to OpenProject"
end
mail_membership_recipients.each_with_index do |recipient, index|
overall_index = index + mail_invite_recipients.length
expect(ActionMailer::Base.deliveries[overall_index].to)
.to match_array [recipient.mail]
expect(ActionMailer::Base.deliveries[overall_index].body.encoded)
.to include OpenProject::TextFormatting::Renderer.format_text(invite_message)
expect(ActionMailer::Base.deliveries[overall_index].body.encoded)
.to include role.name
end
end
end
@ -81,20 +112,15 @@ feature 'Invite user modal', type: :feature, js: true do
end
context 'with an existing user' do
let!(:principal) { FactoryBot.create :user,
firstname: 'Nonproject firstname',
lastname: 'nonproject lastname'
}
it 'can add an existing user to the project' do
modal.run_all_steps
assignee_field.expect_inactive!
assignee_field.expect_display_value principal.name
# But the user got created
new_member = project.reload.members.find_by(user_id: principal.id)
expect(new_member).to be_present
expect(new_member.roles).to eq [role]
let!(:principal) do
FactoryBot.create :user,
firstname: 'Nonproject firstname',
lastname: 'nonproject lastname'
end
it_behaves_like 'invites the principal to the project' do
let(:added_principal) { principal }
let(:mail_membership_recipients) { [principal] }
end
end
@ -107,6 +133,8 @@ feature 'Invite user modal', type: :feature, js: true do
it_behaves_like 'invites the principal to the project' do
let(:added_principal) { User.find_by!(mail: principal.mail) }
let(:mail_invite_recipients) { [added_principal] }
let(:mail_membership_recipients) { [added_principal] }
end
end
@ -114,7 +142,7 @@ feature 'Invite user modal', type: :feature, js: true do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
it 'does not show the invite user option' do
modal.project_step
ngselect = modal.open_select_in_step principal.mail
ngselect = modal.open_select_in_step principal.mail
expect(ngselect).to have_text "No users were found"
expect(ngselect).not_to have_text "Invite: #{principal.mail}"
end
@ -125,15 +153,17 @@ feature 'Invite user modal', type: :feature, js: true do
let(:global_permissions) { %i[manage_user] }
let(:project_no_permissions) { FactoryBot.create :project }
let(:role_no_permissions) { FactoryBot.create :role,
permissions: %i[view_work_packages edit_work_packages]
}
let!(:membership_no_permission) {
let(:role_no_permissions) do
FactoryBot.create :role,
permissions: %i[view_work_packages edit_work_packages]
end
let!(:membership_no_permission) do
FactoryBot.create :member,
user: current_user,
project: project_no_permissions,
roles: [role_no_permissions]
}
user: current_user,
project: project_no_permissions,
roles: [role_no_permissions]
end
it 'disables projects for which you do not have rights' do
ngselect = modal.open_select_in_step
@ -153,6 +183,8 @@ feature 'Invite user modal', type: :feature, js: true do
it_behaves_like 'invites the principal to the project' do
let(:added_principal) { PlaceholderUser.find_by!(name: 'MY NEW PLACEHOLDER') }
# Placeholders get no invite mail
let(:mail_membership_recipients) { [] }
end
end
@ -173,6 +205,8 @@ feature 'Invite user modal', type: :feature, js: true do
it_behaves_like 'invites the principal to the project' do
let(:added_principal) { principal }
# Placeholders get no invite mail
let(:mail_membership_recipients) { [] }
end
end
end
@ -187,10 +221,13 @@ feature 'Invite user modal', type: :feature, js: true do
end
describe 'inviting groups' do
let(:principal) { FactoryBot.create :group, name: 'MY NEW GROUP' }
let(:group_user) { FactoryBot.create(:user) }
let(:principal) { FactoryBot.create :group, name: 'MY NEW GROUP', members: [group_user] }
it_behaves_like 'invites the principal to the project' do
let(:added_principal) { principal }
# Groups get no invite mail themselves but their members do
let(:mail_membership_recipients) { [group_user] }
end
end
end

Loading…
Cancel
Save