mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: Invite emails to groups from add member modal (#10308)
This commit is contained in:
committed by
GitHub
parent
413fa49032
commit
b76731d722
@@ -4,42 +4,101 @@ import Controller from "@ember/controller";
|
|||||||
import { extractError } from "discourse/lib/ajax-error";
|
import { extractError } from "discourse/lib/ajax-error";
|
||||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { emailValid } from "discourse/lib/utilities";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default Controller.extend(ModalFunctionality, {
|
export default Controller.extend(ModalFunctionality, {
|
||||||
loading: false,
|
loading: false,
|
||||||
setAsOwner: false,
|
setAsOwner: false,
|
||||||
|
notifyUsers: false,
|
||||||
|
usernamesAndEmails: null,
|
||||||
|
usernames: null,
|
||||||
|
emails: null,
|
||||||
|
|
||||||
@discourseComputed("model.usernames", "loading")
|
onShow() {
|
||||||
disableAddButton(usernames, loading) {
|
this.setProperties({
|
||||||
return loading || !usernames || !(usernames.length > 0);
|
usernamesAndEmails: "",
|
||||||
|
usernames: [],
|
||||||
|
emails: [],
|
||||||
|
setAsOwner: false,
|
||||||
|
notifyUsers: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("usernamesAndEmails", "loading")
|
||||||
|
disableAddButton(usernamesAndEmails, loading) {
|
||||||
|
return loading || !usernamesAndEmails || !(usernamesAndEmails.length > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("usernamesAndEmails")
|
||||||
|
emailsPresent() {
|
||||||
|
this._splitEmailsAndUsernames();
|
||||||
|
return this.emails.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("usernamesAndEmails")
|
||||||
|
notifyUsersDisabled() {
|
||||||
|
this._splitEmailsAndUsernames();
|
||||||
|
return this.usernames.length === 0 && this.emails.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("model.name", "model.full_name")
|
||||||
|
title(name, fullName) {
|
||||||
|
return I18n.t("groups.add_members.title", { group_name: fullName || name });
|
||||||
},
|
},
|
||||||
|
|
||||||
@action
|
@action
|
||||||
addMembers() {
|
addMembers() {
|
||||||
this.set("loading", true);
|
this.set("loading", true);
|
||||||
|
|
||||||
const usernames = this.model.usernames;
|
if (this.emailsPresent) {
|
||||||
if (isEmpty(usernames)) {
|
this.set("setAsOwner", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.notifyUsersDisabled) {
|
||||||
|
this.set("notifyUsers", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(this.usernamesAndEmails)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let promise;
|
|
||||||
|
|
||||||
if (this.setAsOwner) {
|
const promise = this.setAsOwner
|
||||||
promise = this.model.addOwners(usernames, true);
|
? this.model.addOwners(this.usernames, true, this.notifyUsers)
|
||||||
} else {
|
: this.model.addMembers(
|
||||||
promise = this.model.addMembers(usernames, true);
|
this.usernames,
|
||||||
}
|
true,
|
||||||
|
this.notifyUsers,
|
||||||
|
this.emails
|
||||||
|
);
|
||||||
|
|
||||||
promise
|
promise
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
let queryParams = {};
|
||||||
|
|
||||||
|
if (this.usernames) {
|
||||||
|
queryParams.filter = this.usernames;
|
||||||
|
}
|
||||||
|
|
||||||
this.transitionToRoute("group.members", this.get("model.name"), {
|
this.transitionToRoute("group.members", this.get("model.name"), {
|
||||||
queryParams: { filter: usernames }
|
queryParams
|
||||||
});
|
});
|
||||||
|
|
||||||
this.model.set("usernames", null);
|
|
||||||
this.send("closeModal");
|
this.send("closeModal");
|
||||||
})
|
})
|
||||||
.catch(error => this.flash(extractError(error), "error"))
|
.catch(error => this.flash(extractError(error), "error"))
|
||||||
.finally(() => this.set("loading", false));
|
.finally(() => this.set("loading", false));
|
||||||
|
},
|
||||||
|
|
||||||
|
_splitEmailsAndUsernames() {
|
||||||
|
let emails = [];
|
||||||
|
let usernames = [];
|
||||||
|
|
||||||
|
this.usernamesAndEmails.split(",").forEach(u => {
|
||||||
|
emailValid(u) ? emails.push(u) : usernames.push(u);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set("emails", emails.join(","));
|
||||||
|
this.set("usernames", usernames.join(","));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
|
||||||
import Controller from "@ember/controller";
|
|
||||||
import { extractError } from "discourse/lib/ajax-error";
|
|
||||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
|
|
||||||
export default Controller.extend(ModalFunctionality, {
|
|
||||||
loading: false,
|
|
||||||
|
|
||||||
@discourseComputed("input", "loading", "result")
|
|
||||||
disableAddButton(input, loading, result) {
|
|
||||||
return loading || isEmpty(input) || input.length <= 0 || result;
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
cancel() {
|
|
||||||
this.set("result", null);
|
|
||||||
},
|
|
||||||
|
|
||||||
add() {
|
|
||||||
this.setProperties({
|
|
||||||
loading: true,
|
|
||||||
result: null
|
|
||||||
});
|
|
||||||
|
|
||||||
const users = this.input
|
|
||||||
.split("\n")
|
|
||||||
.uniq()
|
|
||||||
.reject(x => x.length === 0);
|
|
||||||
|
|
||||||
ajax("/admin/groups/bulk", {
|
|
||||||
data: { users, group_id: this.get("model.id") },
|
|
||||||
type: "PUT"
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
this.set("result", result);
|
|
||||||
|
|
||||||
if (result.users_not_added) {
|
|
||||||
this.set("result.invalidUsers", result.users_not_added.join(", "));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.flash(extractError(error), "error");
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.set("loading", false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -113,10 +113,10 @@ const Group = RestModel.extend({
|
|||||||
}).then(() => this.findMembers(params, true));
|
}).then(() => this.findMembers(params, true));
|
||||||
},
|
},
|
||||||
|
|
||||||
addMembers(usernames, filter) {
|
addMembers(usernames, filter, notifyUsers, emails = []) {
|
||||||
return ajax(`/groups/${this.id}/members.json`, {
|
return ajax(`/groups/${this.id}/members.json`, {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: { usernames }
|
data: { usernames, emails, notify_users: notifyUsers }
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (filter) {
|
if (filter) {
|
||||||
this._filterMembers(response);
|
this._filterMembers(response);
|
||||||
@@ -126,10 +126,10 @@ const Group = RestModel.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addOwners(usernames, filter) {
|
addOwners(usernames, filter, notifyUsers) {
|
||||||
return ajax(`/admin/groups/${this.id}/owners.json`, {
|
return ajax(`/admin/groups/${this.id}/owners.json`, {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: { group: { usernames } }
|
data: { group: { usernames, notify_users: notifyUsers } }
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (filter) {
|
if (filter) {
|
||||||
this._filterMembers(response);
|
this._filterMembers(response);
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ export default DiscourseRoute.extend({
|
|||||||
showModal("group-add-members", { model: this.modelFor("group") });
|
showModal("group-add-members", { model: this.modelFor("group") });
|
||||||
},
|
},
|
||||||
|
|
||||||
@action
|
|
||||||
showBulkAddModal() {
|
|
||||||
showModal("group-bulk-add", { model: this.modelFor("group") });
|
|
||||||
},
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
didTransition() {
|
didTransition() {
|
||||||
this.controllerFor("group-index").set("filterInput", this._params.filter);
|
this.controllerFor("group-index").set("filterInput", this._params.filter);
|
||||||
|
|||||||
@@ -13,14 +13,8 @@
|
|||||||
{{#if canManageGroup}}
|
{{#if canManageGroup}}
|
||||||
{{d-button icon="plus"
|
{{d-button icon="plus"
|
||||||
action=(route-action "showAddMembersModal")
|
action=(route-action "showAddMembersModal")
|
||||||
label="groups.add_members.title"
|
label="groups.manage.add_members"
|
||||||
class="group-members-add"}}
|
class="group-members-add"}}
|
||||||
{{#if currentUser.admin}}
|
|
||||||
{{d-button icon="plus"
|
|
||||||
action=(route-action "showBulkAddModal")
|
|
||||||
label="admin.groups.bulk_add.title"
|
|
||||||
class="group-bulk-add"}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
{{d-button
|
{{d-button
|
||||||
icon="plus"
|
icon="plus"
|
||||||
label="groups.add_members.title"
|
label="groups.manage.add_members"
|
||||||
class="group-members-add"
|
class="group-members-add"
|
||||||
action=(route-action "showAddMembersModal")
|
action=(route-action "showAddMembersModal")
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
{{#d-modal-body title="groups.add_members.title"}}
|
{{#d-modal-body rawTitle=title}}
|
||||||
<form class="form-vertical group-add-members">
|
<form class="form-vertical group-add-members">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">
|
<label class="control-label">
|
||||||
{{i18n "groups.add_members.usernames"}}
|
{{i18n "groups.add_members.usernames"}}
|
||||||
</label>
|
</label>
|
||||||
|
<p class="description">
|
||||||
|
{{i18n "groups.add_members.description"}}
|
||||||
|
</p>
|
||||||
|
|
||||||
{{user-selector
|
{{user-selector
|
||||||
class="input-xxlarge"
|
class="input-xxlarge"
|
||||||
usernames=model.usernames
|
usernames=usernamesAndEmails
|
||||||
placeholderKey="groups.selector_placeholder"
|
allowEmails=true
|
||||||
|
placeholderKey="groups.add_members.input_placeholder"
|
||||||
id="group-add-members-user-selector"}}
|
id="group-add-members-user-selector"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -18,11 +22,21 @@
|
|||||||
{{input type="checkbox"
|
{{input type="checkbox"
|
||||||
class="inline"
|
class="inline"
|
||||||
checked=setAsOwner
|
checked=setAsOwner
|
||||||
disabled=bulkAdd}}
|
disabled=emailsPresent}}
|
||||||
{{i18n "admin.groups.add_members.as_owner"}}
|
{{i18n "admin.groups.add_members.as_owner"}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="control-group group-add-members-notify-users">
|
||||||
|
<label>
|
||||||
|
{{input type="checkbox"
|
||||||
|
class="inline"
|
||||||
|
checked=notifyUsers
|
||||||
|
disabled=notifyUsersDisabled}}
|
||||||
|
{{i18n "groups.add_members.notify_users"}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
{{#d-modal-body title="admin.groups.bulk_add.title"}}
|
|
||||||
{{#if result}}
|
|
||||||
{{#if result.message}}
|
|
||||||
<div class="alert alert-success">
|
|
||||||
{{result.message}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if result.invalidUsers}}
|
|
||||||
<div class="alert alert-error">
|
|
||||||
{{i18n "admin.groups.bulk_add.complete_users_not_added"}}
|
|
||||||
{{result.invalidUsers}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="">
|
|
||||||
<a href {{action "cancel"}}>{{i18n "cancel"}}</a>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<form class="form-vertical group-bulk-add">
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label">
|
|
||||||
{{i18n "admin.groups.bulk_add.paste"}}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
{{textarea value=input}}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{{/if}}
|
|
||||||
{{/d-modal-body}}
|
|
||||||
|
|
||||||
<div class="modal-footer">
|
|
||||||
{{d-button action=(action "add")
|
|
||||||
class="add btn-primary"
|
|
||||||
icon="plus"
|
|
||||||
disabled=disableAddButton
|
|
||||||
label="groups.add"}}
|
|
||||||
</div>
|
|
||||||
@@ -99,6 +99,10 @@ class Admin::GroupsController < Admin::AdminController
|
|||||||
end
|
end
|
||||||
group.group_users.where(user_id: user.id).update_all(owner: true)
|
group.group_users.where(user_id: user.id).update_all(owner: true)
|
||||||
group_action_logger.log_make_user_group_owner(user)
|
group_action_logger.log_make_user_group_owner(user)
|
||||||
|
|
||||||
|
if group_params[:notify_users] == "true" || group_params[:notify_users] == true
|
||||||
|
group.notify_added_to_group(user, owner: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
group.restore_user_count!
|
group.restore_user_count!
|
||||||
@@ -176,7 +180,8 @@ class Admin::GroupsController < Admin::AdminController
|
|||||||
:membership_request_template,
|
:membership_request_template,
|
||||||
:owner_usernames,
|
:owner_usernames,
|
||||||
:usernames,
|
:usernames,
|
||||||
:publish_read_state
|
:publish_read_state,
|
||||||
|
:notify_users
|
||||||
]
|
]
|
||||||
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
|
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
|
||||||
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
|
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
|
||||||
|
|||||||
@@ -298,8 +298,7 @@ class GroupsController < ApplicationController
|
|||||||
def add_members
|
def add_members
|
||||||
group = Group.find(params[:id])
|
group = Group.find(params[:id])
|
||||||
group.public_admission ? ensure_logged_in : guardian.ensure_can_edit!(group)
|
group.public_admission ? ensure_logged_in : guardian.ensure_can_edit!(group)
|
||||||
|
users = users_from_params.to_a
|
||||||
users = users_from_params
|
|
||||||
|
|
||||||
if group.public_admission
|
if group.public_admission
|
||||||
if !guardian.can_log_group_changes?(group) && current_user != users.first
|
if !guardian.can_log_group_changes?(group) && current_user != users.first
|
||||||
@@ -311,17 +310,33 @@ class GroupsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (usernames = group.users.where(id: users.pluck(:id)).pluck(:username)).present?
|
emails = []
|
||||||
|
if params[:emails]
|
||||||
|
params[:emails].split(",").each do |email|
|
||||||
|
existing_user = User.find_by_email(email)
|
||||||
|
existing_user.present? ? users.push(existing_user) : emails.push(email)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if users.empty? && emails.empty?
|
||||||
|
raise Discourse::InvalidParameters.new(
|
||||||
|
'usernames or emails must be present'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (usernames = group.users.where(id: users.map(&:id)).pluck(:username)).present?
|
||||||
render_json_error(I18n.t(
|
render_json_error(I18n.t(
|
||||||
"groups.errors.member_already_exist",
|
"groups.errors.member_already_exist",
|
||||||
username: usernames.sort.join(", "),
|
username: usernames.sort.join(", "),
|
||||||
count: usernames.size
|
count: usernames.size
|
||||||
))
|
))
|
||||||
else
|
else
|
||||||
users.each do |user|
|
uniq_users = users.uniq
|
||||||
|
uniq_users.each do |user|
|
||||||
begin
|
begin
|
||||||
group.add(user)
|
group.add(user)
|
||||||
GroupActionLogger.new(current_user, group).log_add_user_to_group(user)
|
GroupActionLogger.new(current_user, group).log_add_user_to_group(user)
|
||||||
|
group.notify_added_to_group(user) if params[:notify_users]&.to_s == "true"
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
# Under concurrency, we might attempt to insert two records quickly and hit a DB
|
# Under concurrency, we might attempt to insert two records quickly and hit a DB
|
||||||
# constraint. In this case we can safely ignore the error and act as if the user
|
# constraint. In this case we can safely ignore the error and act as if the user
|
||||||
@@ -329,8 +344,13 @@ class GroupsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
emails.each do |email|
|
||||||
|
Invite.invite_by_email(email, current_user, nil, [group.id])
|
||||||
|
end
|
||||||
|
|
||||||
render json: success_json.merge!(
|
render json: success_json.merge!(
|
||||||
usernames: users.map(&:username)
|
usernames: uniq_users.map(&:username),
|
||||||
|
emails: emails
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -401,6 +421,9 @@ class GroupsController < ApplicationController
|
|||||||
params[:user_emails] = params[:user_email] if params[:user_email].present?
|
params[:user_emails] = params[:user_email] if params[:user_email].present?
|
||||||
|
|
||||||
users = users_from_params
|
users = users_from_params
|
||||||
|
raise Discourse::InvalidParameters.new(
|
||||||
|
'user_ids or usernames or user_emails must be present'
|
||||||
|
) if users.empty?
|
||||||
|
|
||||||
if group.public_exit
|
if group.public_exit
|
||||||
if !guardian.can_log_group_changes?(group) && current_user != users.first
|
if !guardian.can_log_group_changes?(group) && current_user != users.first
|
||||||
@@ -605,9 +628,7 @@ class GroupsController < ApplicationController
|
|||||||
users = User.with_email(params[:user_emails].split(","))
|
users = User.with_email(params[:user_emails].split(","))
|
||||||
raise Discourse::InvalidParameters.new(:user_emails) if users.blank?
|
raise Discourse::InvalidParameters.new(:user_emails) if users.blank?
|
||||||
else
|
else
|
||||||
raise Discourse::InvalidParameters.new(
|
users = []
|
||||||
'user_ids or usernames or user_emails must be present'
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
users
|
users
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -800,6 +800,16 @@ class Group < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notify_added_to_group(user, owner: false)
|
||||||
|
SystemMessage.create_from_system_user(
|
||||||
|
user,
|
||||||
|
:user_added_to_group,
|
||||||
|
group_name: self.full_name.presence || self.name,
|
||||||
|
group_path: "/g/#{self.name}",
|
||||||
|
membership_level: owner ? "an owner" : "a member"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def name_format_validator
|
def name_format_validator
|
||||||
|
|||||||
@@ -626,9 +626,11 @@ en:
|
|||||||
member_added: "Added"
|
member_added: "Added"
|
||||||
member_requested: "Requested at"
|
member_requested: "Requested at"
|
||||||
add_members:
|
add_members:
|
||||||
title: "Add Members"
|
title: "Add members to %{group_name}"
|
||||||
description: "Manage the membership of this group"
|
description: "You can also paste in a comma separated list."
|
||||||
usernames: "Usernames"
|
usernames: "Enter usernames or email addresses"
|
||||||
|
input_placeholder: "Usernames or emails"
|
||||||
|
notify_users: "Notify users"
|
||||||
requests:
|
requests:
|
||||||
title: "Requests"
|
title: "Requests"
|
||||||
reason: "Reason"
|
reason: "Reason"
|
||||||
|
|||||||
@@ -2912,6 +2912,11 @@ en:
|
|||||||
``` text
|
``` text
|
||||||
%{logs}
|
%{logs}
|
||||||
```
|
```
|
||||||
|
user_added_to_group:
|
||||||
|
title: "Added to Group"
|
||||||
|
subject_template: "You have been added as %{membership_level} of the %{group_name} group"
|
||||||
|
text_body_template: |
|
||||||
|
You have been added as a %{membership_level} of the [%{group_name}](%{base_url}%{group_path}) group.
|
||||||
|
|
||||||
csv_export_succeeded:
|
csv_export_succeeded:
|
||||||
title: "CSV Export Succeeded"
|
title: "CSV Export Succeeded"
|
||||||
|
|||||||
@@ -122,6 +122,32 @@ RSpec.describe Admin::GroupsController do
|
|||||||
expect(response.status).to eq(422)
|
expect(response.status).to eq(422)
|
||||||
expect(response.parsed_body["errors"]).to eq(["You cannot modify an automatic group"])
|
expect(response.parsed_body["errors"]).to eq(["You cannot modify an automatic group"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not notify users when the param is not present' do
|
||||||
|
put "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
group: {
|
||||||
|
usernames: user.username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
topic = Topic.find_by(title: "You have been added as an owner of the #{group.name} group", archetype: "private_message")
|
||||||
|
expect(topic.nil?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'notifies users when the param is present' do
|
||||||
|
put "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
group: {
|
||||||
|
usernames: user.username,
|
||||||
|
notify_users: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
topic = Topic.find_by(title: "You have been added as an owner of the #{group.name} group", archetype: "private_message")
|
||||||
|
expect(topic.nil?).to eq(false)
|
||||||
|
expect(topic.topic_users.map(&:user_id)).to include(-1, user.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#remove_owner' do
|
describe '#remove_owner' do
|
||||||
|
|||||||
@@ -1053,6 +1053,28 @@ describe GroupsController do
|
|||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not notify users when the param is not present" do
|
||||||
|
user2 = Fabricate(:user)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
put "/groups/#{group.id}/members.json", params: { usernames: user2.username }
|
||||||
|
}.to change { Topic.where(archetype: "private_message").count }.by(0)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "notifies users when the param is present" do
|
||||||
|
user2 = Fabricate(:user)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
put "/groups/#{group.id}/members.json", params: { usernames: user2.username, notify_users: true }
|
||||||
|
}.to change { Topic.where(archetype: "private_message").count }.by(1)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
expect(Topic.last.topic_users.map(&:user_id)).to include(Discourse::SYSTEM_USER_ID, user2.id)
|
||||||
|
end
|
||||||
|
|
||||||
context "is able to add several members to a group" do
|
context "is able to add several members to a group" do
|
||||||
fab!(:user1) { Fabricate(:user) }
|
fab!(:user1) { Fabricate(:user) }
|
||||||
fab!(:user2) { Fabricate(:user, username: "UsEr2") }
|
fab!(:user2) { Fabricate(:user, username: "UsEr2") }
|
||||||
@@ -1132,6 +1154,53 @@ describe GroupsController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "return a 400 if no user or emails are present" do
|
||||||
|
[
|
||||||
|
{ usernames: "nouserwiththisusername", emails: "" },
|
||||||
|
{ usernames: "", emails: "" }
|
||||||
|
].each do |params|
|
||||||
|
put "/groups/#{group.id}/members.json", params: params
|
||||||
|
expect(response.status).to eq(400)
|
||||||
|
body = response.parsed_body
|
||||||
|
|
||||||
|
expect(body["error_type"]).to eq("invalid_parameters")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "will send invites to each email with group_id set" do
|
||||||
|
emails = ["something@gmail.com", "anotherone@yahoo.com"]
|
||||||
|
put "/groups/#{group.id}/members.json", params: { emails: emails.join(",") }
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
body = response.parsed_body
|
||||||
|
|
||||||
|
expect(body["emails"]).to eq(emails)
|
||||||
|
|
||||||
|
emails.each do |email|
|
||||||
|
invite = Invite.find_by(email: email)
|
||||||
|
expect(invite.groups).to eq([group])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "will find users by email, and invite the correct user" do
|
||||||
|
new_user = Fabricate(:user)
|
||||||
|
expect(new_user.group_ids.include?(group.id)).to eq(false)
|
||||||
|
|
||||||
|
put "/groups/#{group.id}/members.json", params: { emails: new_user.email }
|
||||||
|
|
||||||
|
expect(new_user.reload.group_ids.include?(group.id)).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "will invite the user if their username and email are both invited" do
|
||||||
|
new_user = Fabricate(:user)
|
||||||
|
put "/groups/#{group.id}/members.json", params: { usernames: new_user.username, emails: new_user.email }
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
body = response.parsed_body
|
||||||
|
|
||||||
|
expect(new_user.reload.group_ids.include?(group.id)).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
context 'public group' do
|
context 'public group' do
|
||||||
fab!(:other_user) { Fabricate(:user) }
|
fab!(:other_user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user