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
@@ -1,56 +1,3 @@
1
1
  Rails.application.routes.draw do
2
- # The priority is based upon order of creation: first created -> highest priority.
3
- # See how all your routes lay out with "rake routes".
4
-
5
- # You can have the root of your site routed with "root"
6
- # root 'welcome#index'
7
-
8
- # Example of regular route:
9
- # get 'products/:id' => 'catalog#view'
10
-
11
- # Example of named route that can be invoked with purchase_url(id: product.id)
12
- # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
13
-
14
- # Example resource route (maps HTTP verbs to controller actions automatically):
15
- # resources :products
16
-
17
- # Example resource route with options:
18
- # resources :products do
19
- # member do
20
- # get 'short'
21
- # post 'toggle'
22
- # end
23
- #
24
- # collection do
25
- # get 'sold'
26
- # end
27
- # end
28
-
29
- # Example resource route with sub-resources:
30
- # resources :products do
31
- # resources :comments, :sales
32
- # resource :seller
33
- # end
34
-
35
- # Example resource route with more complex sub-resources:
36
- # resources :products do
37
- # resources :comments
38
- # resources :sales do
39
- # get 'recent', on: :collection
40
- # end
41
- # end
42
-
43
- # Example resource route with concerns:
44
- # concern :toggleable do
45
- # post 'toggle'
46
- # end
47
- # resources :posts, concerns: :toggleable
48
- # resources :photos, concerns: :toggleable
49
-
50
- # Example resource route within a namespace:
51
- # namespace :admin do
52
- # # Directs /admin/products/* to Admin::ProductsController
53
- # # (app/controllers/admin/products_controller.rb)
54
- # resources :products
55
- # end
2
+ mount SendGridMailer::Engine => "/send_grid_mailer"
56
3
  end
@@ -0,0 +1,34 @@
1
+ test:
2
+ service: Disk
3
+ root: <%= Rails.root.join("tmp/storage") %>
4
+
5
+ local:
6
+ service: Disk
7
+ root: <%= Rails.root.join("storage") %>
8
+
9
+ # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10
+ # amazon:
11
+ # service: S3
12
+ # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13
+ # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14
+ # region: us-east-1
15
+ # bucket: your_own_bucket
16
+
17
+ # Remember not to checkin your GCS keyfile to a repository
18
+ # google:
19
+ # service: GCS
20
+ # project: your_project
21
+ # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22
+ # bucket: your_own_bucket
23
+
24
+ # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25
+ # microsoft:
26
+ # service: AzureStorage
27
+ # storage_account_name: your_account_name
28
+ # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29
+ # container: your_container_name
30
+
31
+ # mirror:
32
+ # service: Mirror
33
+ # primary: local
34
+ # mirrors: [ amazon, google, microsoft ]
data/spec/dummy/config.ru CHANGED
@@ -1,4 +1,6 @@
1
1
  # This file is used by Rack-based servers to start the application.
2
2
 
3
- require ::File.expand_path('../config/environment', __FILE__)
3
+ require_relative "config/environment"
4
+
4
5
  run Rails.application
6
+ Rails.application.load_server
@@ -4,7 +4,7 @@
4
4
  <title>The page you were looking for doesn't exist (404)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/404.html -->
59
59
  <div class="dialog">
60
60
  <div>
@@ -4,7 +4,7 @@
4
4
  <title>The change you wanted was rejected (422)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/422.html -->
59
59
  <div class="dialog">
60
60
  <div>
@@ -4,7 +4,7 @@
4
4
  <title>We're sorry, but something went wrong (500)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/500.html -->
59
59
  <div class="dialog">
60
60
  <div>
File without changes
@@ -1,23 +1,22 @@
1
1
  require "rails_helper"
2
2
 
3
3
  describe SendGridMailer::Definition do
4
- let(:personalization) { subject.send(:personalization) }
5
- let(:mail) { subject.send(:mail) }
4
+ let(:definition) { described_class.new }
5
+ let(:personalization) { definition.send(:personalization) }
6
+ let(:mail) { definition.send(:mail) }
6
7
 
7
8
  describe "#template_id" do
8
9
  it "sets tempalte id in sengrid mail object" do
9
- subject.set_template_id("X")
10
+ definition.set_template_id("X")
10
11
  expect(mail.template_id).to eq("X")
11
12
  end
12
13
  end
13
14
 
14
15
  describe "#substitute" do
15
- before do
16
- @substitution = subject.substitute("%subject%", "Hi!")
17
- end
16
+ let!(:substitution) { definition.substitute("%definition%", "Hi!") }
18
17
 
19
18
  it "creates substitution with valid data" do
20
- expect(@substitution.substitution).to eq("%subject%" => "Hi!")
19
+ expect(substitution).to eq("%definition%" => "Hi!")
21
20
  end
22
21
 
23
22
  it "adds substitution to personalization object" do
@@ -25,21 +24,43 @@ describe SendGridMailer::Definition do
25
24
  end
26
25
 
27
26
  it "adds substitution to collection" do
28
- subject.substitute("%body%", "blah")
27
+ definition.substitute("%body%", "blah")
29
28
  expect(personalization.substitutions.size).to eq(2)
30
29
  end
31
30
  end
32
31
 
32
+ describe "#dynamic_template_data" do
33
+ let!(:substitution) { definition.dynamic_template_data(key: 'value') }
34
+
35
+ it "creates substitution with valid data" do
36
+ expect(substitution).to eq(key: 'value')
37
+ end
38
+
39
+ it "adds substitution to personalization object" do
40
+ expect(personalization.dynamic_template_data.size).to eq(1)
41
+ end
42
+
43
+ it "add dynamic_data to data hash" do
44
+ definition.dynamic_template_data(other_key: 'other_value')
45
+ expect(personalization.dynamic_template_data.size).to eq(2)
46
+ end
47
+
48
+ it "merges new keys into dynamic_data hash" do
49
+ definition.dynamic_template_data(other_key: 'other_value')
50
+ expect(personalization.dynamic_template_data).to eq(key: 'value', other_key: 'other_value')
51
+ end
52
+ end
53
+
33
54
  describe "#set_sender" do
34
55
  it "adds sender to mail object" do
35
- subject.set_sender("sender@platan.us")
56
+ definition.set_sender("sender@platan.us")
36
57
  expect(mail.from).to eq("email" => "sender@platan.us")
37
58
  end
38
59
  end
39
60
 
40
61
  describe "#set_sender" do
41
62
  it "adds sender with format to mail object" do
42
- subject.set_sender("Sender Name <sender@platan.us>")
63
+ definition.set_sender("Sender Name <sender@platan.us>")
43
64
  expect(mail.from).to eq("email" => "sender@platan.us", "name" => "Sender Name")
44
65
  end
45
66
  end
@@ -49,57 +70,65 @@ describe SendGridMailer::Definition do
49
70
  let(:m2) { "ldlsegovia@gmail.com" }
50
71
 
51
72
  it "adds recipients using splat operator" do
52
- subject.set_recipients(:to, m1, m2)
73
+ definition.set_recipients(:to, m1, m2)
53
74
  expect(personalization.tos).to eq([{ "email" => m1 }, { "email" => m2 }])
54
75
  end
55
76
 
56
77
  it "adds recipients passing emails array" do
57
- subject.set_recipients(:to, [m1, m2])
78
+ definition.set_recipients(:to, [m1, m2])
58
79
  expect(personalization.tos).to eq([{ "email" => m1 }, { "email" => m2 }])
59
80
  end
60
81
 
61
82
  it "adds bcc recipient" do
62
- subject.set_recipients(:bcc, m1)
83
+ definition.set_recipients(:bcc, m1)
63
84
  expect(personalization.bccs).to eq([{ "email" => m1 }])
64
85
  end
65
86
 
66
87
  it "adds cc recipient" do
67
- subject.set_recipients(:cc, m1)
88
+ definition.set_recipients(:cc, m1)
68
89
  expect(personalization.ccs).to eq([{ "email" => m1 }])
69
90
  end
70
91
  end
71
92
 
72
- describe "#set_subject" do
73
- it "adds subject to personalization object" do
74
- subject.set_subject("Hi!")
93
+ describe "#set_definition" do
94
+ it "adds definition to personalization object" do
95
+ definition.set_subject("Hi!")
75
96
  expect(personalization.subject).to eq("Hi!")
76
97
  end
77
98
  end
78
99
 
79
100
  describe "#set_content" do
80
101
  it "adds content to mail object" do
81
- subject.set_content("X")
102
+ definition.set_content("X")
82
103
  expect(mail.contents).to eq([{ "type" => "text/plain", "value" => "X" }])
83
104
  end
84
105
 
85
106
  it "adds content with different type" do
86
- subject.set_content("X", "other/type")
107
+ definition.set_content("X", "other/type")
87
108
  expect(mail.contents).to eq([{ "type" => "other/type", "value" => "X" }])
88
109
  end
89
110
  end
90
111
 
91
112
  describe "#add_header" do
92
113
  it "adds headers to personalization object" do
93
- subject.add_header("HEADER1", "VALUE1")
94
- subject.add_header("HEADER2", "VALUE2")
114
+ definition.add_header("HEADER1", "VALUE1")
115
+ definition.add_header("HEADER2", "VALUE2")
95
116
  expect(personalization.headers).to eq("HEADER1" => "VALUE1", "HEADER2" => "VALUE2")
96
117
  end
97
118
  end
98
119
 
120
+ describe "#add_category" do
121
+ it "adds categories to mail object" do
122
+ definition.add_category("category1")
123
+ definition.add_category("category2")
124
+ expect(mail.categories).to eq(["category1", "category2"])
125
+ end
126
+ end
127
+
99
128
  describe "#add_attachment" do
100
129
  it "adds file to mail object" do
101
- file = File.read(fixture_file_upload("image.png", "image/png"))
102
- subject.add_attachment(file, "platanus.png", "image/png")
130
+ file = File.read(fixture_file_upload("spec/dummy/spec/assets/image.png"))
131
+ definition.add_attachment(file, "platanus.png", "image/png")
103
132
  attachment = mail.attachments.first
104
133
  expect(attachment["type"]).to match("image/png")
105
134
  expect(attachment["disposition"]).to match("inline")