diff --git a/Gemfile b/Gemfile index b65e9a3..79e64f2 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,8 @@ gem "pg", "~> 1.1" # Use the Puma web server [https://github.com/puma/puma] gem "puma", "~> 5.0" +gem 'whenever', require: false + # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] gem "importmap-rails" @@ -60,6 +62,8 @@ group :development do # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" + gem "letter_opener" + # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] # gem "rack-mini-profiler" diff --git a/Gemfile.lock b/Gemfile.lock index 8db06e1..ae0dc07 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,6 +82,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) + chronic (0.10.2) concurrent-ruby (1.2.2) crass (1.0.6) date (3.3.3) @@ -107,6 +108,10 @@ GEM jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) + launchy (2.5.2) + addressable (~> 2.8) + letter_opener (1.8.1) + launchy (>= 2.2, < 3) loofah (2.19.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) @@ -228,12 +233,15 @@ GEM websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + whenever (1.0.0) + chronic (>= 0.6.3) xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.6.7) PLATFORMS arm64-darwin-21 + x86_64-darwin-19 x86_64-darwin-22 x86_64-linux @@ -245,6 +253,7 @@ DEPENDENCIES image_processing (~> 1.2) importmap-rails jbuilder + letter_opener name_of_person (~> 1.1) pagy (~> 6.0) pg (~> 1.1) @@ -259,6 +268,7 @@ DEPENDENCIES tzinfo-data web-console webdrivers + whenever RUBY VERSION ruby 3.2.1p31 diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3c34c81..2cde9ea 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" + default from: "no-reply@beginnerbounties.com" layout "mailer" end diff --git a/app/mailers/bounty_mailer.rb b/app/mailers/bounty_mailer.rb new file mode 100644 index 0000000..726b364 --- /dev/null +++ b/app/mailers/bounty_mailer.rb @@ -0,0 +1,7 @@ +class BountyMailer < ApplicationMailer + def open_bounty + @user = params[:user] + @bounties = params[:bounties] + mail(to: @user.email, subject: "Here are the latest open bounties") + end +end \ No newline at end of file diff --git a/app/models/bounty.rb b/app/models/bounty.rb index 02203e0..5f10fe0 100644 --- a/app/models/bounty.rb +++ b/app/models/bounty.rb @@ -5,6 +5,7 @@ class Bounty < ApplicationRecord has_rich_text :description scope :sorted, -> { in_order_of(:status, STATUSES).order(created_at: :desc) } + scope :open, -> { where(status: "open") } validates :amount, presence: true, numericality: {greater_than: 0, only_integer: true} validates :description, presence: true diff --git a/app/views/bounty_mailer/open_bounty.html.erb b/app/views/bounty_mailer/open_bounty.html.erb new file mode 100644 index 0000000..743e470 --- /dev/null +++ b/app/views/bounty_mailer/open_bounty.html.erb @@ -0,0 +1,6 @@ +
The open bounties for this week:
+ <% @bounties.each do |bounty| %> +Amount: <%= bounty.amount %>$
+<%= link_to "View the source code", bounty.url %>
+ <% end %> \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 8500f45..cc6462f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -39,7 +39,13 @@ # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false + + config.action_mailer.delivery_method = :letter_opener + config.action_mailer.default_url_options = { host: 'localhost', port: 3000} config.action_mailer.perform_caching = false + config.action_mailer.perform_deliveries = true + + #config.action_mailer.default_options = {from: 'test@example.com'} # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100644 index 0000000..456824a --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,3 @@ +every :sunday, at: '17:00 pm' do + rake "send_bounty_email" +end diff --git a/lib/tasks/bounty_tasks.rake b/lib/tasks/bounty_tasks.rake new file mode 100644 index 0000000..b1d1f1f --- /dev/null +++ b/lib/tasks/bounty_tasks.rake @@ -0,0 +1,9 @@ +desc 'send open bounties email' +task send_bounty_email: :environment do + @bounties = Bounty.open.last(15) + if @bounties.any? + User.find_each do |user| + BountyMailer.with(user: user, bounties: @bounties).open_bounty.deliver_later + end + end +end \ No newline at end of file diff --git a/test/fixtures/bounties.yml b/test/fixtures/bounties.yml index 9e28599..7acea3f 100644 --- a/test/fixtures/bounties.yml +++ b/test/fixtures/bounties.yml @@ -1,15 +1,13 @@ -# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html - one: user: one - title: MyString - url: MyString - amount: MyString - status: MyString + title: First Bounty + url: http://www.google.com/ + amount: 10 + status: open two: - user: two - title: MyString - url: MyString - amount: MyString - status: MyString + user: one + title: Second Bounty + url: http://www.firefox.com/ + amount: 32 + status: assigned diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index d7a3329..aa1c61d 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -1,11 +1,11 @@ -# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html +one: + email: first@example.com + first_name: first + last_name: Last + encrypted_password: foobar -# This model initially had no columns defined. If you add columns to the -# model remove the "{}" from the fixture names and add the columns immediately -# below each fixture, per the syntax in the comments below -# -one: {} -# column: value -# -two: {} -# column: value +two: + email: second@example.com + first_name: second + last_name: Doe + encrypted_password: foo \ No newline at end of file diff --git a/test/mailers/bounty_mailer_test.rb b/test/mailers/bounty_mailer_test.rb new file mode 100644 index 0000000..12d708e --- /dev/null +++ b/test/mailers/bounty_mailer_test.rb @@ -0,0 +1,17 @@ +require "test_helper" + +class BountyMailerTest < ActionMailer::TestCase + def setup + @user = users(:one) + @bounties = [bounties(:one)] + end + + test "bounty email" do + mail = BountyMailer.with(user: @user, bounties: @bounties).open_bounty + assert_equal "first@example.com", @user.email + assert_equal "Here are the latest open bounties", mail.subject + assert_equal ["first@example.com"], mail.to + assert_equal ["no-reply@beginnerbounties.com"], mail.from + assert_match bounties.first.title, mail.body.encoded + end +end \ No newline at end of file diff --git a/test/mailers/previews/bounty_mailer_preview.rb b/test/mailers/previews/bounty_mailer_preview.rb new file mode 100644 index 0000000..695070b --- /dev/null +++ b/test/mailers/previews/bounty_mailer_preview.rb @@ -0,0 +1,7 @@ +# Preview all emails at http://localhost:3000/rails/mailers/bounty_mailer +class BountyMailerPreview < ActionMailer::Preview + def open_bounty + BountyMailer.with(user: User.first, + bounties: Bounty.where(status: "open").last(15)).open_bounty + end +end