send_grid_mailer 1.1.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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