Last active
January 25, 2021 14:54
-
-
Save hasannadeem/708598e6853b2b99abf9e2a2b6f584c8 to your computer and use it in GitHub Desktop.
Event Management Service with RSpect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Slack::ChannelList | |
def initialize(organization) | |
@client = Slack::Web::Client.new(token: organization.slack_token) | |
end | |
def self.call(organization:) | |
new(organization).call | |
end | |
def call | |
response = client.conversations_list({ exclude_archived: true }) | |
response.ok ? response.channels.pluck(:name, :id) : [] | |
end | |
private | |
attr_reader :client | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
RSpec.describe Events::EditorController, type: :controller do | |
login_user | |
let(:valid_attributes) { | |
FactoryBot.attributes_for(:event).merge(creator_id: @user.id) | |
} | |
let(:invalid_attributes) { | |
valid_attributes.merge(name: nil, organization_id: nil) | |
} | |
let(:participants) { | |
event_attendees = FactoryBot.create_list(:user, 5, organization: @org).pluck(:email) | |
event_invitees = ["[email protected]", "[email protected]"] | |
event_outsiders = ["[email protected]", "[email protected]"] | |
invalid_emails = ["asdfasdf", "asdfasdoiu3"] | |
(event_attendees + event_invitees + event_outsiders + invalid_emails).to_csv | |
} | |
describe "GET #new" do | |
it "returns a success response" do | |
get :new | |
expect(response).to be_successful | |
end | |
end | |
describe "GET #show" do | |
it "returns a success response" do | |
event = FactoryBot.create :event | |
event.event_hosts.create(user: @user) | |
get :show, params: { event_id: event.to_param } | |
expect(response).to be_successful | |
end | |
end | |
describe "POST #create" do | |
context "with valid params" do | |
it "creates a new un-approved Event" do | |
expect { | |
post :create, params: { event: valid_attributes } | |
}.to change(Event, :count).by(1) | |
end | |
it "creates a new approved Event" do | |
admin = FactoryBot.create :user | |
admin.add_role(:admin, admin.organization) | |
expect { | |
post :create, params: { event: valid_attributes.merge(creator_id: admin.id) } | |
}.to change(Event, :count).by(1) | |
end | |
it "creates a new published Event" do | |
admin = FactoryBot.create :user | |
admin.add_role(:admin, admin.organization) | |
event_type = FactoryBot.create :event_type | |
expect { | |
post :create, params: { event: valid_attributes.merge(creator_id: admin.id, published: true, event_type_id: event_type.id) } | |
}.to change(Event, :count).by(1) | |
end | |
it "redirects to the event editor" do | |
post :create, params: { event: valid_attributes } | |
expect(response).to redirect_to(Event.last) | |
end | |
it "notifies followers" do | |
tom = FactoryBot.create :user | |
office = FactoryBot.create :office | |
office.followers << tom << @admin | |
notification_settings = tom.notification_setting.category_settings | |
tom.notification_setting.update! category_settings: notification_settings.merge({ follow: { enabled: true } }) | |
expect { | |
post :create, params: { event: valid_attributes.merge(office_id: office.id, creator_id: @admin.id) } | |
}.to have_enqueued_mail(FollowMailer, :resource_created_email) | |
end | |
context "with follow notifications disabled" do | |
it "does not notify follower" do | |
spike = FactoryBot.create :user | |
office = FactoryBot.create :office | |
office.followers << spike | |
notification_settings = spike.notification_setting.category_settings | |
spike.notification_setting.update! category_settings: notification_settings.merge({ follow: { enabled: false } }) | |
expect { | |
post :create, params: { event: valid_attributes.merge(office_id: office.id) } | |
}.to_not have_enqueued_mail(FollowMailer, :resource_created_email) | |
end | |
end | |
it "creates a new event and add a gcal event" do | |
expect { | |
post :create, params: { event: valid_attributes, add_gcal_event: true } | |
}.to change(Event, :count).by(1) | |
end | |
context "with participants" do | |
it "creates a new Event and add event_attendees and event_invitees" do | |
expect { | |
post :create, params: { event: valid_attributes, participants_via_email: participants } | |
}.to change(Event, :count).by(1) | |
expect(Event.last.event_attendees.count).to eq(5) | |
expect(Event.last.event_invitees.count).to eq(2) | |
expect(Event.last.outsiders.count).to eq(0) | |
end | |
it "creates a new Event and add event_attendees and event_invitees and event_outsiders" do | |
expect { | |
post :create, params: { event: valid_attributes.merge(privacy: :open), participants_via_email: participants } | |
}.to change(Event, :count).by(1) | |
expect(Event.last.event_attendees.count).to eq(5) | |
expect(Event.last.event_invitees.count).to eq(2) | |
expect(Event.last.outsiders.count).to eq(2) | |
end | |
context "with selected_attendees_ids" do | |
it "creates a new Event and add event_attendees and event_invitees" do | |
attendee_ids = event_attendees = FactoryBot.create_list(:user, 5, organization: @org).pluck(:id).to_csv | |
expect { | |
post :create, params: { event: valid_attributes, participants_via_email: participants, selected_attendees_ids: attendee_ids } | |
}.to change(Event, :count).by(1) | |
expect(Event.last.event_attendees.count).to eq(10) | |
expect(Event.last.event_invitees.count).to eq(2) | |
expect(Event.last.outsiders.count).to eq(0) | |
end | |
end | |
end | |
context "creates new published recurring events" do | |
before(:each) do | |
@event_type = FactoryBot.create :event_type | |
@start = 'Fri, 01 Jan 2021 07:06:18 CST -06:00'.to_time | |
end | |
it "daily Recurring Events without end date" do | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: @start + 2.hours, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'daily'), recurring_event: 'on' } | |
}.to change(Event, :count).by(31) | |
expect(Event.last.parent_event.recurring_events.count).to eq(30) | |
end | |
it "weekly Recurring Events without end date" do | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: @start + 2.hours, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'weekly'), recurring_event: 'on' } | |
}.to change(Event, :count).by(13) | |
expect(Event.last.parent_event.recurring_events.count).to eq(12) | |
end | |
it "monthly Recurring Events without end date" do | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: @start + 2.hours, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'monthly'), recurring_event: 'on' } | |
}.to change(Event, :count).by(13) | |
expect(Event.last.parent_event.recurring_events.count).to eq(12) | |
end | |
it "daily Recurring Events with end date" do | |
ends = @start + 2.hours | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: ends, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'daily', recurrence_end_date: @start + 10.day), recurring_event: 'on' } | |
}.to change(Event, :count).by(11) | |
expect(Event.last.parent_event.recurring_events.count).to eq(10) | |
end | |
it "daily Recurring Events with survey schedule time" do | |
ends = @start + 2.hours | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: ends, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'daily', survey_scheduled: '1', survey_schedule_time: ends + 1.day, recurrence_end_date: @start + 10.day), recurring_event: 'on' } | |
}.to change(Event, :count).by(11) | |
expect(Event.last.survey_schedule_time.to_date).to eq((Event.last.start + 1.day).to_date) | |
end | |
it "daily Recurring Events with rsvp required by date" do | |
ends = @start + 2.hours | |
expect { | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: ends, creator_id: @admin.id, published: true, event_type_id: @event_type.id, pattern_type: 'daily', rsvp_required: '1', rsvp_required_by_date: @start - 1.day, recurrence_end_date: @start + 10.day), recurring_event: 'on' } | |
}.to change(Event, :count).by(11) | |
expect(Event.last.rsvp_required_by_date.to_date).to eq((Event.last.start - 1.day).to_date) | |
end | |
end | |
end | |
context "with invalid params" do | |
it "returns a success response (i.e. to display the editor view)" do | |
post :create, params: {event: invalid_attributes} | |
expect(response).to be_successful | |
end | |
end | |
end | |
describe "PUT #update" do | |
context "with valid params" do | |
let(:new_attributes) { | |
FactoryBot.attributes_for :event, name: "Bowling Night", description: "Lets hit the lanes!" | |
} | |
it "updates the requested event" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: new_attributes } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
end | |
it "redirects to the event editor" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: new_attributes } | |
expect(response).to redirect_to(event) | |
end | |
it "updates the requested event and add a gcal event" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: new_attributes, add_gcal_event: true } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
end | |
context "with gcal event" do | |
it "updates the requested event" do | |
event = FactoryBot.create(:event, creator: @user) | |
event.calendar_events.new(user: event.creator, calendar_id: @user.email).save | |
put :update, params: { event_id: event.to_param, event: new_attributes } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
end | |
it "updates the requested event and delete a gcal event" do | |
event = FactoryBot.create(:event, creator: @user) | |
event.calendar_events.new(user: event.creator, calendar_id: @user.email).save | |
put :update, params: { event_id: event.to_param, event: new_attributes, delete_calendar_event: true } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
end | |
end | |
context "with participants" do | |
it "updates the requested event and add event_attendees and event_invitees" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: new_attributes, participants_via_email: participants } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
expect(event.event_attendees.count).to eq(5) | |
expect(event.event_invitees.count).to eq(2) | |
expect(event.outsiders.count).to eq(0) | |
end | |
it "updates the requested event and add event_attendees and event_invitees and event_outsiders" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: new_attributes.merge(privacy: :open), participants_via_email: participants } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
expect(event.event_attendees.count).to eq(5) | |
expect(event.event_invitees.count).to eq(2) | |
expect(event.outsiders.count).to eq(2) | |
end | |
context "with selected_attendees_ids" do | |
it "updates the requested event and add event_attendees and event_invitees" do | |
event = FactoryBot.create(:event, creator: @user) | |
attendee_ids = event_attendees = FactoryBot.create_list(:user, 5, organization: @org).pluck(:id).to_csv | |
put :update, params: { event_id: event.to_param, event: new_attributes, participants_via_email: participants, selected_attendees_ids: attendee_ids } | |
event.reload | |
expect(event.name).to eq(new_attributes[:name]) | |
expect(event.event_attendees.count).to eq(10) | |
expect(event.event_invitees.count).to eq(2) | |
expect(event.outsiders.count).to eq(0) | |
end | |
end | |
end | |
context "with recurring events" do | |
before(:each) do | |
event_type = FactoryBot.create :event_type | |
@start = 'Fri, 01 Jan 2021 07:06:18 CST -06:00'.to_time | |
post :create, params: { event: valid_attributes.merge(start: @start, ends: @start + 2.hours, creator_id: @admin.id, published: true, event_type_id: event_type.id, pattern_type: 'monthly'), recurring_event: 'on' } | |
@parent_event = Event.last.parent_event | |
allow(controller).to receive(:current_user).and_return(@admin) | |
end | |
it "updates this and following events from parent" do | |
expect { | |
put :update, params: { event_id: @parent_event.to_param, event: new_attributes.merge(start: @start, ends: @start + 2.hours), update_type: 'next' } | |
@parent_event.reload | |
}.to change(@parent_event, :name).from('Happy Hour').to('Bowling Night') | |
expect(Event.last.name).to eq('Bowling Night') | |
end | |
it "updates all events from parent" do | |
expect { | |
put :update, params: { event_id: @parent_event.to_param, event: new_attributes.merge(start: @start, ends: @start + 2.hours), update_type: 'all' } | |
@parent_event.reload | |
}.to change(@parent_event, :name).from('Happy Hour').to('Bowling Night') | |
expect(Event.last.name).to eq('Bowling Night') | |
end | |
it "does not repeat recurring events from parent" do | |
child_events_ids = @parent_event.recurring_events.ids | |
expect { | |
put :update, params: { event_id: @parent_event.to_param, event: valid_attributes.merge(start: @start, ends: @start + 2.hours) } | |
@parent_event.reload | |
}.to change(@parent_event, :pattern_type).from('monthly').to(nil) | |
expect(Event.pluck(:id)).not_to include(child_events_ids) | |
end | |
it "does not repeat recurring events from child" do | |
child_event = @parent_event.recurring_events.first | |
expect { | |
put :update, params: { event_id: child_event.to_param, event: valid_attributes.merge(start: @start, ends: @start + 2.hours) } | |
child_event.reload | |
}.to change(child_event, :parent_id).from(@parent_event.id).to(nil) | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
end | |
it "updates this and following events pattern type from parent" do | |
expect { | |
put :update, params: { event_id: @parent_event.to_param, event: valid_attributes.merge(start: @parent_event.start, ends: @parent_event.ends, pattern_type: 'weekly'), recurring_event: 'on', update_type: 'next', update_pattern_type: true } | |
@parent_event.reload | |
}.to change(@parent_event.recurring_events, :count).from(12).to(52) | |
expect(@parent_event.pattern_type).to eq('weekly') | |
end | |
it "updates this and following events pattern type from child" do | |
child_event = @parent_event.recurring_events.second | |
expect { | |
put :update, params: { event_id: child_event.to_param, event: valid_attributes.merge(start: child_event.start, ends: child_event.ends, pattern_type: 'weekly'), recurring_event: 'on', update_type: 'next', update_pattern_type: true } | |
child_event.reload | |
}.to change(child_event, :parent_id).from(@parent_event.id).to(nil) | |
expect(child_event.recurring_events.count).to eq(43) | |
expect(@parent_event.recurring_events.count).to eq(1) | |
end | |
it "updates all events pattern type from child" do | |
child_event = @parent_event.recurring_events.second | |
expect { | |
put :update, params: { event_id: child_event.to_param, event: valid_attributes.merge(start: child_event.start, ends: child_event.ends, pattern_type: 'weekly'), recurring_event: 'on', update_type: 'all', update_pattern_type: true } | |
child_event.reload | |
}.to change(child_event, :parent_id).from(@parent_event.id).to(nil) | |
expect(child_event.recurring_events.count).to eq(43) | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
end | |
end | |
end | |
context "with invalid params" do | |
it "returns a success response (i.e. to display the editor view)" do | |
event = FactoryBot.create(:event, creator: @user) | |
put :update, params: { event_id: event.to_param, event: invalid_attributes } | |
expect(response).to be_successful | |
end | |
end | |
end | |
describe "POST #create_via_emails" do | |
context "with valid file format" do | |
it "returns a success response (i.e. to render create_via_emails.js.erb)" do | |
csv_data = [ { email: "[email protected]" }, { email: "[email protected]" }, { email: "[email protected]" } ] | |
post :create_via_emails, params: { event: { privacy: 1 }, participant_file: Rack::Test::UploadedFile.new(generate_csv(csv_data), 'text/csv') }, format: 'js' | |
expect(response).to be_successful | |
end | |
end | |
end | |
describe "POST #create_via_text" do | |
it "returns a success response (i.e. to render create_via_text.js.erb)" do | |
emails = "[email protected], [email protected], [email protected]" | |
post :create_via_text, params: { participants_emails: emails }, format: 'js' | |
expect(response).to be_successful | |
end | |
end | |
describe 'delete #destroy' do | |
it 'destroys the event and redirects with notice' do | |
e = FactoryBot.create :event | |
delete :destroy, params: { event_id: e.id } | |
expect(Event.pluck(:id)).not_to include(e.id) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
context "destroys recurring events" do | |
before(:each) do | |
event_type = FactoryBot.create :event_type | |
start = Time.current + 2.day | |
post :create, params: { event: valid_attributes.merge(start: start, ends: start + 2.hours, creator_id: @admin.id, published: true, event_type_id: event_type.id, pattern_type: 'monthly'), recurring_event: 'on' } | |
@parent_event = Event.last.parent_event | |
end | |
it "this event only from parent and redirects with notice" do | |
delete :destroy, params: { event_id: @parent_event.id, update_type: 'this' } | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
expect(Event.last.parent_id).not_to eq(@parent_event.id) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
it "this event only from child and redirects with notice" do | |
child_event_id = @parent_event.recurring_events.first.id | |
delete :destroy, params: { event_id: child_event_id, update_type: 'this' } | |
expect(Event.pluck(:id)).not_to include(child_event_id) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
it "this and following events from parent and redirects with notice" do | |
delete :destroy, params: { event_id: @parent_event.id, update_type: 'next', destroy_event: 'true' } | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
expect(Event.pluck(:id)).not_to include(@parent_event.recurring_events.ids) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
it "this and following events from child and redirects with notice" do | |
delete :destroy, params: { event_id: @parent_event.recurring_events.first.id, update_type: 'next', destroy_event: 'true' } | |
expect(Event.pluck(:id)).not_to include(@parent_event.recurring_events.ids) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
it "all events from parent and redirects with notice" do | |
delete :destroy, params: { event_id: @parent_event.id, update_type: 'all', destroy_event: 'true' } | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
expect(Event.pluck(:id)).not_to include(@parent_event.recurring_events.ids) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
it "all events from child and redirects with notice" do | |
delete :destroy, params: { event_id: @parent_event.recurring_events.first.id, update_type: 'all', destroy_event: 'true' } | |
expect(Event.pluck(:id)).not_to include(@parent_event.id) | |
expect(Event.pluck(:id)).not_to include(@parent_event.recurring_events.ids) | |
expect(response).to redirect_to(events_path) | |
expect(flash[:notice]).to eq('Event has been destroyed.') | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Event::EditorService | |
include GcalEventSync, SessionInfo | |
attr_reader :event, :current_user | |
def initialize(event: nil, params: , current_user:) | |
set_event(event, params) | |
@current_user = current_user | |
end | |
def call | |
if event.save | |
if event.was_a_new_record? | |
notify_org_admins | |
notify_office_followers | |
end | |
true | |
else | |
false | |
end | |
end | |
private | |
def set_event(event, params) | |
@event = event || current_organization.events.new | |
@event.assign_attributes(params) | |
# Handle Timezones | |
@event.start = @event.start.asctime.in_time_zone(@event.timezone) | |
@event.ends = @event.ends.asctime.in_time_zone(@event.timezone) | |
@event.rsvp_required_by_date = @event.rsvp_required_by_date.asctime.in_time_zone(@event.timezone) if @event.rsvp_required_by_date | |
@event.survey_schedule_time = @event.survey_schedule_time.asctime.in_time_zone(@event.timezone) if @event.survey_schedule_time | |
end | |
def notify_office_followers | |
return if event.office.blank? || event.pending? | |
event.office.followers.all_except(event.creator).each do |follower| | |
Notification.create(target: follower, object: event, type: :resource_created, category: :follow) | |
FollowMailer.resource_created_email(event, event.office, follower).deliver_later if follower.notifications_enabled? :follow | |
end | |
end | |
def notify_org_admins | |
if event.pending? | |
admin_emails = User.active_with_role(:admin, event.organization).pluck(:email) | |
EventApprovalMailer.event_created_email(event.id, admin_emails).deliver_later | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Slack::Rsvp::PostMessage | |
def initialize(slack_message) | |
@client = Slack::Web::Client.new(token: slack_message.event.organization.slack_token) | |
@slack_message = slack_message | |
end | |
def self.call(slack_message:) | |
new(slack_message).call | |
end | |
def call | |
response = client.chat_postMessage(Slack::RsvpMessages.post(slack_message)) | |
response.ts if response.ok | |
end | |
private | |
attr_reader :client, :slack_message | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Slack::Rsvp::ProcessResponse | |
def initialize(event, slack_user, action, trigger_id, responses) | |
@event = event | |
@slack_user = slack_user | |
@responses = responses | |
@trigger_id = trigger_id | |
@action = action | |
end | |
def self.call(event:, slack_user:, action:, trigger_id:, responses: nil) | |
new(event, slack_user, action, trigger_id, responses).call | |
end | |
def call | |
if event.finished? | |
Slack::EventConfirmationMessageJob.perform_later(event.id, slack_user.id, 'past_event') | |
return true | |
end | |
user = User.find_by(email: slack_user.email) | |
if user.present? | |
attendee = event.event_attendees.find_or_initialize_by(user: user) | |
else | |
attendee = event.event_invitees.find_or_initialize_by(email: slack_user.email) | |
attendee.invited_by ||= event.organization.users.active_with_role(:admin, event.organization).first.id | |
end | |
return if attendee.status == action | |
if action == 'not_attending' | |
attendee.update(status: action) | |
return true | |
end | |
if responses.nil? && event.require_information && event.event_questions.exists? | |
Slack::Rsvp::ShowQuestionsModal.call(event: event, action: action, trigger_id: trigger_id) | |
return true | |
end | |
attendee.status = action | |
ActiveRecord::Base.transaction do | |
attendee.save | |
responses&.each do |question_id, response| | |
attendee.event_question_responses.create(event_question_id: question_id, response: response) | |
end | |
end | |
if attendee.rsvp? | |
Slack::EventConfirmationMessageJob.perform_later(event.id, slack_user.id, 'rsvp') | |
SyncGcalEventJob.perform_later( | |
event: event, | |
action: 'update', | |
calendar_id: event.calendar_events.where(attendees_added: true).pluck(:calendar_id), | |
add_attendees: true, | |
) if event.calendar_events.exists? | |
end | |
end | |
private | |
attr_reader :event, :slack_user, :action, :trigger_id, :responses | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Slack::Rsvp::ShowQuestionsModal | |
def initialize(trigger_id, action, event) | |
@client = Slack::Web::Client.new(token: event.organization.slack_token) | |
@trigger_id = trigger_id | |
@event = event | |
@action = action | |
end | |
def self.call(trigger_id:, action:, event:) | |
new(trigger_id, action, event).call | |
end | |
def call | |
response = client.views_open(questions_modal(trigger_id)) | |
response.ok | |
end | |
private | |
attr_reader :client, :trigger_id, :action, :event | |
def questions_modal(trigger_id) | |
questions_list = [] | |
event.event_questions.each { |question| questions_list << question_block(question) } | |
{ | |
trigger_id: trigger_id, | |
view: { | |
type: 'modal', | |
callback_id: action, | |
private_metadata: "#{event.slug}", | |
title: { | |
type: 'plain_text', | |
text: 'Required Questions' | |
}, | |
submit: { | |
type: 'plain_text', | |
text: 'Submit' | |
}, | |
blocks: questions_list | |
} | |
} | |
end | |
def question_block(question) | |
{ | |
type: 'input', | |
block_id: "#{question.id}", | |
element: { | |
type: 'plain_text_input', | |
action_id: "#{question.id}" | |
}, | |
label: { | |
type: 'plain_text', | |
text: "#{question.question_text}" | |
} | |
} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Slack::Rsvp::ShowResponsesModal | |
def initialize(event, trigger_id) | |
@client = Slack::Web::Client.new(token: event.organization.slack_token) | |
@trigger_id = trigger_id | |
@event = event | |
end | |
def self.call(event:, trigger_id:) | |
new(event, trigger_id).call | |
end | |
def call | |
response = client.views_open(responses_modal(trigger_id)) | |
response.ok | |
end | |
private | |
attr_reader :client, :event, :trigger_id | |
def responses_modal(trigger_id) | |
{ | |
trigger_id: trigger_id, | |
view: { | |
type: 'modal', | |
callback_id: 'responses_modal', | |
title: { | |
type: 'plain_text', | |
text: 'Responses' | |
}, | |
blocks: [ | |
{ | |
type: 'section', | |
text: { | |
type: 'mrkdwn', | |
text: "*RSVP'd (#{SlackUser.rsvp(event).count})*\n\n#{SlackUser.rsvp(event).mention}" | |
} | |
}, | |
{ | |
type: 'divider' | |
}, | |
{ | |
type: 'section', | |
text: { | |
type: 'mrkdwn', | |
text: "*Maybe Attending (#{SlackUser.maybe_attending(event).count})*\n\n#{SlackUser.maybe_attending(event).mention}" | |
} | |
}, | |
{ | |
type: 'divider' | |
}, | |
{ | |
type: 'section', | |
text: { | |
type: 'mrkdwn', | |
text: "*Not Attending (#{SlackUser.not_attending(event).count})*\n\n#{SlackUser.not_attending(event).mention}" | |
} | |
} | |
] | |
} | |
} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
RSpec.describe SlackMessagesController, type: :controller do | |
login_user | |
let(:valid_slack_message_attributes) { FactoryBot.attributes_for(:slack_message) } | |
let(:invalid_slack_message_attributes) { valid_slack_message_attributes.merge(channel: nil) } | |
let(:org) { FactoryBot.create :organization, :with_slack_integrated } | |
let(:event) { FactoryBot.create :event, organization: org } | |
before :each do | |
Rails.application.routes.default_url_options[:host] = "fivetonine.test" | |
allow(controller).to receive(:current_tenant).and_return(org) | |
end | |
describe "GET #show" do | |
it 'returns a successful response' do | |
stub_request(:post, "https://slack.com/api/conversations.list").to_return(body: File.read('spec/fixtures/slack/conversations_list_response.json')) | |
get :show, params: { event_id: event.id }, xhr: true, format: 'js' | |
expect{ response }.not_to raise_error | |
end | |
end | |
describe "POST #create" do | |
before :each do | |
stub_request(:post, "https://slack.com/api/chat.postMessage").to_return(body: File.read('spec/fixtures/slack/rsvp/post_message_response.json')) | |
end | |
context 'with valid params' do | |
it "creates an slack message" do | |
expect{ | |
post :create, params: { event_id: event.id, slack_message: valid_slack_message_attributes }, format: 'js' | |
}.to change(SlackMessage.delivered, :count).by 1 | |
end | |
end | |
context 'with invalid params' do | |
it "should not create an slack message" do | |
expect { | |
post :create, params: { event_id: event.id, slack_message: invalid_slack_message_attributes }, format: 'js' | |
}.to change(SlackMessage, :count).by 0 | |
end | |
end | |
end | |
describe "POST #update" do | |
context 'with valid params' do | |
it "creates an slack message" do | |
message = FactoryBot.create(:slack_message, :scheduled, event: event) | |
old_channel = message.channel | |
expect{ | |
put :update, params: { event_id: event.id, id: message.id, slack_message: { channel: 'alpha' } }, format: 'js' | |
}.to change(SlackMessage.delivered, :count).by 0 | |
message.reload | |
expect(message.channel).to eq 'alpha' | |
expect(message.channel).not_to eq old_channel | |
end | |
end | |
context 'with invalid params' do | |
it "should not create an slack message" do | |
message = FactoryBot.create(:slack_message, :scheduled, event: event) | |
old_channel = message.channel | |
expect { | |
put :update, params: { event_id: event.id, id: message.id, slack_message: { channel: '' } }, format: 'js' | |
}.to change(SlackMessage, :count).by 0 | |
message.reload | |
expect(message.channel).to eq old_channel | |
end | |
end | |
end | |
describe "POST #destroy" do | |
it 'destroys the scheduled message' do | |
message = FactoryBot.create(:slack_message, :scheduled, event: event) | |
expect { | |
delete :destroy, params: { id: message.id, event_id: message.event.id } | |
}.to change(SlackMessage, :count).by -1 | |
expect(response).to redirect_to event_editor_path(event_id: message.event.id, tab: 'slack') | |
end | |
it 'does not destroys an already delivered message' do | |
stub_request(:post, "https://slack.com/api/chat.postMessage").to_return(body: File.read('spec/fixtures/slack/rsvp/post_message_response.json')) | |
message = FactoryBot.create(:slack_message, event: event) | |
expect { | |
delete :destroy, params: { id: message.id, event_id: message.event.id } | |
}.to change(SlackMessage, :count).by 0 | |
expect(response).to redirect_to event_editor_path(event_id: message.event.id, tab: 'slack') | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment