diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb index 0b93d0d29..ad1c31cb4 100644 --- a/app/controllers/collections_controller.rb +++ b/app/controllers/collections_controller.rb @@ -94,6 +94,8 @@ def download_all def share if share_message.save + recipient = User.find_by(email: params[:user]) + CollectionInvitationMailer.with(collection: @collection, recipient:).send_invitation.deliver_later redirect_to @collection, notice: t('.success_notice'), status: :see_other else redirect_to @collection, alert: share_message.errors.full_messages.join(', '), status: :see_other diff --git a/app/mailers/collection_invitation_mailer.rb b/app/mailers/collection_invitation_mailer.rb new file mode 100644 index 000000000..0a6012dae --- /dev/null +++ b/app/mailers/collection_invitation_mailer.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class CollectionInvitationMailer < ApplicationMailer + def send_invitation + @collection = params.fetch(:collection) + @recipient = params.fetch(:recipient) + + I18n.with_locale(@recipient.preferred_locale || I18n.default_locale) do + mail(to: @recipient.email, subject: t('collections.invitation_mailer.subject', collection: @collection.title)) + end + end +end diff --git a/app/views/collection_invitation_mailer/send_invitation.html.slim b/app/views/collection_invitation_mailer/send_invitation.html.slim new file mode 100644 index 000000000..f81d82f2c --- /dev/null +++ b/app/views/collection_invitation_mailer/send_invitation.html.slim @@ -0,0 +1,9 @@ + +h3 = t('collections.invitation_mailer.greeting', user: @recipient.name) +p = t('collections.invitation_mailer.invitation_message', collection: @collection.title) +p = t('collections.invitation_mailer.collaboration_details') +p = t('collections.invitation_mailer.view_collection_instructions') +p = link_to t('collections.invitation_mailer.view_collection'), collection_url(@collection) +p = t('collections.invitation_mailer.contact_info') +p = t('collections.invitation_mailer.thank_you') +p = t('collections.invitation_mailer.team_signature', app_name: t('application.name')) diff --git a/app/views/collection_invitation_mailer/send_invitation.text.slim b/app/views/collection_invitation_mailer/send_invitation.text.slim new file mode 100644 index 000000000..58d360010 --- /dev/null +++ b/app/views/collection_invitation_mailer/send_invitation.text.slim @@ -0,0 +1,13 @@ += t('collections.invitation_mailer.greeting', user: @recipient.name) + += t('collections.invitation_mailer.invitation_message', collection: @collection.title) + += t('collections.invitation_mailer.collaboration_details') + += t('collections.invitation_mailer.view_collection_instructions') += collection_url(@collection) + += t('collections.invitation_mailer.contact_info') + += t('collections.invitation_mailer.thank_you') += t('collections.invitation_mailer.team_signature', app_name: t('application.name')) diff --git a/config/locales/de/views/application.yml b/config/locales/de/views/application.yml index 692084592..ce7cb606b 100644 --- a/config/locales/de/views/application.yml +++ b/config/locales/de/views/application.yml @@ -16,6 +16,7 @@ de: markdown_editor: collapse: Editor zuklappen expand: Editor aufklappen + name: CodeHarbor navigation: rails_admin: Rails Admin session: diff --git a/config/locales/de/views/collections.yml b/config/locales/de/views/collections.yml index ee637c159..c8309f4c7 100644 --- a/config/locales/de/views/collections.yml +++ b/config/locales/de/views/collections.yml @@ -18,6 +18,16 @@ de: mine: Meine Sammlungen public: Öffentliche Sammlungen view_shared: Geteilte Sammlung anzeigen + invitation_mailer: + collaboration_details: Diese Zusammenarbeit ermöglicht es Ihnen, zum Inhalt dieser Sammlung beizutragen und bei der Verwaltung zu helfen. + contact_info: Wenn Sie Fragen zu dieser Einladung oder Ihrer Rolle als Mitarbeiter haben, wenden Sie sich bitte direkt an den Besitzer der Sammlung. + greeting: Hallo %{user}, + invitation_message: Sie wurden eingeladen, an der Sammlung "%{collection}" mitzuarbeiten. + subject: 'Einladung zur Sammlung: %{collection}' + team_signature: "%{app_name} Team" + thank_you: Vielen Dank, + view_collection: Sammlung anzeigen + view_collection_instructions: 'Um die Sammlung anzuzeigen und mit Ihrer Zusammenarbeit zu beginnen, klicken Sie auf den Link unten:' new: header: Neue Sammlung shared: diff --git a/config/locales/en/views/application.yml b/config/locales/en/views/application.yml index abddf891d..bc797d490 100644 --- a/config/locales/en/views/application.yml +++ b/config/locales/en/views/application.yml @@ -16,6 +16,7 @@ en: markdown_editor: collapse: Collapse editor expand: Expand editor + name: CodeHarbor navigation: rails_admin: Rails admin session: diff --git a/config/locales/en/views/collections.yml b/config/locales/en/views/collections.yml index cb1eb0371..0c29be47f 100644 --- a/config/locales/en/views/collections.yml +++ b/config/locales/en/views/collections.yml @@ -18,6 +18,16 @@ en: mine: My Collections public: Public Collections view_shared: View Shared Collection + invitation_mailer: + collaboration_details: This collaboration will allow you to contribute to and help manage this collection's content. + contact_info: If you have any questions about this invitation or your role as a collaborator, please contact the collection owner directly. + greeting: Hi %{user}, + invitation_message: You've been invited to collaborate on the collection "%{collection}". + subject: 'Invitation to collection: %{collection}' + team_signature: "%{app_name} Team" + thank_you: Thank you, + view_collection: View collection + view_collection_instructions: 'To view the collection and get started with your collaboration, click the link below:' new: header: New Collection shared: diff --git a/spec/controllers/collections_controller_spec.rb b/spec/controllers/collections_controller_spec.rb index 7051f25be..68716f25b 100644 --- a/spec/controllers/collections_controller_spec.rb +++ b/spec/controllers/collections_controller_spec.rb @@ -440,11 +440,27 @@ let(:params) { {id: collection.id, user: recipient.email} } let(:recipient) { create(:user) } + let(:mailer) { double('Mailer', send_invitation: delivery) } # rubocop:disable RSpec/VerifiedDoubles + let(:delivery) { instance_double(ActionMailer::MessageDelivery) } + + before do + allow(CollectionInvitationMailer).to receive(:with).and_return(mailer) + allow(mailer).to receive(:send_invitation).and_return(delivery) + allow(delivery).to receive(:deliver_later) + end + shared_examples 'success' do it 'creates a message' do expect { post_request }.to change(Message, :count).by(1) end + it 'sends an invitation email' do + post_request + expect(CollectionInvitationMailer).to have_received(:with).with({collection:, recipient:}) + expect(mailer).to have_received(:send_invitation) + expect(delivery).to have_received(:deliver_later) + end + it 'redirects to collection' do post_request expect(response).to redirect_to collection @@ -460,6 +476,11 @@ expect { post_request }.not_to change(Message, :count) end + it 'does not send an invitation email' do + post_request + expect(CollectionInvitationMailer).not_to have_received(:with) + end + it 'redirects to collection' do post_request expect(response).to redirect_to collection diff --git a/spec/mailers/collection_invitation_mailer_spec.rb b/spec/mailers/collection_invitation_mailer_spec.rb new file mode 100644 index 000000000..365c1d3b6 --- /dev/null +++ b/spec/mailers/collection_invitation_mailer_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe CollectionInvitationMailer do + describe '#send_invitation' do + subject(:invitation_email) { described_class.with(collection:, recipient: user).send_invitation } + + let(:collection) { create(:collection) } + let(:user) { create(:user) } + + it 'sends an email to the correct recipient' do + expect(invitation_email.to).to include(user.email) + end + + it 'has the correct subject' do + expect(invitation_email.subject).to include(collection.title) + end + + it 'contains the correct content' do + expect(invitation_email.body.encoded).to include(user.name) + expect(invitation_email.body.encoded).to include(collection.title) + expect(invitation_email.body.encoded).to include('collaborate') + end + + context 'with different locales' do + before do + user.update(preferred_locale: 'de') + end + + it 'uses the user\'s preferred locale' do + expect(invitation_email.body.encoded).to include('Sammlung') + expect(invitation_email.subject).to include('Einladung zur Sammlung') + end + end + end +end diff --git a/spec/mailers/previews/collection_invitation_mailer_preview.rb b/spec/mailers/previews/collection_invitation_mailer_preview.rb new file mode 100644 index 000000000..6bf2291fe --- /dev/null +++ b/spec/mailers/previews/collection_invitation_mailer_preview.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'factory_bot_rails' + +class CollectionInvitationMailerPreview < ActionMailer::Preview + def send_invitation + collection = FactoryBot.build(:collection, id: 1) + user = FactoryBot.build(:user, id: 2) + CollectionInvitationMailer.send_invitation(collection, user) + end +end