send_grid_mailer 1.1.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +102 -0
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.rubocop.yml +31 -591
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +28 -0
  7. data/README.md +46 -2
  8. data/lib/send_grid_mailer/api.rb +14 -9
  9. data/lib/send_grid_mailer/definition.rb +32 -14
  10. data/lib/send_grid_mailer/dev_deliverer.rb +72 -0
  11. data/lib/send_grid_mailer/engine.rb +4 -2
  12. data/lib/send_grid_mailer/logger.rb +10 -5
  13. data/lib/send_grid_mailer/mailer_base_ext.rb +13 -2
  14. data/lib/send_grid_mailer/version.rb +1 -1
  15. data/send_grid_mailer.gemspec +12 -6
  16. data/spec/dummy/Rakefile +1 -1
  17. data/spec/dummy/app/assets/config/manifest.js +3 -0
  18. data/spec/dummy/app/assets/stylesheets/application.css +3 -3
  19. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  20. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  21. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  22. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +3 -1
  23. data/spec/dummy/app/jobs/application_job.rb +7 -0
  24. data/spec/dummy/app/mailers/application_mailer.rb +1 -1
  25. data/spec/dummy/app/mailers/test_mailer.rb +12 -0
  26. data/spec/dummy/app/models/application_record.rb +3 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +10 -9
  28. data/spec/dummy/bin/rails +3 -3
  29. data/spec/dummy/bin/rake +2 -2
  30. data/spec/dummy/bin/setup +18 -14
  31. data/spec/dummy/config/application.rb +12 -22
  32. data/spec/dummy/config/boot.rb +3 -3
  33. data/spec/dummy/config/cable.yml +10 -0
  34. data/spec/dummy/config/database.yml +2 -2
  35. data/spec/dummy/config/environment.rb +1 -1
  36. data/spec/dummy/config/environments/development.rb +48 -18
  37. data/spec/dummy/config/environments/production.rb +63 -22
  38. data/spec/dummy/config/environments/test.rb +29 -12
  39. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  40. data/spec/dummy/config/initializers/assets.rb +4 -3
  41. data/spec/dummy/config/initializers/backtrace_silencers.rb +4 -3
  42. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  43. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  44. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  45. data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
  46. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
  47. data/spec/dummy/config/locales/en.yml +11 -1
  48. data/spec/dummy/config/puma.rb +43 -0
  49. data/spec/dummy/config/routes.rb +1 -54
  50. data/spec/dummy/config/storage.yml +34 -0
  51. data/spec/dummy/config.ru +3 -1
  52. data/spec/dummy/public/404.html +6 -6
  53. data/spec/dummy/public/422.html +6 -6
  54. data/spec/dummy/public/500.html +6 -6
  55. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  56. data/spec/dummy/public/apple-touch-icon.png +0 -0
  57. data/spec/dummy/spec/lib/send_grid_mailer/definition_spec.rb +52 -23
  58. data/spec/dummy/spec/mailers/test_mailer_spec.rb +547 -384
  59. data/spec/rails_helper.rb +5 -7
  60. metadata +124 -38
  61. data/.hound.yml +0 -4
  62. data/.travis.yml +0 -15
  63. data/spec/dummy/bin/bundle +0 -3
  64. data/spec/dummy/config/initializers/session_store.rb +0 -3
  65. data/spec/dummy/config/secrets.yml +0 -22
  66. data/spec/dummy/db/schema.rb +0 -16
  67. data/spec/dummy/spec/support/test_helpers.rb +0 -5
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3
1
+ 2.7
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ### v2.0.1
6
+
7
+ ##### Fixed
8
+
9
+ * :sendgrid_dev delivery method doesn't work with rails templates and missing api key.
10
+
11
+ ### v2.0.0
12
+
13
+ ##### Changed
14
+
15
+ * Replace travis with circleci.
16
+
17
+ ##### Removed
18
+
19
+ * Support for Ruby 2.5
20
+
21
+ ### v1.2.1
22
+
23
+ ##### Fixed
24
+
25
+ * :sendgrid_dev delivery method now works with Rails templates.
26
+
27
+ ### v1.2.0
28
+
29
+ ##### Added
30
+
31
+ * Add :sendgrid_dev delivery method
32
+
5
33
  ### v1.1.0
6
34
 
