<%= @content %>
\ No newline at end of file diff --git a/app/views/portal_mailer/generic_email.text.erb b/app/views/portal_mailer/generic_email.text.erb new file mode 100644 index 00000000..c39df4db --- /dev/null +++ b/app/views/portal_mailer/generic_email.text.erb @@ -0,0 +1 @@ +<%= @content %> \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index e9d8fdb8..41c7e633 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -39,4 +39,16 @@ # Raises error for missing translations # config.action_view.raise_on_missing_translations = true + + config.action_mailer.delivery_method = :smtp + # SMTP settings for gmail + config.action_mailer.smtp_settings = { + :address => "smtp.gmail.com", + :port => 587, + :user_name => ENV['gmail_username'], + :password => ENV['gmail_password'], + :authentication => "plain", + :enable_starttls_auto => true + } + end diff --git a/config/environments/production.rb b/config/environments/production.rb index 471ea5ec..c54c3287 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -76,4 +76,16 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + config.action_mailer.delivery_method = :smtp + # SMTP settings for gmail + config.action_mailer.smtp_settings = { + :address => "smtp.gmail.com", + :port => 587, + :user_name => ENV['gmail_username'], + :password => ENV['gmail_password'], + :authentication => "plain", + :enable_starttls_auto => true + } + end diff --git a/config/locales/de.events.yml b/config/locales/de.events.yml index c58af447..b4412f3d 100644 --- a/config/locales/de.events.yml +++ b/config/locales/de.events.yml @@ -14,6 +14,10 @@ de: occupied_places: one: '%{count} Platz belegt' other: '%{count} Plätze belegt' + unclassified_applications_left: 'Bewerbung(en) wurden noch nicht klassifiziert' + maximum_number_of_participants_exeeded: 'Maximale Teilnehmeranzahl wurde überschritten' + sending_acceptances: 'Zusagen verschicken' + sending_rejections: 'Absagen verschicken' participants: participants: "Teilnehmer" show_participants: "Teilnehmerliste" diff --git a/config/locales/de.yml b/config/locales/de.yml index 2840ab6d..be973ec0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -33,6 +33,7 @@ de: user_management: "Benutzerverwaltung" requests: "Anfragen" profile: "Mein Profil" + create_profile: "Mein Profil anlegen" settings: "Profilinfo" login: "Einloggen" logout: "Ausloggen" diff --git a/db/schema.rb b/db/schema.rb index 1f7bcb8a..f9edbef5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -14,8 +14,8 @@ ActiveRecord::Schema.define(version: 20161204205355) do create_table "agreement_letters", force: :cascade do |t| - t.integer "user_id" - t.integer "event_id" + t.integer "user_id", null: false + t.integer "event_id", null: false t.string "path", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false diff --git a/db/seeds.rb b/db/seeds.rb index e07b977d..3c66dcde 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -112,6 +112,7 @@ vegan: false, allergic: false, allergies: "", + status: ApplicationLetter.statuses[:pending], user: applicant, event: event ) diff --git a/spec/features/events_spec.rb b/spec/features/events_spec.rb index bb7e22dc..571b7bd6 100644 --- a/spec/features/events_spec.rb +++ b/spec/features/events_spec.rb @@ -22,6 +22,43 @@ expect(page).to have_css("div#occupied_places") end + scenario "logged in as Organizer I want to be unable to send emails if there is any unclassified application left" do + login(:organizer) + @event.update!(max_participants: 1) + @pupil = FactoryGirl.create(:profile) + @pupil.user.role = :pupil + @pending_application = FactoryGirl.create(:application_letter, :event => @event, :user => @pupil.user) + visit event_path(@event) + expect(page).to have_button(I18n.t('events.applicants_overview.sending_acceptances'), disabled: true) + expect(page).to have_button(I18n.t('events.applicants_overview.sending_rejections'), disabled: true) + end + + scenario "logged in as Organizer I want to be unable to send emails if there is a negative number of free places left" do + login(:organizer) + @event.update!(max_participants: 1) + 2.times do |n| + @pupil = FactoryGirl.create(:profile) + @pupil.user.role = :pupil + FactoryGirl.create(:application_letter_accepted, :event => @event, :user => @pupil.user) + end + visit event_path(@event) + expect(page).to have_button(I18n.t('events.applicants_overview.sending_acceptances'), disabled: true) + expect(page).to have_button(I18n.t('events.applicants_overview.sending_rejections'), disabled: true) + end + + scenario "logged in as Organizer I want to open a modal by clicking on sending emails" do + login(:organizer) + @event.update!(max_participants: 2) + 2.times do |n| + @pupil = FactoryGirl.create(:profile) + @pupil.user.role = :pupil + FactoryGirl.create(:application_letter_accepted, :event => @event, :user => @pupil.user) + end + visit event_path(@event) + click_button I18n.t('events.applicants_overview.sending_acceptances') + expect(page).to have_selector('div', :id => 'send-emails-modal') + end + scenario "logged in as Organizer I can see the correct count of free/occupied places" do login(:organizer) @event.update!(max_participants: 1) diff --git a/spec/mailers/portal_mailer_spec.rb b/spec/mailers/portal_mailer_spec.rb new file mode 100644 index 00000000..f877f7b8 --- /dev/null +++ b/spec/mailers/portal_mailer_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe PortalMailer, type: :mailer do + let(:recipients) { ['test@example.de', 'test2@example.de'] } + let(:reply_to) { ['test3@example.de'] } + let(:subject) {'Subject'} + let(:content) {'Awesome content'} + + describe 'mail sending with direct addressing' do + let(:mail) { described_class.generic_email(false, recipients, reply_to, subject, content).deliver_now } + + it 'sets the subject' do + expect(mail.subject).to eq(subject) + end + + it 'sets the receiver email' do + expect(mail.to).to eq(recipients) + end + + it 'sets the bcc receiver email' do + expect(mail.bcc).to be_nil + end + + it 'sets the reply_to email' do + expect(mail.reply_to).to eq(reply_to) + end + + it 'renders the sender email' do + expect(mail.from).to eq(['workshop.portal@gmail.com']) + end + + it 'sets the content' do + expect(mail.body.encoded).to match(content) + end + end + + describe 'mail sending with bcc addressing' do + let(:mail) { described_class.generic_email(true, recipients, reply_to, subject, content).deliver_now } + + it 'sets the receiver email' do + expect(mail.to).to be_nil + end + + it 'sets the bcc receiver email' do + expect(mail.bcc).to eq(recipients) + end + end +end diff --git a/spec/mailers/previews/portal_mailer_preview.rb b/spec/mailers/previews/portal_mailer_preview.rb new file mode 100644 index 00000000..956f1764 --- /dev/null +++ b/spec/mailers/previews/portal_mailer_preview.rb @@ -0,0 +1,6 @@ +# Preview all emails at http://localhost:3000/rails/mailers/portal_mailer +class PortalMailerPreview < ActionMailer::Preview + def generic_email_preview + PortalMailer.generic_email(true, "receiver@example.com", "reply@to.me", "This is subject", "This is content") + end +end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index ce4f203f..e25d29d1 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -59,6 +59,28 @@ end + it "checks if there are unclassified applications_letters" do + event = FactoryGirl.create(:event) + accepted_application_letter = FactoryGirl.create(:application_letter_accepted, :event => event, :user => FactoryGirl.create(:user)) + event.application_letters.push(accepted_application_letter) + expect(event.applications_classified?).to eq(true) + + pending_application_letter = FactoryGirl.create(:application_letter, :event => event, :user => FactoryGirl.create(:user)) + event.application_letters.push(pending_application_letter) + expect(event.applications_classified?).to eq(false) + end + + it "computes the email addresses of the accepted and the rejected applications" do + event = FactoryGirl.create(:event) + accepted_application_letter_1 = FactoryGirl.create(:application_letter_accepted, :event => event, :user => FactoryGirl.create(:user)) + accepted_application_letter_2 = FactoryGirl.create(:application_letter_accepted, :event => event, :user => FactoryGirl.create(:user)) + accepted_application_letter_3 = FactoryGirl.create(:application_letter_accepted, :event => event, :user => FactoryGirl.create(:user)) + rejected_application_letter = FactoryGirl.create(:application_letter_rejected, :event => event, :user => FactoryGirl.create(:user)) + [accepted_application_letter_1, accepted_application_letter_2, accepted_application_letter_3, rejected_application_letter].each { |letter| event.application_letters.push(letter) } + expect(event.email_adresses_of_accepted_applicants).to eq([accepted_application_letter_1.user.email, accepted_application_letter_2.user.email, accepted_application_letter_3.user.email].join(',')) + expect(event.email_adresses_of_rejected_applicants).to eq([rejected_application_letter.user.email].join(',')) + end + it "is either a camp or a workshop" do expect { FactoryGirl.build(:event, kind: :smth_invalid) }.to raise_error(ArgumentError) @@ -146,3 +168,4 @@ expect(event.compute_occupied_places).to eq(2) end end + diff --git a/spec/views/navbar_spec.rb b/spec/views/navbar_spec.rb index 25a5d73e..37d7ab50 100644 --- a/spec/views/navbar_spec.rb +++ b/spec/views/navbar_spec.rb @@ -21,11 +21,12 @@ render template: 'application/index', layout: 'layouts/application' end - it "shows Profilinfo, Meine Bewerbungen, Ausloggen in the dropdown" do + it "shows Profilinfo, Mein Profil anlegen, Meine Bewerbungen, Ausloggen in the dropdown" do expect(rendered).to have_css(".nav .dropdown-menu a", text: 'Profilinfo') + expect(rendered).to have_css(".nav .dropdown-menu a", text: 'Mein Profil anlegen') expect(rendered).to have_css(".nav .dropdown-menu a", text: 'Meine Bewerbungen') expect(rendered).to have_css(".nav .dropdown-menu a", text: 'Ausloggen') - expect(rendered).to have_css(".nav .dropdown-menu a", count: 3) + expect(rendered).to have_css(".nav .dropdown-menu a", count: 4) end end