mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
Support for inviting to a forum from a user's invite page.
This commit is contained in:
parent
8d47215ea5
commit
de30af9302
22 changed files with 307 additions and 84 deletions
|
@ -9,6 +9,11 @@
|
|||
**/
|
||||
Discourse.InviteController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
|
||||
/**
|
||||
Can we submit the form?
|
||||
|
||||
@property disabled
|
||||
**/
|
||||
disabled: function() {
|
||||
if (this.get('saving')) return true;
|
||||
if (this.blank('email')) return true;
|
||||
|
@ -16,30 +21,79 @@ Discourse.InviteController = Discourse.ObjectController.extend(Discourse.ModalFu
|
|||
return false;
|
||||
}.property('email', 'saving'),
|
||||
|
||||
/**
|
||||
The current text for the invite button
|
||||
|
||||
@property buttonTitle
|
||||
**/
|
||||
buttonTitle: function() {
|
||||
if (this.get('saving')) return I18n.t('topic.inviting');
|
||||
return I18n.t('topic.invite_reply.action');
|
||||
}.property('saving'),
|
||||
|
||||
/**
|
||||
We are inviting to a topic if the model isn't the current user. The current user would
|
||||
mean we are inviting to the forum in general.
|
||||
|
||||
@property invitingToTopic
|
||||
**/
|
||||
invitingToTopic: function() {
|
||||
return this.get('model') !== Discourse.User.current();
|
||||
}.property('model'),
|
||||
|
||||
/**
|
||||
Instructional text for the modal.
|
||||
|
||||
@property inviteInstructions
|
||||
**/
|
||||
inviteInstructions: function() {
|
||||
if (this.get('invitingToTopic')) {
|
||||
return I18n.t('topic.invite_reply.to_topic');
|
||||
} else {
|
||||
return I18n.t('topic.invite_reply.to_forum');
|
||||
}
|
||||
}.property('invitingToTopic'),
|
||||
|
||||
/**
|
||||
The "success" text for when the invite was created.
|
||||
|
||||
@property successMessage
|
||||
**/
|
||||
successMessage: function() {
|
||||
return I18n.t('topic.invite_reply.success', { email: this.get('email') });
|
||||
}.property('email'),
|
||||
|
||||
actions: {
|
||||
createInvite: function() {
|
||||
if (this.get('disabled')) return;
|
||||
/**
|
||||
Reset the modal to allow a new user to be invited.
|
||||
|
||||
var inviteController = this;
|
||||
this.set('saving', true);
|
||||
this.set('error', false);
|
||||
this.get('model').inviteUser(this.get('email')).then(function() {
|
||||
// Success
|
||||
inviteController.set('saving', false);
|
||||
return inviteController.set('finished', true);
|
||||
}, function() {
|
||||
// Failure
|
||||
inviteController.set('error', true);
|
||||
return inviteController.set('saving', false);
|
||||
@method reset
|
||||
**/
|
||||
reset: function() {
|
||||
this.setProperties({
|
||||
email: null,
|
||||
error: false,
|
||||
saving: false,
|
||||
finished: false
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
/**
|
||||
Create the invite and update the modal accordingly.
|
||||
|
||||
@method createInvite
|
||||
**/
|
||||
createInvite: function() {
|
||||
|
||||
if (this.get('disabled')) { return; }
|
||||
|
||||
var self = this;
|
||||
this.setProperties({ saving: true, error: false });
|
||||
this.get('model').createInvite(this.get('email')).then(function() {
|
||||
self.setProperties({ saving: false, finished: true });
|
||||
}).fail(function() {
|
||||
self.setProperties({ saving: false, error: true });
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
@module Discourse
|
||||
**/
|
||||
Discourse.InvitePrivateController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
|
||||
modalClass: 'invite',
|
||||
|
||||
onShow: function(){
|
||||
|
@ -26,28 +25,25 @@ Discourse.InvitePrivateController = Discourse.ObjectController.extend(Discourse.
|
|||
return I18n.t('topic.invite_private.action');
|
||||
}.property('saving'),
|
||||
|
||||
invite: function() {
|
||||
actions: {
|
||||
invite: function() {
|
||||
if (this.get('disabled')) return;
|
||||
|
||||
if (this.get('disabled')) return;
|
||||
var self = this;
|
||||
this.setProperties({saving: true, error: false});
|
||||
|
||||
var invitePrivateController = this;
|
||||
this.set('saving', true);
|
||||
this.set('error', false);
|
||||
// Invite the user to the private message
|
||||
this.get('content').inviteUser(this.get('emailOrUsername')).then(function(result) {
|
||||
// Success
|
||||
invitePrivateController.set('saving', false);
|
||||
invitePrivateController.set('finished', true);
|
||||
// Invite the user to the private message
|
||||
this.get('model').createInvite(this.get('emailOrUsername')).then(function(result) {
|
||||
self.setProperties({saving: true, finished: true});
|
||||
|
||||
if(result && result.user) {
|
||||
invitePrivateController.get('content.details.allowed_users').pushObject(result.user);
|
||||
}
|
||||
}, function() {
|
||||
// Failure
|
||||
invitePrivateController.set('error', true);
|
||||
invitePrivateController.set('saving', false);
|
||||
});
|
||||
return false;
|
||||
if(result && result.user) {
|
||||
self.get('model.details.allowed_users').pushObject(result.user);
|
||||
}
|
||||
}).fail(function() {
|
||||
self.setProperties({error: true, saving: false});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
**/
|
||||
Discourse.UserInvitedController = Ember.ArrayController.extend({
|
||||
|
||||
/**
|
||||
Observe the search term box with a debouncer and change the results.
|
||||
|
||||
@observes searchTerm
|
||||
**/
|
||||
_searchTermChanged: Discourse.debounce(function() {
|
||||
var self = this;
|
||||
Discourse.Invite.findInvitedBy(self.get('user'), this.get('searchTerm')).then(function (invites) {
|
||||
|
@ -15,20 +20,51 @@ Discourse.UserInvitedController = Ember.ArrayController.extend({
|
|||
});
|
||||
}, 250).observes('searchTerm'),
|
||||
|
||||
/**
|
||||
The maximum amount of invites that will be displayed in the view
|
||||
|
||||
@property maxInvites
|
||||
**/
|
||||
maxInvites: function() {
|
||||
return Discourse.SiteSettings.invites_shown;
|
||||
}.property(),
|
||||
|
||||
/**
|
||||
Can the currently logged in user invite users to the site
|
||||
|
||||
@property canInviteToForum
|
||||
**/
|
||||
canInviteToForum: function() {
|
||||
return Discourse.User.currentProp('can_invite_to_forum');
|
||||
}.property(),
|
||||
|
||||
/**
|
||||
Should the search filter input box be displayed?
|
||||
|
||||
@property showSearch
|
||||
**/
|
||||
showSearch: function() {
|
||||
if (Em.isNone(this.get('searchTerm')) && this.get('model.length') === 0) { return false; }
|
||||
return true;
|
||||
}.property('searchTerm', 'model.length'),
|
||||
|
||||
/**
|
||||
Were the results limited by our `maxInvites`
|
||||
|
||||
@property truncated
|
||||
**/
|
||||
truncated: function() {
|
||||
return this.get('model.length') === Discourse.SiteSettings.invites_shown;
|
||||
}.property('model.length'),
|
||||
|
||||
actions: {
|
||||
|
||||
/**
|
||||
Rescind a given invite
|
||||
|
||||
@method rescive
|
||||
@param {Discourse.Invite} invite the invite to rescind.
|
||||
**/
|
||||
rescind: function(invite) {
|
||||
invite.rescind();
|
||||
return false;
|
||||
|
|
|
@ -196,11 +196,16 @@ Discourse.Topic = Discourse.Model.extend({
|
|||
});
|
||||
},
|
||||
|
||||
// Invite a user to this topic
|
||||
inviteUser: function(user) {
|
||||
/**
|
||||
Invite a user to this topic
|
||||
|
||||
@method createInvite
|
||||
@param {String} emailOrUsername The email or username of the user to be invited
|
||||
**/
|
||||
createInvite: function(emailOrUsername) {
|
||||
return Discourse.ajax("/t/" + this.get('id') + "/invite", {
|
||||
type: 'POST',
|
||||
data: { user: user }
|
||||
data: { user: emailOrUsername }
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -282,13 +282,27 @@ Discourse.User = Discourse.Model.extend({
|
|||
Determines whether the current user is allowed to upload a file.
|
||||
|
||||
@method isAllowedToUploadAFile
|
||||
@param {string} type The type of the upload (image, attachment)
|
||||
@param {String} type The type of the upload (image, attachment)
|
||||
@returns true if the current user is allowed to upload a file
|
||||
**/
|
||||
isAllowedToUploadAFile: function(type) {
|
||||
return this.get('staff') ||
|
||||
this.get('trust_level') > 0 ||
|
||||
Discourse.SiteSettings['newuser_max_' + type + 's'] > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
Invite a user to the site
|
||||
|
||||
@method createInvite
|
||||
@param {String} email The email address of the user to invite to the site
|
||||
@returns {Promise} the result of the server call
|
||||
**/
|
||||
createInvite: function(email) {
|
||||
return Discourse.ajax('/invites', {
|
||||
type: 'POST',
|
||||
data: {email: email}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -36,12 +36,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
|
||||
showInvite: function() {
|
||||
Discourse.Route.showModal(this, 'invite', this.modelFor('topic'));
|
||||
this.controllerFor('invite').setProperties({
|
||||
email: null,
|
||||
error: false,
|
||||
saving: false,
|
||||
finished: false
|
||||
});
|
||||
this.controllerFor('invite').reset();
|
||||
},
|
||||
|
||||
showPrivateInvite: function() {
|
||||
|
|
|
@ -22,6 +22,19 @@ Discourse.UserInvitedRoute = Discourse.Route.extend({
|
|||
searchTerm: ''
|
||||
});
|
||||
this.controllerFor('user').set('indexStream', false);
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
/**
|
||||
Shows the invite modal to invite users to the forum.
|
||||
|
||||
@method showInvite
|
||||
**/
|
||||
showInvite: function() {
|
||||
Discourse.Route.showModal(this, 'invite', Discourse.User.current());
|
||||
this.controllerFor('invite').reset();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -9,7 +9,8 @@
|
|||
{{#if finished}}
|
||||
{{{successMessage}}}
|
||||
{{else}}
|
||||
<label>{{i18n topic.invite_reply.email}}</label>
|
||||
|
||||
<label>{{inviteInstructions}}</label>
|
||||
{{textField value=email placeholderKey="topic.invite_reply.email_placeholder"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
<h2>{{i18n user.invited.title}}</h2>
|
||||
|
||||
{{#if canInviteToForum}}
|
||||
<button {{action showInvite}} class='btn right'>{{i18n user.invited.create}}</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if showSearch}}
|
||||
<form>
|
||||
{{textField value=searchTerm placeholderKey="user.invited.search"}}
|
||||
|
|
|
@ -8,12 +8,18 @@
|
|||
**/
|
||||
Discourse.InviteView = Discourse.ModalBodyView.extend({
|
||||
templateName: 'modal/invite',
|
||||
title: I18n.t('topic.invite_reply.title'),
|
||||
|
||||
title: function() {
|
||||
if (this.get('controller.invitingToTopic')) {
|
||||
return I18n.t('topic.invite_reply.title');
|
||||
} else {
|
||||
return I18n.t('user.invited.create');
|
||||
}
|
||||
}.property('controller.invitingToTopic'),
|
||||
|
||||
keyUp: function(e) {
|
||||
// Add the invitee if they hit enter
|
||||
if (e.keyCode === 13) { this.get('controller').createInvite(); }
|
||||
if (e.keyCode === 13) { this.get('controller').send('createInvite'); }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,10 @@
|
|||
border: 1px solid #ddd;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.btn.right {
|
||||
float: right
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def preload_current_user_data
|
||||
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, root: false)))
|
||||
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, scope: guardian, root: false)))
|
||||
serializer = ActiveModel::ArraySerializer.new(TopicTrackingState.report([current_user.id]), each_serializer: TopicTrackingStateSerializer)
|
||||
store_preloaded("topicTrackingStates", MultiJson.dump(serializer))
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class InvitesController < ApplicationController
|
|||
skip_before_filter :check_xhr
|
||||
skip_before_filter :redirect_to_login_if_required
|
||||
|
||||
before_filter :ensure_logged_in, only: [:destroy]
|
||||
before_filter :ensure_logged_in, only: [:destroy, :create]
|
||||
|
||||
def show
|
||||
invite = Invite.where(invite_key: params[:id]).first
|
||||
|
@ -27,6 +27,18 @@ class InvitesController < ApplicationController
|
|||
redirect_to "/"
|
||||
end
|
||||
|
||||
def create
|
||||
params.require(:email)
|
||||
|
||||
guardian.ensure_can_invite_to_forum!
|
||||
|
||||
if Invite.invite_by_email(params[:email], current_user)
|
||||
render json: success_json
|
||||
else
|
||||
render json: failed_json, status: 422
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
params.require(:email)
|
||||
|
||||
|
|
|
@ -8,11 +8,19 @@ class InviteMailer < ActionMailer::Base
|
|||
first_topic = invite.topics.order(:created_at).first
|
||||
|
||||
# If they were invited to a topic
|
||||
build_email(invite.email,
|
||||
template: 'invite_mailer',
|
||||
invitee_name: invite.invited_by.username,
|
||||
invite_link: "#{Discourse.base_url}/invites/#{invite.invite_key}",
|
||||
topic_title: first_topic.try(:title))
|
||||
if first_topic.present?
|
||||
build_email(invite.email,
|
||||
template: 'invite_mailer',
|
||||
invitee_name: invite.invited_by.username,
|
||||
invite_link: "#{Discourse.base_url}/invites/#{invite.invite_key}",
|
||||
topic_title: first_topic.try(:title))
|
||||
else
|
||||
build_email(invite.email,
|
||||
template: 'invite_forum_mailer',
|
||||
invitee_name: invite.invited_by.username,
|
||||
invite_link: "#{Discourse.base_url}/invites/#{invite.invite_key}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -44,6 +44,30 @@ class Invite < ActiveRecord::Base
|
|||
InviteRedeemer.new(self).redeem unless expired? || destroyed?
|
||||
end
|
||||
|
||||
|
||||
# Create an invite for a user, supplying an optional topic
|
||||
#
|
||||
# Return the previously existing invite if already exists. Returns nil if the invite can't be created.
|
||||
def self.invite_by_email(email, invited_by, topic=nil)
|
||||
lower_email = Email.downcase(email)
|
||||
invite = Invite.with_deleted.where('invited_by_id = ? and email = ?', invited_by.id, lower_email).first
|
||||
|
||||
if invite.blank?
|
||||
invite = Invite.create(invited_by: invited_by, email: lower_email)
|
||||
unless invite.valid?
|
||||
topic.grant_permission_to_user(lower_email) if topic.present? && topic.email_already_exists_for?(invite)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Recover deleted invites if we invite them again
|
||||
invite.recover! if invite.deleted_at.present?
|
||||
|
||||
topic.topic_invites.create(invite_id: invite.id) if topic.present?
|
||||
Jobs.enqueue(:invite_email, invite_id: invite.id)
|
||||
invite
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -443,28 +443,8 @@ class Topic < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
# Invite a user by email and return the invite. Return the previously existing invite
|
||||
# if already exists. Returns nil if the invite can't be created.
|
||||
def invite_by_email(invited_by, email)
|
||||
lower_email = Email.downcase(email)
|
||||
invite = Invite.with_deleted.where('invited_by_id = ? and email = ?', invited_by.id, lower_email).first
|
||||
|
||||
if invite.blank?
|
||||
invite = Invite.create(invited_by: invited_by, email: lower_email)
|
||||
unless invite.valid?
|
||||
|
||||
grant_permission_to_user(lower_email) if email_already_exists_for?(invite)
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Recover deleted invites if we invite them again
|
||||
invite.recover if invite.deleted_at.present?
|
||||
|
||||
topic_invites.create(invite_id: invite.id)
|
||||
Jobs.enqueue(:invite_email, invite_id: invite.id)
|
||||
invite
|
||||
Invite.invite_by_email(email, invited_by, self)
|
||||
end
|
||||
|
||||
def email_already_exists_for?(invite)
|
||||
|
|
|
@ -14,7 +14,8 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
:external_links_in_new_tab,
|
||||
:dynamic_favicon,
|
||||
:trust_level,
|
||||
:can_edit
|
||||
:can_edit,
|
||||
:can_invite_to_forum
|
||||
|
||||
def include_site_flagged_posts_count?
|
||||
object.staff?
|
||||
|
@ -36,4 +37,12 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
true
|
||||
end
|
||||
|
||||
def can_invite_to_forum
|
||||
true
|
||||
end
|
||||
|
||||
def include_can_invite_to_forum?
|
||||
scope.can_invite_to_forum?
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -339,6 +339,7 @@ en:
|
|||
time_read: "Read Time"
|
||||
days_visited: "Days Visited"
|
||||
account_age_days: "Account age in days"
|
||||
create: "Invite Friends to this Forum"
|
||||
|
||||
password:
|
||||
title: "Password"
|
||||
|
@ -736,7 +737,9 @@ en:
|
|||
title: 'Invite Friends to Reply'
|
||||
action: 'Email Invite'
|
||||
help: 'send invitations to friends so they can reply to this topic with a single click'
|
||||
email: "We'll send your friend a brief email allowing them to immediately reply to this topic by clicking a link, no login required."
|
||||
to_topic: "We'll send your friend a brief email allowing them to immediately reply to this topic by clicking a link, no login required."
|
||||
to_forum: "We'll send your friend a brief email allowing them to join the forum by clicking a link."
|
||||
|
||||
email_placeholder: 'email address'
|
||||
success: "Thanks! We mailed out an invitation to <b>{{email}}</b>. We'll let you know when they redeem your invitation. Check the invitations tab on your user page to keep track of who you've invited."
|
||||
error: "Sorry, we couldn't invite that person. Perhaps they are already a user?"
|
||||
|
|
|
@ -813,6 +813,19 @@ en:
|
|||
|
||||
[1]: %{invite_link}
|
||||
|
||||
invite_forum_mailer:
|
||||
subject_template: "[%{site_name}] %{invitee_name} invited you to join %{site_name}"
|
||||
text_body_template: |
|
||||
%{invitee_name} invited you to %{site_name}.
|
||||
|
||||
If you're interested, click the link below to join:
|
||||
|
||||
[Visit %{site_name}][1]
|
||||
|
||||
You were invited by a trusted user, so you'll be able to join immediately, without needing to log in.
|
||||
|
||||
[1]: %{invite_link}
|
||||
|
||||
test_mailer:
|
||||
subject_template: "[%{site_name}] Email Deliverability Test"
|
||||
text_body_template: |
|
||||
|
|
|
@ -191,15 +191,18 @@ class Guardian
|
|||
is_me?(user)
|
||||
end
|
||||
|
||||
def can_invite_to?(object)
|
||||
def can_invite_to_forum?
|
||||
authenticated? &&
|
||||
can_see?(object) &&
|
||||
(
|
||||
(!SiteSetting.must_approve_users? && @user.has_trust_level?(:regular)) ||
|
||||
is_staff?
|
||||
)
|
||||
end
|
||||
|
||||
def can_invite_to?(object)
|
||||
can_see?(object) && can_invite_to_forum?
|
||||
end
|
||||
|
||||
def can_see_deleted_posts?
|
||||
is_staff?
|
||||
end
|
||||
|
|
|
@ -181,6 +181,26 @@ describe Guardian do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'can_invite_to_forum?' do
|
||||
let(:user) { Fabricate.build(:user) }
|
||||
let(:moderator) { Fabricate.build(:moderator) }
|
||||
|
||||
it "doesn't allow anonymous users to invite" do
|
||||
Guardian.new.can_invite_to_forum?.should be_false
|
||||
end
|
||||
|
||||
it 'returns true when the site requires approving users and is mod' do
|
||||
SiteSetting.expects(:must_approve_users?).returns(true)
|
||||
Guardian.new(moderator).can_invite_to_forum?.should be_true
|
||||
end
|
||||
|
||||
it 'returns false when the site requires approving users and is regular' do
|
||||
SiteSetting.expects(:must_approve_users?).returns(true)
|
||||
Guardian.new(user).can_invite_to_forum?.should be_false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'can_invite_to?' do
|
||||
let(:topic) { Fabricate(:topic) }
|
||||
let(:user) { topic.user }
|
||||
|
@ -198,7 +218,7 @@ describe Guardian do
|
|||
Guardian.new(moderator).can_invite_to?(topic).should be_true
|
||||
end
|
||||
|
||||
it 'returns true when the site requires approving users and is regular' do
|
||||
it 'returns false when the site requires approving users and is regular' do
|
||||
SiteSetting.expects(:must_approve_users?).returns(true)
|
||||
Guardian.new(coding_horror).can_invite_to?(topic).should be_false
|
||||
end
|
||||
|
|
|
@ -35,13 +35,39 @@ describe InvitesController do
|
|||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context '.create' do
|
||||
it 'requires you to be logged in' do
|
||||
lambda {
|
||||
post :create, email: 'jake@adventuretime.ooo'
|
||||
}.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
context 'while logged in' do
|
||||
let!(:user) { log_in }
|
||||
let(:email) { 'jake@adventuretime.ooo' }
|
||||
|
||||
it "fails if you can't invite to the forum" do
|
||||
Guardian.any_instance.stubs(:can_invite_to_forum?).returns(false)
|
||||
Invite.expects(:invite_by_email).never
|
||||
post :create, email: email
|
||||
response.should_not be_success
|
||||
end
|
||||
|
||||
it "delegates to Invite#invite_by_email and returns success if you can invite" do
|
||||
Guardian.any_instance.stubs(:can_invite_to_forum?).returns(true)
|
||||
Invite.expects(:invite_by_email).with(email, user).returns(Invite.new)
|
||||
post :create, email: email
|
||||
response.should be_success
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context '.show' do
|
||||
|
||||
context 'with an invalid invite id' do
|
||||
|
||||
before do
|
||||
get :show, id: "doesn't exist"
|
||||
end
|
||||
|
@ -53,7 +79,6 @@ describe InvitesController do
|
|||
it "should not change the session" do
|
||||
session[:current_user_id].should be_blank
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with a deleted invite' do
|
||||
|
@ -71,10 +96,8 @@ describe InvitesController do
|
|||
it "should not change the session" do
|
||||
session[:current_user_id].should be_blank
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
context 'with a valid invite id' do
|
||||
let(:topic) { Fabricate(:topic) }
|
||||
let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") }
|
||||
|
|
Loading…
Reference in a new issue