7
35
  ##### Added
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SendGrid Mailer
2
2
  [![Gem Version](https://badge.fury.io/rb/send_grid_mailer.svg)](https://badge.fury.io/rb/send_grid_mailer)
3
- [![Build Status](https://travis-ci.org/platanus/send_grid_mailer.svg?branch=master)](https://travis-ci.org/platanus/send_grid_mailer)
3
+ [![CircleCI](https://circleci.com/gh/platanus/send_grid_mailer.svg?style=shield)](https://app.circleci.com/pipelines/github/platanus/send_grid_mailer)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/platanus/send_grid_mailer/badge.svg)](https://coveralls.io/github/platanus/send_grid_mailer)
5
5
 
6
6
  Is an Action Mailer adapter for using SendGrid in a Rails application and
@@ -18,7 +18,16 @@ gem "send_grid_mailer"
18
18
  bundle install
19
19
  ```
20
20
 
21
- In your environment file you need to add:
21
+ We provide two delivery methods. For development environments, where sending the email is not required, you can use `:sendgrid_dev` to open it in the browser:
22
+
23
+ ```ruby
24
+ config.action_mailer.delivery_method = :sendgrid_dev
25
+ config.action_mailer.sendgrid_dev_settings = {
26
+ api_key: "YOUR-SENDGRID-API-KEY"
27
+ }
28
+ ```
29
+
30
+ Otherwise, you can use `:sendgrid` to actually send the email:
22
31
 
23
32
  ```ruby
24
33
  config.action_mailer.delivery_method = :sendgrid
@@ -27,6 +36,7 @@ config.action_mailer.sendgrid_settings = {
27
36
  }
28
37
  ```
29
38
 
39
+
30
40
  ## Usage
31
41
 
32
42
  With this adapter you will be able to:
@@ -134,6 +144,8 @@ end
134
144
 
135
145
  #### Set SendGrid's Template
136
146
 
147
+ To use this functionality you need to add the SENDGRID_API_KEY and, in case you do not add the api key, the gem would not search in Sendgrid for the template.
148
+
137
149
  ```ruby
138
150
  class TestMailer < ApplicationMailer
139
151
  def my_email
@@ -159,6 +171,28 @@ class TestMailer < ApplicationMailer
159
171
  end
160
172
  ```
161
173
 
174
+ #### Set Dynamic Template Data
175
+
176
+ ```ruby
177
+ class TestMailer < ApplicationMailer
178
+ def my_email
179
+ dynamic_template_data({ key1: "value1", key2: "value2" })
180
+ mail
181
+ end
182
+ end
183
+ ```
184
+
185
+ #### Add Category
186
+
187
+ ```ruby
188
+ class TestMailer < ApplicationMailer
189
+ def my_email
190
+ add_category("value")
191
+ mail
192
+ end
193
+ end
194
+ ```
195
+
162
196
  > Remember: you need to specify al least: `body`, `template_id` or a Rails template.
163
197
 
164
198
  ## Recipient Interceptor
@@ -195,6 +229,16 @@ bundle exec guard
195
229
 
196
230
  You need to put **all your tests** in the `/send_grid_mailer/spec/dummy/spec/` directory.
197
231
 
232
+ ## Publishing
233
+
234
+ On master/main branch...
235
+
236
+ 1. Change `VERSION` in `lib/send_grid_mailer/version.rb`.
237
+ 2. Change `Unreleased` title to current version in `CHANGELOG.md`.
238
+ 3. Commit new release. For example: `Releasing v0.1.0`.
239
+ 4. Create tag. For example: `git tag v0.1.0`.
240
+ 5. Push tag. For example: `git push origin v0.1.0`.
241
+
198
242
  ## Contributing
199
243
 
200
244
  1. Fork it
@@ -2,32 +2,37 @@ module SendGridMailer
2
2
  class Api
3
3
  include Logger
4
4
 
5
- SUCCESS_CODE = 202
6
-
7
5
  def initialize(api_key)
8
6
  @api_key = api_key || raise(SendGridMailer::InvalidApiKey)
9
7
  end
10
8
 
11
9
  def send_mail(sg_definition)
12
10
  response = sg_api.client.mail._('send').post(request_body: sg_definition.to_json)
13
- handle_response(response)
11
+ handle_response(response, :mail)
12
+ end
13
+
14
+ def get_template(sg_definition)
15
+ response = sg_api.client.templates._(sg_definition.mail.template_id).get()
16
+ handle_response(response, :template)
14
17
  end
15
18
 
16
19
  private
17
20
 
18
- def handle_response(response)
19
- if response.status_code.to_i != SUCCESS_CODE
21
+ def handle_response(response, api_call_type)
22
+ status_code = response.status_code.to_i
23
+ if status_code.between?(400, 600)
20
24
  errors = response_errors(response)
21
- log_api_error_response(response.status_code, errors)
22
- raise SendGridMailer::ApiError.new(response.status_code, errors)
25
+ log_api_error_response(status_code, errors, api_call_type)
26
+ raise SendGridMailer::ApiError.new(status_code, errors)
23
27
  end
24
28
 
25
- log_api_success_response(response)
29
+ log_api_success_response(status_code, api_call_type)
26
30
  response
27
31
  end
28
32
 
29
33
  def response_errors(response)
30
- JSON.parse(response.body)["errors"]
34
+ body = JSON.parse(response.body)
35
+ body["errors"] || [{ "message" => body["error"] }]
31
36
  end
32
37
 
33
38
  def sg_api
@@ -2,28 +2,36 @@ module SendGridMailer
2
2
  class Definition
3
3
  METHODS = [
4
4
  :substitute,
5
+ :dynamic_template_data,
5
6
  :set_template_id,
6
7
  :set_sender,
7
8
  :set_recipients,
8
9
  :set_subject,
9
10
  :set_content,
10
11
  :add_attachment,
11
- :add_header
12
+ :add_header,
13
+ :add_category
12
14
  ]
13
15
 
14
16
  def substitute(key, value, default = "")
15
- personalization.substitutions = SendGrid::Substitution.new(
16
- key: key, value: value.to_s || default
17
+ personalization.add_substitution(
18
+ SendGrid::Substitution.new(key: key, value: value.to_s || default)
17
19
  )
18
20
  end
19
21
 
22
+ def dynamic_template_data(object)
23
+ personalization.add_dynamic_template_data(object)
24
+ end
25
+
20
26
  def set_template_id(value)
21
27
  return unless value
28
+
22
29
  mail.template_id = value
23
30
  end
24
31
 
25
32
  def set_sender(email)
26
33
  return unless email
34
+
27
35
  matched_format = email.match(/<(.+)>/)
28
36
  if matched_format
29
37
  address = matched_format[1]
@@ -37,19 +45,22 @@ module SendGridMailer
37
45
  def set_recipients(mode, *emails)
38
46
  emails.flatten.each do |email|
39
47
  next unless email
40
- personalization.send("#{mode}=", SendGrid::Email.new(email: email))
48
+
49
+ personalization.send("add_#{mode}", SendGrid::Email.new(email: email))
41
50
  end
42
51
  end
43
52
 
44
53
  def set_subject(value)
45
54
  return unless value
55
+
46
56
  personalization.subject = value
47
57
  end
48
58
 
49
59
  def set_content(value, type = nil)
50
60
  return unless value
51
- type = "text/plain" unless type
52
- mail.contents = SendGrid::Content.new(type: type, value: value)
61
+
62
+ type ||= "text/plain"
63
+ mail.add_content(SendGrid::Content.new(type: type, value: value))
53
64
  end
54
65
 
55
66
  def add_attachment(file, name, type, disposition = "inline", content_id = nil)
@@ -59,16 +70,23 @@ module SendGridMailer
59
70
  attachment.filename = name
60
71
  attachment.disposition = disposition
61
72
  attachment.content_id = content_id
62
- mail.attachments = attachment
73
+ mail.add_attachment(attachment)
63
74
  end
64
75
 
65
76
  def add_header(key, value)
66
77
  return if !key || !value
67
- personalization.headers = SendGrid::Header.new(key: key, value: value)
78
+
79
+ personalization.add_header(SendGrid::Header.new(key: key, value: value))
80
+ end
81
+
82
+ def add_category(value)
83
+ return unless value
84
+
85
+ mail.add_category(SendGrid::Category.new(name: value))
68
86
  end
69
87
 
70
88
  def to_json
71
- mail.personalizations = personalization if personalization?
89
+ mail.add_personalization(personalization) if personalization?
72
90
  mail.to_json
73
91
  end
74
92
 
@@ -77,7 +95,7 @@ module SendGridMailer
77
95
  end
78
96
 
79
97
  def clean_recipients(mode)
80
- personalization.instance_variable_set("@#{mode}s", nil)
98
+ personalization.instance_variable_set("@#{mode}s", [])
81
99
  end
82
100
 
83
101
  def personalization
@@ -86,12 +104,12 @@ module SendGridMailer
86
104
 
87
105
  def personalization?; !personalization.to_json.empty? end
88
106
 
89
- def content?; !mail.contents.blank? end
107
+ def content?; mail.contents.present? end
90
108
 
91
- def sender?; !mail.from.blank? end
109
+ def sender?; mail.from.present? end
92
110
 
93
- def subject?; !personalization.subject.blank? end
111
+ def subject?; personalization.subject.present? end
94
112
 
95
- def template_id?; !mail.template_id.blank? end
113
+ def template_id?; mail.template_id.present? end
96
114
  end
97
115
  end
@@ -0,0 +1,72 @@
1
+ module SendGridMailer
2
+ class DevDeliverer
3
+ include InterceptorsHandler
4
+ include Logger
5
+ require "letter_opener"
6
+ require "handlebars"
7
+
8
+ def deliver!(sg_definition)
9
+ @sg_definition = sg_definition
10
+ execute_interceptors(@sg_definition)
11
+ log_definition(@sg_definition)
12
+ letter_opener_delivery_method.deliver!(mail)
13
+ end
14
+
15
+ private
16
+
17
+ def sg_api
18
+ @sg_api ||= Api.new(api_key)
19
+ end
20
+
21
+ def api_key
22
+ Rails.application.config.action_mailer.sendgrid_dev_settings[:api_key]
23
+ rescue
24
+ nil
25
+ end
26
+
27
+ def letter_opener_delivery_method
28
+ @letter_opener_delivery_method ||= LetterOpener::DeliveryMethod.new(location: dev_emails_location)
29
+ end
30
+
31
+ def dev_emails_location
32
+ Rails.application.config.action_mailer.sendgrid_dev_settings[:emails_location] || "/tmp/mails"
33
+ rescue
34
+ "/tmp/mails"
35
+ end
36
+
37
+ def parsed_template
38
+ return nil if api_key.blank?
39
+
40
+ template_response = sg_api.get_template(@sg_definition)
41
+ template_versions = JSON.parse(template_response.body)["versions"]
42
+ return if template_versions.blank?
43
+
44
+ template_active_version = template_versions.find { |version| version["active"] == 1 }
45
+ template_content = template_active_version["html_content"]
46
+ @sg_definition.personalization.substitutions.each { |k, v| template_content.gsub!(k, v) }
47
+ template = Handlebars::Context.new.compile(template_content)
48
+ template_content = template.call(@sg_definition.personalization.dynamic_template_data)
49
+ template_content
50
+ end
51
+
52
+ def emails(origin)
53
+ @emails ||= {}
54
+ return @emails[origin] if @emails.has_key?(origin)
55
+
56
+ @emails[origin] = @sg_definition.personalization.send(origin)&.map {|em| em["email"]}
57
+ end
58
+
59
+ def mail
60
+ template = (parsed_template || @sg_definition.mail.contents[0]['value']).html_safe
61
+ m = Mail.new
62
+ m.html_part = template
63
+ m.subject = @sg_definition.personalization.subject
64
+ m.from = @sg_definition.mail.from["email"] if @sg_definition.mail.from.present?
65
+ m.to = emails(:tos) if emails(:tos).present?
66
+ m.cc = emails(:ccs) if emails(:ccs).present?
67
+ m.bcc = emails(:bccs) if emails(:bccs).present?
68
+
69
+ m
70
+ end
71
+ end
72
+ end
@@ -4,7 +4,7 @@ module SendGridMailer
4
4
 
5
5
  config.generators do |g|
6
6
  g.test_framework :rspec, fixture: false
7
- g.fixture_replacement :factory_girl, dir: "spec/factories"
7
+ g.fixture_replacement :factory_bot, dir: "spec/factories"
8
8
  end
9
9
 
10
10
  initializer "initialize" do
@@ -17,9 +17,11 @@ module SendGridMailer
17
17
  require_relative "./mailer_base_ext"
18
18
  end
19
19
 
20
- initializer "add_sendgrid_deliverer", before: "action_mailer.set_configs" do
20
+ initializer "add_sendgrid_deliverers", before: "action_mailer.set_configs" do
21
+ require_relative "./dev_deliverer"
21
22
  require_relative "./deliverer"
22
23
  ActionMailer::Base.add_delivery_method(:sendgrid, SendGridMailer::Deliverer)
24
+ ActionMailer::Base.add_delivery_method(:sendgrid_dev, SendGridMailer::DevDeliverer)
23
25
  end
24
26
  end
25
27
  end
@@ -20,12 +20,12 @@ module SendGridMailer
20
20
  log(build_definition_message(data))
21
21
  end
22
22
 
23
- def log_api_success_response(response)
24
- log("The E-mail was successfully sent :)\nStatus Code: #{response.status_code}")
23
+ def log_api_success_response(status_code, api_call_type)
24
+ log("Succesfully called the SendGrid API :)\nStatus Code: #{status_code}")
25
25
  end
26
26
 
27
- def log_api_error_response(status_code, errors)
28
- msg = "The E-mail was not sent :(\nStatus Code: #{status_code}\nErrors:"
27
+ def log_api_error_response(status_code, errors, api_call_type)
28
+ msg = "There was a problem calling the SendGrid API :(\nStatus Code: #{status_code}\nErrors:"
29
29
  msg += log_errors(errors)
30
30
  log(msg)
31
31
  end
@@ -40,18 +40,20 @@ module SendGridMailer
40
40
  def build_definition_message(data)
41
41
  data = data.keys.map do |k|
42
42
  d = data[k].to_s
43
- "#{k}: #{(d.blank? ? '-' : d)}"
43
+ "#{k}: #{d.presence || '-'}"
44
44
  end.join("\n")
45
45
  end
46
46
 
47
47
  def log_email(email)
48
48
  return if email.blank?
49
+
49
50
  email["email"]
50
51
  end
51
52
 
52
53
  def log_emails(personalization, origin)
53
54
  emails = personalization.send(origin)
54
55
  return if emails.blank?
56
+
55
57
  emails.map do |email|
56
58
  log_email(email)
57
59
  end.join(", ")
@@ -59,6 +61,7 @@ module SendGridMailer
59
61
 
60
62
  def log_attachments(mail)
61
63
  return if mail.attachments.blank?
64
+
62
65
  mail.attachments.map do |f|
63
66
  "\n\t#{f['filename']}"
64
67
  end.join("")
@@ -66,6 +69,7 @@ module SendGridMailer
66
69
 
67
70
  def log_contents(mail)
68
71
  return if mail.contents.blank?
72
+
69
73
  mail.contents.map do |content|
70
74
  "\n\ttype: #{content['type']}\n\tvalue: #{content['value']}"
71
75
  end.join("")
@@ -73,6 +77,7 @@ module SendGridMailer
73
77
 
74
78
  def log_pairs(hash)
75
79
  return if hash.blank?
80
+
76
81
  hash.keys.map do |k|
77
82
  "\n\t#{k} => #{hash[k]}"
78
83
  end.join("")
@@ -23,7 +23,7 @@ module ActionMailer
23
23
 
24
24
  define_sg_mail(headers)
25
25
 
26
- SendGridMailer::Deliverer.new.deliver!(sg_definition)
26
+ deliverer&.new&.deliver!(sg_definition)
27
27
  end
28
28
 
29
29
  private
@@ -59,8 +59,10 @@ module ActionMailer
59
59
  def set_body(params)
60
60
  set_template_id(params[:template_id])
61
61
  return if sg_definition.template_id?
62
+
62
63
  set_content(params[:body], params[:content_type])
63
64
  return if sg_definition.content?
65
+
64
66
  set_body_from_tpl(params)
65
67
  end
66
68
 
@@ -82,8 +84,17 @@ module ActionMailer
82
84
  @sg_definition ||= SendGridMailer::Definition.new
83
85
  end
84
86
 
87
+ def deliverer
88
+ case self.class.delivery_method
89
+ when :sendgrid_dev
90
+ SendGridMailer::DevDeliverer
91
+ when :sendgrid
92
+ SendGridMailer::Deliverer
93
+ end
94
+ end
95
+
85
96
  def enabled_sendgrid?
86
- self.class.delivery_method == :sendgrid
97
+ [:sendgrid, :sendgrid_dev].include?(self.class.delivery_method)
87
98
  end
88
99
  end
89
100
  end
@@ -1,3 +1,3 @@
1
1
  module SendGridMailer
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.1"
3
3
  end
@@ -19,13 +19,19 @@ Gem::Specification.new do |s|
19
19
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  s.test_files = Dir["spec/**/*"]
21
21
 
22
+ s.add_dependency "handlebars", "~> 0.8.0"
23
+ s.add_dependency "letter_opener", "~> 1.7.0"
22
24
  s.add_dependency "rails", ">= 4.2.0"
23
- s.add_dependency "sendgrid-ruby", "~> 4.0", ">= 4.0.4"
25
+ s.add_dependency "sendgrid-ruby", "~> 5", ">= 5.3.0"
26
+
27
+ s.add_development_dependency "coveralls"
28
+ s.add_development_dependency "factory_bot_rails"
29
+ s.add_development_dependency "guard-rspec", "~> 4.7"
24
30
  s.add_development_dependency "pry"
25
31
  s.add_development_dependency "pry-rails"
26
- s.add_development_dependency "sqlite3"
27
- s.add_development_dependency "rspec-rails", "~> 3.4.0"
28
- s.add_development_dependency "guard-rspec", "~> 4.7"
29
- s.add_development_dependency "factory_girl_rails", "~> 4.6.0"
30
- s.add_development_dependency "coveralls"
32
+ s.add_development_dependency "rspec-rails", "~> 3.5.0"
33
+ s.add_development_dependency "rspec_junit_formatter"
34
+ s.add_development_dependency "rubocop", "0.65.0"
35
+ s.add_development_dependency "rubocop-rspec"
36
+ s.add_development_dependency "sqlite3", "~> 1.4"
31
37
  end
data/spec/dummy/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
- require File.expand_path('../config/application', __FILE__)
4
+ require_relative "config/application"
5
5
 
6
6
  Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
3
+ //= link send_grid_mailer_manifest.js
@@ -6,9 +6,9 @@
6
6
  * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
7
  *
8
8
  * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any styles
10
- * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
- * file per style scope.
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
12
  *
13
13
  *= require_tree .
14
14
  *= require_self
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -1,5 +1,2 @@
1
1
  class ApplicationController < ActionController::Base
2
- # Prevent CSRF attacks by raising an exception.
3
- # For APIs, you may want to use :null_session instead.
4
- protect_from_forgery with: :exception
5
2
  end
@@ -5,9 +5,11 @@
5
5
  // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
6
  //
7
7
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file.
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
9
  //
10
10
  // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
+ //= require rails-ujs
14
+ //= require activestorage
13
15
  //= require_tree .
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -1,4 +1,4 @@
1
1
  class ApplicationMailer < ActionMailer::Base
2
- default from: "from@example.com"
2
+ default from: 'from@example.com'
3
3
  layout 'mailer'
4
4
  end
@@ -78,4 +78,16 @@ class TestMailer < ApplicationMailer
78
78
  substitute "%key2%", "value2"
79
79
  mail(body: "X")
80
80
  end
81
+
82
+ def template_with_substitutions_email(value)
83
+ set_template_id("XXX")
84
+ substitute "%key%", value
85
+ mail(to: "r1@platan.us", body: "X")
86
+ end
87
+
88
+ def dynamic_template_email(value)
89
+ set_template_id("XXX")
90
+ dynamic_template_data(key: value)
91
+ mail(to: "r1@platan.us")
92
+ end
81
93
  end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -1,14 +1,15 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <title>Dummy</title>
5
- <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6
- <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
10
8
 
11
- <%= yield %>
9
+ <%= stylesheet_link_tag 'application', media: 'all' %>
10
+ </head>
12
11
 
13
- </body>
12
+ <body>
13
+ <%= yield %>
14
+ </body>
14
15
  </html>
data/spec/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
3
- require_relative '../config/boot'
4
- require 'rails/commands'
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
+ require_relative "../config/boot"
4
+ require "rails/commands"
data/spec/dummy/bin/rake CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative '../config/boot'
3
- require 'rake'
2
+ require_relative "../config/boot"
3
+ require "rake"
4
4
  Rake.application.run