diff options
18 files changed, 108 insertions, 58 deletions
diff --git a/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb b/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb index ebe83a9ec0..bf0fd562fe 100644 --- a/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb +++ b/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb @@ -38,7 +38,7 @@ module ActionMailbox # config.action_mailbox.ingress = :mailgun # # 3. {Configure Mailgun}[https://documentation.mailgun.com/en/latest/user_manual.html#receiving-forwarding-and-storing-messages] - # to forward inbound emails to `/rails/action_mailbox/mailgun/inbound_emails/mime`. + # to forward inbound emails to +/rails/action_mailbox/mailgun/inbound_emails/mime+. # # If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL # <tt>https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime</tt>. diff --git a/actionmailbox/app/jobs/action_mailbox/incineration_job.rb b/actionmailbox/app/jobs/action_mailbox/incineration_job.rb index 224c9329a5..1579a3c7c8 100644 --- a/actionmailbox/app/jobs/action_mailbox/incineration_job.rb +++ b/actionmailbox/app/jobs/action_mailbox/incineration_job.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true module ActionMailbox - # You can configure when this `IncinerationJob` will be run as a time-after-processing using the - # `config.action_mailbox.incinerate_after` or `ActionMailbox.incinerate_after` setting. + # You can configure when this +IncinerationJob+ will be run as a time-after-processing using the + # +config.action_mailbox.incinerate_after+ or +ActionMailbox.incinerate_after+ setting. # - # Since this incineration is set for the future, it'll automatically ignore any `InboundEmail`s + # Since this incineration is set for the future, it'll automatically ignore any <tt>InboundEmail</tt>s # that have already been deleted and discard itself if so. class IncinerationJob < ActiveJob::Base queue_as { ActionMailbox.queues[:incineration] } diff --git a/actionmailbox/app/models/action_mailbox/inbound_email.rb b/actionmailbox/app/models/action_mailbox/inbound_email.rb index 3a8dfd163c..023de19ccc 100644 --- a/actionmailbox/app/models/action_mailbox/inbound_email.rb +++ b/actionmailbox/app/models/action_mailbox/inbound_email.rb @@ -3,22 +3,22 @@ require "mail" module ActionMailbox - # The `InboundEmail` is an Active Record that keeps a reference to the raw email stored in Active Storage + # The +InboundEmail+ is an Active Record that keeps a reference to the raw email stored in Active Storage # and tracks the status of processing. By default, incoming emails will go through the following lifecycle: # # * Pending: Just received by one of the ingress controllers and scheduled for routing. # * Processing: During active processing, while a specific mailbox is running its #process method. # * Delivered: Successfully processed by the specific mailbox. - # * Failed: An exception was raised during the specific mailbox's execution of the `#process` method. + # * Failed: An exception was raised during the specific mailbox's execution of the +#process+ method. # * Bounced: Rejected processing by the specific mailbox and bounced to sender. # - # Once the `InboundEmail` has reached the status of being either `delivered`, `failed`, or `bounced`, - # it'll count as having been `#processed?`. Once processed, the `InboundEmail` will be scheduled for + # Once the +InboundEmail+ has reached the status of being either +delivered+, +failed+, or +bounced+, + # it'll count as having been +#processed?+. Once processed, the +InboundEmail+ will be scheduled for # automatic incineration at a later point. # - # When working with an `InboundEmail`, you'll usually interact with the parsed version of the source, - # which is available as a `Mail` object from `#mail`. But you can also access the raw source directly - # using the `#source` method. + # When working with an +InboundEmail+, you'll usually interact with the parsed version of the source, + # which is available as a +Mail+ object from +#mail+. But you can also access the raw source directly + # using the +#source+ method. # # Examples: # diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb index 825e300648..697331ede4 100644 --- a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb +++ b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -# Ensure that the `InboundEmail` is automatically scheduled for later incineration if the status has been -# changed to `processed`. The later incineration will be invoked at the time specified by the -# `ActionMailbox.incinerate_after` time using the `IncinerationJob`. +# Ensure that the +InboundEmail+ is automatically scheduled for later incineration if the status has been +# changed to +processed+. The later incineration will be invoked at the time specified by the +# +ActionMailbox.incinerate_after+ time using the +IncinerationJob+. module ActionMailbox::InboundEmail::Incineratable extend ActiveSupport::Concern diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb index 685f7fceb6..dabc83fae6 100644 --- a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb +++ b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true module ActionMailbox - # Command class for carrying out the actual incineration of the `InboundMail` that's been scheduled - # for removal. Before the incineration – which really is just a call to `#destroy!` – is run, we verify + # Command class for carrying out the actual incineration of the +InboundMail+ that's been scheduled + # for removal. Before the incineration – which really is just a call to +#destroy!+ – is run, we verify # that it's both eligible (by virtue of having already been processed) and time to do so (that is, - # the `InboundEmail` was processed after the `incinerate_after` time). + # the +InboundEmail+ was processed after the +incinerate_after+ time). class InboundEmail::Incineratable::Incineration def initialize(inbound_email) @inbound_email = inbound_email diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb b/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb index 2ad4525929..57b4a2445d 100644 --- a/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb +++ b/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -# The `Message-ID` as specified by rfc822 is supposed to be a unique identifier for that individual email. -# That makes it an ideal tracking token for debugging and forensics, just like `X-Request-Id` does for +# The +Message-ID+ as specified by rfc822 is supposed to be a unique identifier for that individual email. +# That makes it an ideal tracking token for debugging and forensics, just like +X-Request-Id+ does for # web request. # # If an inbound email does not, against the rfc822 mandate, specify a Message-ID, one will be generated -# using the approach from `Mail::MessageIdField`. +# using the approach from <tt>Mail::MessageIdField</tt>. module ActionMailbox::InboundEmail::MessageId extend ActiveSupport::Concern @@ -14,9 +14,9 @@ module ActionMailbox::InboundEmail::MessageId end class_methods do - # Create a new `InboundEmail` from the raw `source` of the email, which be uploaded as a Active Storage - # attachment called `raw_email`. Before the upload, extract the Message-ID from the `source` and set - # it as an attribute on the new `InboundEmail`. + # Create a new +InboundEmail+ from the raw +source+ of the email, which be uploaded as a Active Storage + # attachment called +raw_email+. Before the upload, extract the Message-ID from the +source+ and set + # it as an attribute on the new +InboundEmail+. def create_and_extract_message_id!(source, **options) create! options.merge(message_id: extract_message_id(source)) do |inbound_email| inbound_email.raw_email.attach io: StringIO.new(source), filename: "message.eml", content_type: "message/rfc822" diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb b/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb index 58d67eb20c..39565df166 100644 --- a/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb +++ b/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -# A newly received `InboundEmail` will not be routed synchronously as part of ingress controller's receival. -# Instead, the routing will be done asynchronously, using a `RoutingJob`, to ensure maximum parallel capacity. +# A newly received +InboundEmail+ will not be routed synchronously as part of ingress controller's receival. +# Instead, the routing will be done asynchronously, using a +RoutingJob+, to ensure maximum parallel capacity. # -# By default, all newly created `InboundEmail` records that have the status of `pending`, which is the default, +# By default, all newly created +InboundEmail+ records that have the status of +pending+, which is the default, # will be scheduled for automatic, deferred routing. module ActionMailbox::InboundEmail::Routable extend ActiveSupport::Concern @@ -12,12 +12,12 @@ module ActionMailbox::InboundEmail::Routable after_create_commit :route_later, if: :pending? end - # Enqueue a `RoutingJob` for this `InboundEmail`. + # Enqueue a +RoutingJob+ for this +InboundEmail+. def route_later ActionMailbox::RoutingJob.perform_later self end - # Route this `InboundEmail` using the routing rules declared on the `ApplicationMailbox`. + # Route this +InboundEmail+ using the routing rules declared on the +ApplicationMailbox+. def route ApplicationMailbox.route self end diff --git a/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb b/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb index 0124b4b98f..8cf621d7e3 100644 --- a/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb +++ b/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb @@ -4,8 +4,8 @@ class CreateActionMailboxTables < ActiveRecord::Migration[6.0] t.integer :status, default: 0, null: false t.string :message_id - t.datetime :created_at, precision: 6 - t.datetime :updated_at, precision: 6 + t.datetime :created_at, precision: 6, null: false + t.datetime :updated_at, precision: 6, null: false end end end diff --git a/actionmailbox/lib/action_mailbox/base.rb b/actionmailbox/lib/action_mailbox/base.rb index 4ac594b9f8..ff8587acd1 100644 --- a/actionmailbox/lib/action_mailbox/base.rb +++ b/actionmailbox/lib/action_mailbox/base.rb @@ -7,7 +7,7 @@ require "action_mailbox/routing" module ActionMailbox # The base class for all application mailboxes. Not intended to be inherited from directly. Inherit from - # `ApplicationMailbox` instead, as that's where the app-specific routing is configured. This routing + # +ApplicationMailbox+ instead, as that's where the app-specific routing is configured. This routing # is specified in the following ways: # # class ApplicationMailbox < ActionMailbox::Base @@ -27,15 +27,15 @@ module ActionMailbox # routing :all => :backstop # end # - # Application mailboxes need to overwrite the `#process` method, which is invoked by the framework after - # callbacks have been run. The callbacks available are: `before_processing`, `after_processing`, and - # `around_processing`. The primary use case is ensure certain preconditions to processing are fulfilled - # using `before_processing` callbacks. + # Application mailboxes need to overwrite the +#process+ method, which is invoked by the framework after + # callbacks have been run. The callbacks available are: +before_processing+, +after_processing+, and + # +around_processing+. The primary use case is ensure certain preconditions to processing are fulfilled + # using +before_processing+ callbacks. # - # If a precondition fails to be met, you can halt the processing using the `#bounced!` method, + # If a precondition fails to be met, you can halt the processing using the +#bounced!+ method, # which will silently prevent any further processing, but not actually send out any bounce notice. You # can also pair this behavior with the invocation of an Action Mailer class responsible for sending out - # an actual bounce email. This is done using the `#bounce_with` method, which takes the mail object returned + # an actual bounce email. This is done using the +#bounce_with+ method, which takes the mail object returned # by an Action Mailer method, like so: # # class ForwardsMailbox < ApplicationMailbox @@ -50,12 +50,12 @@ module ActionMailbox # end # # During the processing of the inbound email, the status will be tracked. Before processing begins, - # the email will normally have the `pending` status. Once processing begins, just before callbacks - # and the `#process` method is called, the status is changed to `processing`. If processing is allowed to - # complete, the status is changed to `delivered`. If a bounce is triggered, then `bounced`. If an unhandled - # exception is bubbled up, then `failed`. + # the email will normally have the +pending+ status. Once processing begins, just before callbacks + # and the +#process+ method is called, the status is changed to +processing+. If processing is allowed to + # complete, the status is changed to +delivered+. If a bounce is triggered, then +bounced+. If an unhandled + # exception is bubbled up, then +failed+. # - # Exceptions can be handled at the class level using the familiar `Rescuable` approach: + # Exceptions can be handled at the class level using the familiar +Rescuable+ approach: # # class ForwardsMailbox < ApplicationMailbox # rescue_from(ApplicationSpecificVerificationError) { bounced! } diff --git a/actionmailbox/lib/action_mailbox/router/route.rb b/actionmailbox/lib/action_mailbox/router/route.rb index b681eb7ea8..7e98e83382 100644 --- a/actionmailbox/lib/action_mailbox/router/route.rb +++ b/actionmailbox/lib/action_mailbox/router/route.rb @@ -2,7 +2,7 @@ module ActionMailbox # Encapsulates a route, which can then be matched against an inbound_email and provide a lookup of the matching - # mailbox class. See examples for the different route addresses and how to use them in the `ActionMailbox::Base` + # mailbox class. See examples for the different route addresses and how to use them in the +ActionMailbox::Base+ # documentation. class Router::Route attr_reader :address, :mailbox_name diff --git a/actionmailbox/lib/action_mailbox/routing.rb b/actionmailbox/lib/action_mailbox/routing.rb index 1ea96c8a9d..58462a44c6 100644 --- a/actionmailbox/lib/action_mailbox/routing.rb +++ b/actionmailbox/lib/action_mailbox/routing.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActionMailbox - # See `ActionMailbox::Base` for how to specify routing. + # See +ActionMailbox::Base+ for how to specify routing. module Routing extend ActiveSupport::Concern diff --git a/actionmailbox/lib/action_mailbox/test_helper.rb b/actionmailbox/lib/action_mailbox/test_helper.rb index 02c52fb779..0ec9152844 100644 --- a/actionmailbox/lib/action_mailbox/test_helper.rb +++ b/actionmailbox/lib/action_mailbox/test_helper.rb @@ -4,38 +4,38 @@ require "mail" module ActionMailbox module TestHelper - # Create an `InboundEmail` record using an eml fixture in the format of message/rfc822 + # Create an +InboundEmail+ record using an eml fixture in the format of message/rfc822 # referenced with +fixture_name+ located in +test/fixtures/files/fixture_name+. def create_inbound_email_from_fixture(fixture_name, status: :processing) create_inbound_email_from_source file_fixture(fixture_name).read, status: status end - # Create an `InboundEmail` by specifying it using `Mail.new` options. Example: + # Create an +InboundEmail+ by specifying it using +Mail.new+ options. Example: # # create_inbound_email_from_mail(from: "david@loudthinking.com", subject: "Hello!") def create_inbound_email_from_mail(status: :processing, **mail_options) create_inbound_email_from_source Mail.new(mail_options).to_s, status: status end - # Create an `InboundEmail` using the raw rfc822 `source` as text. + # Create an +InboundEmail+ using the raw rfc822 +source+ as text. def create_inbound_email_from_source(source, status: :processing) ActionMailbox::InboundEmail.create_and_extract_message_id! source, status: status end - # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_fixture` + # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_fixture+ # and immediately route it to processing. def receive_inbound_email_from_fixture(*args) create_inbound_email_from_fixture(*args).tap(&:route) end - # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_mail` + # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_mail+ # and immediately route it to processing. def receive_inbound_email_from_mail(**kwargs) create_inbound_email_from_mail(**kwargs).tap(&:route) end - # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_source` + # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_source+ # and immediately route it to processing. def receive_inbound_email_from_source(**kwargs) create_inbound_email_from_source(**kwargs).tap(&:route) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 95da4265a4..1457794354 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -85,10 +85,6 @@ *Yoshiyuki Kinjo* -* Remove undocumented `params` option from `url_for` helper. - - *Ilkka Oksanen* - * Encode Content-Disposition filenames on `send_data` and `send_file`. Previously, `send_data 'data', filename: "\u{3042}.txt"` sends `"filename=\"\u{3042}.txt\""` as Content-Disposition and it can be diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2966c969f6..972953d4f3 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -820,6 +820,10 @@ module ActionDispatch path, params = generate(route_name, path_options, recall) + if options.key? :params + params.merge! options[:params] + end + options[:path] = path options[:script_name] = script_name options[:params] = params diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 1a31c7dbb8..fcb8ae296b 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -133,6 +133,7 @@ module ActionDispatch # <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1. # * <tt>:port</tt> - Optionally specify the port to connect to. # * <tt>:anchor</tt> - An anchor name to be appended to the path. + # * <tt>:params</tt> - The query parameters to be appended to the path. # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/" # * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path. # diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 558e710df9..d8cea10153 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -193,7 +193,7 @@ class UrlOptionsTest < ActionController::TestCase action: "home", controller: "pages", only_path: true, - token: "secret" + params: { "token" => "secret" } } assert_equal "/home?token=secret", rs.url_for(options) diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index e381abee36..9222250b9c 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -354,6 +354,14 @@ module AbstractController assert_equal({ p2: "Y2" }.to_query, params[1]) end + def test_params_option + url = W.new.url_for(only_path: true, controller: "c", action: "a", params: { domain: "foo", id: "1" }) + params = extract_params(url) + assert_equal("/c/a?domain=foo&id=1", url) + assert_equal({ domain: "foo" }.to_query, params[0]) + assert_equal({ id: "1" }.to_query, params[1]) + end + def test_hash_parameter url = W.new.url_for(only_path: true, controller: "c", action: "a", query: { name: "Bob", category: "prof" }) params = extract_params(url) diff --git a/tasks/release.rb b/tasks/release.rb index 600e716a8d..214c1fd16e 100644 --- a/tasks/release.rb +++ b/tasks/release.rb @@ -173,15 +173,56 @@ namespace :all do end task verify: :install do - app_name = "pkg/verify-#{version}-#{Time.now.to_i}" + require "tmpdir" + + cd Dir.tmpdir + app_name = "verify-#{version}-#{Time.now.to_i}" sh "rails _#{version}_ new #{app_name} --skip-bundle" # Generate with the right version. cd app_name + substitute = -> (file_name, regex, replacement) do + File.write(file_name, File.read(file_name).sub(regex, replacement)) + end + # Replace the generated gemfile entry with the exact version. - File.write("Gemfile", File.read("Gemfile").sub(/^gem 'rails.*/, "gem 'rails', '#{version}'")) + substitute.call("Gemfile", /^gem 'rails.*/, "gem 'rails', '#{version}'") + substitute.call("Gemfile", /^# gem 'image_processing/, "gem 'image_processing") sh "bundle" + sh "rails action_mailbox:install" + sh "rails action_text:install" + + sh "rails generate scaffold user name description:text admin:boolean" + sh "rails db:migrate" + + # Replace the generated gemfile entry with the exact version. + substitute.call("app/models/user.rb", /end\n\z/, <<~CODE) + has_one_attached :avatar + has_rich_text :description + end + CODE - sh "rails generate scaffold user name admin:boolean && rails db:migrate" + substitute.call("app/views/users/_form.html.erb", /text_area :description %>\n <\/div>/, <<~CODE) + rich_text_area :description %>\n </div> + + <div class="field"> + Avatar: <%= form.file_field :avatar %> + </div> + CODE + + substitute.call("app/views/users/show.html.erb", /description %>\n<\/p>/, <<~CODE) + description %>\n</p> + + <p> + <%= image_tag @user.avatar.representation(resize_to_fit: [500, 500]) %> + </p> + CODE + + # Permit the avatar param. + substitute.call("app/controllers/users_controller.rb", /:admin/, ":admin, :avatar") + + if ENV["EDITOR"] + `#{ENV["EDITOR"]} #{File.expand_path(app_name)}` + end puts "Booting a Rails server. Verify the release by:" puts |