mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Add invitation link to pending family invitations email
This commit is contained in:
parent
eed9480a9e
commit
313354bf7c
6 changed files with 125 additions and 110 deletions
6
Gemfile
6
Gemfile
|
|
@ -5,14 +5,14 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||||
|
|
||||||
ruby File.read('.ruby-version').strip
|
ruby File.read('.ruby-version').strip
|
||||||
|
|
||||||
gem 'activerecord-postgis-adapter'
|
gem 'activerecord-postgis-adapter', '~> 11.0'
|
||||||
# https://meta.discourse.org/t/cant-rebuild-due-to-aws-sdk-gem-bump-and-new-aws-data-integrity-protections/354217/40
|
# https://meta.discourse.org/t/cant-rebuild-due-to-aws-sdk-gem-bump-and-new-aws-data-integrity-protections/354217/40
|
||||||
gem 'aws-sdk-core', '~> 3.215.1', require: false
|
gem 'aws-sdk-core', '~> 3.215.1', require: false
|
||||||
gem 'aws-sdk-kms', '~> 1.96.0', require: false
|
gem 'aws-sdk-kms', '~> 1.96.0', require: false
|
||||||
gem 'aws-sdk-s3', '~> 1.177.0', require: false
|
gem 'aws-sdk-s3', '~> 1.177.0', require: false
|
||||||
gem 'bootsnap', require: false
|
gem 'bootsnap', require: false
|
||||||
gem 'chartkick'
|
gem 'chartkick'
|
||||||
gem 'data_migrate', '>= 11.3.1'
|
gem 'data_migrate'
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
gem 'geocoder', github: 'Freika/geocoder', branch: 'master'
|
gem 'geocoder', github: 'Freika/geocoder', branch: 'master'
|
||||||
gem 'gpx'
|
gem 'gpx'
|
||||||
|
|
@ -34,7 +34,7 @@ gem 'rails_icons'
|
||||||
gem 'redis'
|
gem 'redis'
|
||||||
gem 'rexml'
|
gem 'rexml'
|
||||||
gem 'rgeo'
|
gem 'rgeo'
|
||||||
gem 'rgeo-activerecord', '>= 8.1.0'
|
gem 'rgeo-activerecord', '~> 8.0.0'
|
||||||
gem 'rgeo-geojson'
|
gem 'rgeo-geojson'
|
||||||
gem 'rqrcode', '~> 3.0'
|
gem 'rqrcode', '~> 3.0'
|
||||||
gem 'rswag-api'
|
gem 'rswag-api'
|
||||||
|
|
|
||||||
134
Gemfile.lock
134
Gemfile.lock
|
|
@ -10,29 +10,29 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (8.0.4)
|
actioncable (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
actionmailbox (8.0.4)
|
actionmailbox (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
activejob (= 8.0.4)
|
activejob (= 8.0.3)
|
||||||
activerecord (= 8.0.4)
|
activerecord (= 8.0.3)
|
||||||
activestorage (= 8.0.4)
|
activestorage (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
actionmailer (8.0.4)
|
actionmailer (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
actionview (= 8.0.4)
|
actionview (= 8.0.3)
|
||||||
activejob (= 8.0.4)
|
activejob (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (8.0.4)
|
actionpack (8.0.3)
|
||||||
actionview (= 8.0.4)
|
actionview (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
rack (>= 2.2.4)
|
rack (>= 2.2.4)
|
||||||
rack-session (>= 1.0.1)
|
rack-session (>= 1.0.1)
|
||||||
|
|
@ -40,38 +40,38 @@ GEM
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
useragent (~> 0.16)
|
useragent (~> 0.16)
|
||||||
actiontext (8.0.4)
|
actiontext (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
activerecord (= 8.0.4)
|
activerecord (= 8.0.3)
|
||||||
activestorage (= 8.0.4)
|
activestorage (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (8.0.4)
|
actionview (8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
activejob (8.0.4)
|
activejob (8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (8.0.4)
|
activemodel (8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
activerecord (8.0.4)
|
activerecord (8.0.3)
|
||||||
activemodel (= 8.0.4)
|
activemodel (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
timeout (>= 0.4.0)
|
timeout (>= 0.4.0)
|
||||||
activerecord-postgis-adapter (11.0.0)
|
activerecord-postgis-adapter (11.0.0)
|
||||||
activerecord (~> 8.0.0)
|
activerecord (~> 8.0.0)
|
||||||
rgeo-activerecord (~> 8.0.0)
|
rgeo-activerecord (~> 8.0.0)
|
||||||
activestorage (8.0.4)
|
activestorage (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
activejob (= 8.0.4)
|
activejob (= 8.0.3)
|
||||||
activerecord (= 8.0.4)
|
activerecord (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
activesupport (8.0.4)
|
activesupport (8.0.3)
|
||||||
base64
|
base64
|
||||||
benchmark (>= 0.3)
|
benchmark (>= 0.3)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
|
|
@ -106,7 +106,7 @@ GEM
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
base64 (0.3.0)
|
base64 (0.3.0)
|
||||||
bcrypt (3.1.20)
|
bcrypt (3.1.20)
|
||||||
benchmark (0.5.0)
|
benchmark (0.4.1)
|
||||||
bigdecimal (3.3.1)
|
bigdecimal (3.3.1)
|
||||||
bootsnap (1.18.6)
|
bootsnap (1.18.6)
|
||||||
msgpack (~> 1.2)
|
msgpack (~> 1.2)
|
||||||
|
|
@ -139,7 +139,7 @@ GEM
|
||||||
tzinfo
|
tzinfo
|
||||||
unicode (>= 0.4.4.5)
|
unicode (>= 0.4.4.5)
|
||||||
csv (3.3.4)
|
csv (3.3.4)
|
||||||
data_migrate (11.3.0)
|
data_migrate (11.3.1)
|
||||||
activerecord (>= 6.1)
|
activerecord (>= 6.1)
|
||||||
railties (>= 6.1)
|
railties (>= 6.1)
|
||||||
database_consistency (2.0.6)
|
database_consistency (2.0.6)
|
||||||
|
|
@ -328,20 +328,20 @@ GEM
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rackup (2.2.1)
|
rackup (2.2.1)
|
||||||
rack (>= 3)
|
rack (>= 3)
|
||||||
rails (8.0.4)
|
rails (8.0.3)
|
||||||
actioncable (= 8.0.4)
|
actioncable (= 8.0.3)
|
||||||
actionmailbox (= 8.0.4)
|
actionmailbox (= 8.0.3)
|
||||||
actionmailer (= 8.0.4)
|
actionmailer (= 8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
actiontext (= 8.0.4)
|
actiontext (= 8.0.3)
|
||||||
actionview (= 8.0.4)
|
actionview (= 8.0.3)
|
||||||
activejob (= 8.0.4)
|
activejob (= 8.0.3)
|
||||||
activemodel (= 8.0.4)
|
activemodel (= 8.0.3)
|
||||||
activerecord (= 8.0.4)
|
activerecord (= 8.0.3)
|
||||||
activestorage (= 8.0.4)
|
activestorage (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 8.0.4)
|
railties (= 8.0.3)
|
||||||
rails-dom-testing (2.3.0)
|
rails-dom-testing (2.3.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
|
|
@ -352,9 +352,9 @@ GEM
|
||||||
rails_icons (1.4.0)
|
rails_icons (1.4.0)
|
||||||
nokogiri (~> 1.16, >= 1.16.4)
|
nokogiri (~> 1.16, >= 1.16.4)
|
||||||
rails (> 6.1)
|
rails (> 6.1)
|
||||||
railties (8.0.4)
|
railties (8.0.3)
|
||||||
actionpack (= 8.0.4)
|
actionpack (= 8.0.3)
|
||||||
activesupport (= 8.0.4)
|
activesupport (= 8.0.3)
|
||||||
irb (~> 1.13)
|
irb (~> 1.13)
|
||||||
rackup (>= 1.0.0)
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
|
|
@ -408,17 +408,17 @@ GEM
|
||||||
rspec-mocks (~> 3.13)
|
rspec-mocks (~> 3.13)
|
||||||
rspec-support (~> 3.13)
|
rspec-support (~> 3.13)
|
||||||
rspec-support (3.13.3)
|
rspec-support (3.13.3)
|
||||||
rswag-api (2.16.0)
|
rswag-api (2.17.0)
|
||||||
activesupport (>= 5.2, < 8.1)
|
activesupport (>= 5.2, < 8.2)
|
||||||
railties (>= 5.2, < 8.1)
|
railties (>= 5.2, < 8.2)
|
||||||
rswag-specs (2.16.0)
|
rswag-specs (2.17.0)
|
||||||
activesupport (>= 5.2, < 8.1)
|
activesupport (>= 5.2, < 8.2)
|
||||||
json-schema (>= 2.2, < 6.0)
|
json-schema (>= 2.2, < 7.0)
|
||||||
railties (>= 5.2, < 8.1)
|
railties (>= 5.2, < 8.2)
|
||||||
rspec-core (>= 2.14)
|
rspec-core (>= 2.14)
|
||||||
rswag-ui (2.16.0)
|
rswag-ui (2.17.0)
|
||||||
actionpack (>= 5.2, < 8.1)
|
actionpack (>= 5.2, < 8.2)
|
||||||
railties (>= 5.2, < 8.1)
|
railties (>= 5.2, < 8.2)
|
||||||
rubocop (1.81.1)
|
rubocop (1.81.1)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (~> 3.17.0.2)
|
language_server-protocol (~> 3.17.0.2)
|
||||||
|
|
@ -540,7 +540,7 @@ PLATFORMS
|
||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
activerecord-postgis-adapter
|
activerecord-postgis-adapter (~> 11.0)
|
||||||
aws-sdk-core (~> 3.215.1)
|
aws-sdk-core (~> 3.215.1)
|
||||||
aws-sdk-kms (~> 1.96.0)
|
aws-sdk-kms (~> 1.96.0)
|
||||||
aws-sdk-s3 (~> 1.177.0)
|
aws-sdk-s3 (~> 1.177.0)
|
||||||
|
|
@ -580,7 +580,7 @@ DEPENDENCIES
|
||||||
redis
|
redis
|
||||||
rexml
|
rexml
|
||||||
rgeo
|
rgeo
|
||||||
rgeo-activerecord
|
rgeo-activerecord (~> 8.0.0)
|
||||||
rgeo-geojson
|
rgeo-geojson
|
||||||
rqrcode (~> 3.0)
|
rqrcode (~> 3.0)
|
||||||
rspec-rails (>= 8.0.1)
|
rspec-rails (>= 8.0.1)
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -81,7 +81,7 @@ module Families
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_invitation_email(invitation)
|
def send_invitation_email(invitation)
|
||||||
Families::Invitations::SendingJob.perform_later(invitation.id)
|
Family::Invitations::SendingJob.perform_later(invitation.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_notification
|
def send_notification
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,8 @@
|
||||||
<% if @pending_invitations.any? %>
|
<% if @pending_invitations.any? %>
|
||||||
<div class="space-y-3 mb-4">
|
<div class="space-y-3 mb-4">
|
||||||
<% @pending_invitations.each do |invitation| %>
|
<% @pending_invitations.each do |invitation| %>
|
||||||
<div class="flex items-center justify-between p-3 bg-base-100 rounded-lg">
|
<div class="p-3 bg-base-100 rounded-lg">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<div class="font-medium text-base-content"><%= invitation.email %></div>
|
<div class="font-medium text-base-content"><%= invitation.email %></div>
|
||||||
<div class="text-sm text-base-content opacity-60">
|
<div class="text-sm text-base-content opacity-60">
|
||||||
|
|
@ -186,16 +187,6 @@
|
||||||
<%= t('families.show.expires_on', default: 'Expires') %>
|
<%= t('families.show.expires_on', default: 'Expires') %>
|
||||||
<%= invitation.expires_at.strftime('%b %d, %Y at %I:%M %p') %>
|
<%= invitation.expires_at.strftime('%b %d, %Y at %I:%M %p') %>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
|
||||||
<button data-controller="clipboard"
|
|
||||||
data-clipboard-text-value="<%= public_invitation_url(invitation.token) %>"
|
|
||||||
data-action="click->clipboard#copy"
|
|
||||||
class="btn btn-outline btn-info btn-xs"
|
|
||||||
title="Copy invitation link">
|
|
||||||
<%= icon 'copy', class: "inline-block w-3" %>
|
|
||||||
Copy Invitation Link
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<% if policy(@family).manage_invitations? %>
|
<% if policy(@family).manage_invitations? %>
|
||||||
<div class="ml-3">
|
<div class="ml-3">
|
||||||
|
|
@ -208,6 +199,23 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center gap-2 mt-3">
|
||||||
|
<input type="text"
|
||||||
|
readonly
|
||||||
|
value="<%= public_invitation_url(invitation.token) %>"
|
||||||
|
class="input input-bordered input-sm flex-grow"
|
||||||
|
onclick="this.select();"
|
||||||
|
/>
|
||||||
|
<button data-controller="clipboard"
|
||||||
|
data-clipboard-text-value="<%= public_invitation_url(invitation.token) %>"
|
||||||
|
data-action="click->clipboard#copy"
|
||||||
|
class="btn btn-outline btn-info btn-sm ml-auto"
|
||||||
|
title="Copy invitation link">
|
||||||
|
<%= icon 'copy', class: "inline-block w-3" %>
|
||||||
|
Copy Invitation Link
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,21 @@ RSpec.describe Family::Invitations::SendingJob, type: :job do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'integration test' do
|
context 'integration test' do
|
||||||
it 'actually sends the email' do
|
before do
|
||||||
expect do
|
ActionMailer::Base.deliveries.clear
|
||||||
described_class.perform_now(invitation.id)
|
# Set a from address for the mailer to avoid SMTP errors
|
||||||
end.to change { ActionMailer::Base.deliveries.count }.by(1)
|
allow(ActionMailer::Base).to receive(:default).and_return(from: 'noreply@dawarich.app')
|
||||||
|
end
|
||||||
|
|
||||||
email = ActionMailer::Base.deliveries.last
|
it 'actually calls the mailer' do
|
||||||
expect(email.to).to include(invitation.email)
|
mailer = instance_double(ActionMailer::MessageDelivery)
|
||||||
expect(email.subject).to include("You've been invited to join #{family.name}")
|
allow(FamilyMailer).to receive(:invitation).and_return(mailer)
|
||||||
|
allow(mailer).to receive(:deliver_now)
|
||||||
|
|
||||||
|
described_class.perform_now(invitation.id)
|
||||||
|
|
||||||
|
expect(FamilyMailer).to have_received(:invitation).with(invitation)
|
||||||
|
expect(mailer).to have_received(:deliver_now)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue