mailkick 0.3.1 → 1.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -18
- data/LICENSE.txt +1 -1
- data/README.md +153 -85
- data/app/controllers/mailkick/subscriptions_controller.rb +38 -20
- data/app/models/mailkick/opt_out.rb +1 -1
- data/app/models/mailkick/subscription.rb +9 -0
- data/app/views/mailkick/subscriptions/show.html.erb +1 -1
- data/lib/generators/mailkick/install_generator.rb +4 -21
- data/lib/generators/mailkick/templates/install.rb.tt +11 -0
- data/lib/mailkick.rb +23 -69
- data/lib/mailkick/engine.rb +0 -4
- data/lib/mailkick/legacy.rb +70 -0
- data/lib/mailkick/model.rb +11 -21
- data/lib/mailkick/service.rb +1 -16
- data/lib/mailkick/service/aws_ses.rb +47 -0
- data/lib/mailkick/service/postmark.rb +41 -0
- data/lib/mailkick/service/sendgrid.rb +4 -1
- data/lib/mailkick/service/sendgrid_v2.rb +52 -0
- data/lib/mailkick/url_helper.rb +8 -0
- data/lib/mailkick/version.rb +1 -1
- metadata +20 -184
- data/.gitignore +0 -25
- data/.travis.yml +0 -16
- data/Gemfile +0 -6
- data/Rakefile +0 -9
- data/app/helpers/mailkick/url_helper.rb +0 -15
- data/lib/generators/mailkick/templates/install.rb +0 -14
- data/mailkick.gemspec +0 -32
- data/test/gemfiles/actionmailer42.gemfile +0 -6
- data/test/gemfiles/actionmailer50.gemfile +0 -6
- data/test/gemfiles/actionmailer51.gemfile +0 -6
- data/test/internal/app/mailers/user_mailer.rb +0 -7
- data/test/internal/app/models/user.rb +0 -3
- data/test/internal/app/views/user_mailer/welcome.html.erb +0 -1
- data/test/internal/app/views/user_mailer/welcome.text.erb +0 -1
- data/test/internal/config/database.yml +0 -3
- data/test/internal/db/schema.rb +0 -16
- data/test/mailkick_test.rb +0 -29
- data/test/test_helper.rb +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ff139814252a1c4ec153cc81f311dd5d8c1745a4970aaab8cb2164df4d4692d
|
|
4
|
+
data.tar.gz: 1e4700dc2dbb96dcb09c4c79c00a837de387c8712db72c3bc13150ea94355da2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f28ec4a1bb1fa022ad4bd9a250a45650562db467a7c6d14f0150e5f9c8137cd766376a605c0304092ff7036d2efca22ae95e3d61e5693d40f616205b54aedb72
|
|
7
|
+
data.tar.gz: 5eb0a1544b00da879c77c2919501c2b21f6c4916e7bc1b710ad271c33ba6cd9cd6607d5d8c06f64380ce825f11187ff841deb21c58cd9ee4a8af3536ff3f594b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,79 +1,102 @@
|
|
|
1
|
-
## 0.
|
|
1
|
+
## 1.0.0 (2021-06-03)
|
|
2
|
+
|
|
3
|
+
- Switched from opt-outs to subscriptions
|
|
4
|
+
|
|
5
|
+
## 0.4.3 (2020-11-01)
|
|
6
|
+
|
|
7
|
+
- Added support for AWS SES
|
|
8
|
+
|
|
9
|
+
## 0.4.2 (2020-04-06)
|
|
10
|
+
|
|
11
|
+
- Added support for official SendGrid gem
|
|
12
|
+
- Fixed deprecation warning
|
|
13
|
+
|
|
14
|
+
## 0.4.1 (2019-10-27)
|
|
15
|
+
|
|
16
|
+
- Added Postmark support
|
|
17
|
+
|
|
18
|
+
## 0.4.0 (2019-07-15)
|
|
19
|
+
|
|
20
|
+
- Fixed error with model methods and `email_key` option
|
|
21
|
+
- Fixed bug with `opted_out` scope
|
|
22
|
+
- Dropped support for Action Mailer 4.2
|
|
23
|
+
|
|
24
|
+
## 0.3.1 (2018-04-21)
|
|
2
25
|
|
|
3
26
|
- Fixed `Secret should not be nil` error in Rails 5.2
|
|
4
27
|
- Gracefully handle missing email
|
|
5
28
|
- Added `user` option to `mailkick_unsubscribe_url`
|
|
6
29
|
|
|
7
|
-
## 0.3.0
|
|
30
|
+
## 0.3.0 (2018-04-20)
|
|
8
31
|
|
|
9
32
|
- Improved performance
|
|
10
33
|
- Fixed `Subscription not found` for Rails 5.2
|
|
11
34
|
- Use `references` in migration
|
|
12
35
|
- Use `smtp_settings[:domain]` for Mailgun
|
|
13
|
-
- Dropped support for
|
|
36
|
+
- Dropped support for Action Mailer < 4.2
|
|
14
37
|
|
|
15
|
-
## 0.2.1
|
|
38
|
+
## 0.2.1 (2017-10-30)
|
|
16
39
|
|
|
17
40
|
- Fixed errors with Rails 5+
|
|
18
41
|
- Fixed errors with the latest version of Gibbon
|
|
19
42
|
|
|
20
|
-
## 0.2.0
|
|
43
|
+
## 0.2.0 (2017-05-01)
|
|
21
44
|
|
|
22
45
|
- Added support for Rails 5.1
|
|
23
46
|
|
|
24
|
-
## 0.1.6
|
|
47
|
+
## 0.1.6 (2017-01-10)
|
|
25
48
|
|
|
26
49
|
- Fixed error with frozen strings
|
|
27
50
|
|
|
28
|
-
## 0.1.5
|
|
51
|
+
## 0.1.5 (2016-12-06)
|
|
29
52
|
|
|
30
53
|
- Use `safely`
|
|
31
54
|
- Only discover services if not manually set
|
|
32
55
|
- Added `mount` option
|
|
33
56
|
|
|
34
|
-
## 0.1.4
|
|
57
|
+
## 0.1.4 (2016-02-20)
|
|
35
58
|
|
|
36
59
|
- Use `Module#prepend` instead of `alias_method_chain`
|
|
37
60
|
|
|
38
|
-
## 0.1.3
|
|
61
|
+
## 0.1.3 (2015-06-29)
|
|
39
62
|
|
|
40
63
|
- Fixed issue with double escaping tokens
|
|
41
64
|
|
|
42
|
-
## 0.1.2
|
|
65
|
+
## 0.1.2 (2015-06-07)
|
|
43
66
|
|
|
44
67
|
- Added support for Mailgun
|
|
45
68
|
|
|
46
|
-
## 0.1.1
|
|
69
|
+
## 0.1.1 (2015-01-31)
|
|
47
70
|
|
|
48
71
|
- Fixed tokens with `+` in them
|
|
49
72
|
|
|
50
|
-
## 0.1.0
|
|
73
|
+
## 0.1.0 (2014-08-31)
|
|
51
74
|
|
|
52
75
|
- Fixed secret token for Rails 4.1
|
|
53
76
|
|
|
54
|
-
## 0.0.6
|
|
77
|
+
## 0.0.6 (2014-05-09)
|
|
55
78
|
|
|
56
79
|
- Rails 3 fix
|
|
57
80
|
|
|
58
|
-
## 0.0.5
|
|
81
|
+
## 0.0.5 (2014-05-05)
|
|
59
82
|
|
|
60
83
|
- Fixed bug with subscriptions page
|
|
61
84
|
|
|
62
|
-
## 0.0.4
|
|
85
|
+
## 0.0.4 (2014-05-05)
|
|
63
86
|
|
|
64
87
|
- Added `email_key` option to `mailkick_user`
|
|
65
88
|
|
|
66
|
-
## 0.0.3
|
|
89
|
+
## 0.0.3 (2014-05-04)
|
|
67
90
|
|
|
68
91
|
- Added support for multiple lists
|
|
69
92
|
- Changed `mailkick_user` method names - sorry early adopters :(
|
|
70
93
|
|
|
71
|
-
## 0.0.2
|
|
94
|
+
## 0.0.2 (2014-05-04)
|
|
72
95
|
|
|
73
96
|
- Added Mailchimp service
|
|
74
97
|
- Fixed Mandrill service
|
|
75
98
|
- Added `uniq` to `subscribed` scope
|
|
76
99
|
|
|
77
|
-
## 0.0.1
|
|
100
|
+
## 0.0.1 (2014-05-04)
|
|
78
101
|
|
|
79
102
|
- First release
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# Mailkick
|
|
2
2
|
|
|
3
|
-
Email subscriptions
|
|
3
|
+
Email subscriptions for Rails
|
|
4
4
|
|
|
5
5
|
- Add one-click unsubscribe links to your emails
|
|
6
6
|
- Fetch bounces and spam reports from your email service
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
**Mailkick 1.0 was recently released** - see [how to upgrade](#upgrading)
|
|
8
9
|
|
|
9
10
|
:postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for analytics
|
|
10
11
|
|
|
11
|
-
[](https://github.com/ankane/mailkick/actions)
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
@@ -18,191 +19,249 @@ Add this line to your application’s Gemfile:
|
|
|
18
19
|
gem 'mailkick'
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
And run the generator. This creates a
|
|
22
|
+
And run the generator. This creates a table to store subscriptions.
|
|
22
23
|
|
|
23
24
|
```sh
|
|
25
|
+
bundle install
|
|
24
26
|
rails generate mailkick:install
|
|
25
27
|
rails db:migrate
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
Add an unsubscribe link to your emails.
|
|
30
|
+
## Getting Started
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Add `has_subscriptions` to your user model:
|
|
33
33
|
|
|
34
|
-
```
|
|
35
|
-
|
|
34
|
+
```ruby
|
|
35
|
+
class User < ApplicationRecord
|
|
36
|
+
has_subscriptions
|
|
37
|
+
end
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
Subscribe to a list
|
|
39
41
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
+
```ruby
|
|
43
|
+
user.subscribe("sales")
|
|
42
44
|
```
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
Unsubscribe from a list
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
rails generate mailkick:views
|
|
48
|
+
```ruby
|
|
49
|
+
user.unsubscribe("sales")
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Check if subscribed
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
```ruby
|
|
55
|
+
user.subscribed?("sales")
|
|
56
|
+
```
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Get subscribers for a list (use this for sending emails)
|
|
59
59
|
|
|
60
60
|
```ruby
|
|
61
|
-
|
|
62
|
-
mailkick_user
|
|
63
|
-
end
|
|
61
|
+
User.subscribed("sales")
|
|
64
62
|
```
|
|
65
63
|
|
|
66
|
-
|
|
64
|
+
## Unsubscribe Links
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
Add an unsubscribe link to your emails. For HTML emails, use:
|
|
67
|
+
|
|
68
|
+
```erb
|
|
69
|
+
<%= link_to "Unsubscribe", mailkick_unsubscribe_url(@user, "sales") %>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
For text emails, use:
|
|
73
73
|
|
|
74
|
-
```
|
|
75
|
-
|
|
74
|
+
```erb
|
|
75
|
+
Unsubscribe: <%= mailkick_unsubscribe_url(@user, "sales") %>
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
When a user unsubscribes, they are taken to a mobile-friendly page and given the option to resubscribe. To customize the view, run:
|
|
79
79
|
|
|
80
|
-
```
|
|
81
|
-
|
|
80
|
+
```sh
|
|
81
|
+
rails generate mailkick:views
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
which copies the view into `app/views/mailkick`.
|
|
85
|
+
|
|
84
86
|
## Bounces and Spam Reports
|
|
85
87
|
|
|
86
|
-
Fetch bounces, spam reports, and unsubscribes from your email service.
|
|
88
|
+
Fetch bounces, spam reports, and unsubscribes from your email service. Create `config/initializers/mailkick.rb` with a method to handle opt outs.
|
|
87
89
|
|
|
88
90
|
```ruby
|
|
89
|
-
Mailkick.
|
|
91
|
+
Mailkick.process_opt_outs_method = lambda do |opt_outs|
|
|
92
|
+
emails = opt_outs.map { |v| v[:email] }
|
|
93
|
+
subscribers = User.includes(:mailkick_subscriptions).where(email: emails).index_by(&:email)
|
|
94
|
+
|
|
95
|
+
opt_outs.each do |opt_out|
|
|
96
|
+
subscriber = subscribers[opt_out[:email]]
|
|
97
|
+
next unless subscriber
|
|
98
|
+
|
|
99
|
+
subscriber.mailkick_subscriptions.each do |subscription|
|
|
100
|
+
subscription.destroy if subscription.updated_at < opt_out[:time]
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
90
104
|
```
|
|
91
105
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Add the gem
|
|
106
|
+
And run:
|
|
95
107
|
|
|
96
108
|
```ruby
|
|
97
|
-
|
|
109
|
+
Mailkick.fetch_opt_outs
|
|
98
110
|
```
|
|
99
111
|
|
|
100
|
-
|
|
112
|
+
The following services are supported:
|
|
101
113
|
|
|
102
|
-
|
|
114
|
+
- [AWS SES](#aws-ses)
|
|
115
|
+
- [Mailchimp](#mailchimp)
|
|
116
|
+
- [Mailgun](#mailgun)
|
|
117
|
+
- [Mandrill](#mandrill)
|
|
118
|
+
- [Postmark](#postmark)
|
|
119
|
+
- [SendGrid](#sendgrid)
|
|
120
|
+
|
|
121
|
+
Will gladly accept pull requests for others.
|
|
122
|
+
|
|
123
|
+
#### AWS SES
|
|
124
|
+
|
|
125
|
+
Add the gem
|
|
103
126
|
|
|
104
127
|
```ruby
|
|
105
|
-
gem '
|
|
128
|
+
gem 'aws-sdk-sesv2'
|
|
106
129
|
```
|
|
107
130
|
|
|
108
|
-
|
|
131
|
+
And [configure your AWS credentials](https://github.com/aws/aws-sdk-ruby#configuration). Requires `ses:ListSuppressedDestinations` permission.
|
|
132
|
+
|
|
133
|
+
If you started using Amazon SES [before November 25, 2019](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email-suppression-list.html#sending-email-suppression-list-considerations), you have to manually [enable account-level suppression list feature](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_PutAccountSuppressionAttributes.html).
|
|
109
134
|
|
|
110
135
|
#### Mailchimp
|
|
111
136
|
|
|
137
|
+
Add the gem
|
|
138
|
+
|
|
112
139
|
```ruby
|
|
113
140
|
gem 'gibbon', '>= 2'
|
|
114
141
|
```
|
|
115
142
|
|
|
116
|
-
|
|
143
|
+
And set `ENV["MAILCHIMP_API_KEY"]` and `ENV["MAILCHIMP_LIST_ID"]`.
|
|
117
144
|
|
|
118
145
|
#### Mailgun
|
|
119
146
|
|
|
147
|
+
Add the gem
|
|
148
|
+
|
|
120
149
|
```ruby
|
|
121
150
|
gem 'mailgun-ruby'
|
|
122
151
|
```
|
|
123
152
|
|
|
124
|
-
|
|
153
|
+
And set `ENV["MAILGUN_API_KEY"]`.
|
|
125
154
|
|
|
126
|
-
####
|
|
127
|
-
|
|
128
|
-
Will gladly accept pull requests.
|
|
129
|
-
|
|
130
|
-
### Advanced
|
|
155
|
+
#### Mandrill
|
|
131
156
|
|
|
132
|
-
|
|
157
|
+
Add the gem
|
|
133
158
|
|
|
134
159
|
```ruby
|
|
135
|
-
|
|
136
|
-
Mailkick::Service::Sendgrid.new(api_key: "API_KEY"),
|
|
137
|
-
Mailkick::Service::Mandrill.new(api_key: "API_KEY")
|
|
138
|
-
]
|
|
160
|
+
gem 'mandrill-api'
|
|
139
161
|
```
|
|
140
162
|
|
|
141
|
-
|
|
163
|
+
And set `ENV["MANDRILL_APIKEY"]`.
|
|
164
|
+
|
|
165
|
+
#### Postmark
|
|
142
166
|
|
|
143
|
-
|
|
167
|
+
Add the gem
|
|
144
168
|
|
|
145
169
|
```ruby
|
|
146
|
-
|
|
170
|
+
gem 'postmark'
|
|
147
171
|
```
|
|
148
172
|
|
|
149
|
-
|
|
173
|
+
And set `ENV["POSTMARK_API_KEY"]`.
|
|
174
|
+
|
|
175
|
+
#### SendGrid
|
|
176
|
+
|
|
177
|
+
Add the gem
|
|
150
178
|
|
|
151
179
|
```ruby
|
|
152
|
-
|
|
153
|
-
User.not_opted_out(list: "order_reminders")
|
|
154
|
-
user.opted_out?(list: "order_reminders")
|
|
180
|
+
gem 'sendgrid-ruby'
|
|
155
181
|
```
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
And set `ENV["SENDGRID_API_KEY"]`. The API key requires only the `Suppressions` permission.
|
|
158
184
|
|
|
159
|
-
|
|
185
|
+
### Advanced
|
|
160
186
|
|
|
161
|
-
|
|
187
|
+
For more control over services, set them by hand.
|
|
162
188
|
|
|
163
189
|
```ruby
|
|
164
|
-
|
|
190
|
+
Mailkick.services = [
|
|
191
|
+
Mailkick::Service::SendGridV2.new(api_key: "API_KEY"),
|
|
192
|
+
Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID")
|
|
193
|
+
]
|
|
165
194
|
```
|
|
166
195
|
|
|
167
|
-
|
|
196
|
+
## Reference
|
|
197
|
+
|
|
198
|
+
Access the subscription model directly
|
|
168
199
|
|
|
169
200
|
```ruby
|
|
170
|
-
|
|
201
|
+
Mailkick::Subscription.all
|
|
171
202
|
```
|
|
172
203
|
|
|
173
|
-
##
|
|
204
|
+
## Upgrading
|
|
174
205
|
|
|
175
|
-
|
|
206
|
+
### 1.0
|
|
176
207
|
|
|
177
|
-
|
|
178
|
-
- [Letter Opener](https://github.com/ryanb/letter_opener) - preview email in development
|
|
208
|
+
Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate:
|
|
179
209
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
Change how the user is determined
|
|
210
|
+
1. Add a table to store subscriptions
|
|
183
211
|
|
|
184
|
-
```
|
|
185
|
-
|
|
212
|
+
```sh
|
|
213
|
+
rails generate mailkick:install
|
|
214
|
+
rails db:migrate
|
|
186
215
|
```
|
|
187
216
|
|
|
188
|
-
|
|
217
|
+
2. Change the following methods in your code:
|
|
218
|
+
|
|
219
|
+
- `mailkick_user` to `has_subscriptions`
|
|
220
|
+
- `User.not_opted_out` to `User.subscribed(list)`
|
|
221
|
+
- `opt_in` to `subscribe(list)`
|
|
222
|
+
- `opt_out` to `unsubscribe(list)`
|
|
223
|
+
|
|
224
|
+
3. Add a user and list to `mailkick_unsubscribe_url`
|
|
189
225
|
|
|
190
226
|
```ruby
|
|
191
|
-
|
|
227
|
+
mailkick_unsubscribe_url(user, list)
|
|
192
228
|
```
|
|
193
229
|
|
|
194
|
-
|
|
230
|
+
4. Migrate data for each of your lists
|
|
195
231
|
|
|
196
232
|
```ruby
|
|
197
|
-
|
|
233
|
+
opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil)
|
|
234
|
+
opted_out_users = Mailkick::Legacy.opted_out_users(list: nil)
|
|
235
|
+
|
|
236
|
+
User.find_in_batches do |users|
|
|
237
|
+
users.reject! { |u| opted_out_emails.include?(u.email) }
|
|
238
|
+
users.reject! { |u| opted_out_users.include?(u) }
|
|
239
|
+
|
|
240
|
+
now = Time.now
|
|
241
|
+
records =
|
|
242
|
+
users.map do |user|
|
|
243
|
+
{
|
|
244
|
+
subscriber_type: user.class.name,
|
|
245
|
+
subscriber_id: user.id,
|
|
246
|
+
list: "sales",
|
|
247
|
+
created_at: now,
|
|
248
|
+
updated_at: now
|
|
249
|
+
}
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# use create! for Active Record < 6
|
|
253
|
+
Mailkick::Subscription.insert_all!(records)
|
|
254
|
+
end
|
|
198
255
|
```
|
|
199
256
|
|
|
200
|
-
|
|
257
|
+
5. Drop the `mailkick_opt_outs` table
|
|
201
258
|
|
|
202
259
|
```ruby
|
|
203
|
-
|
|
260
|
+
drop_table :mailkick_opt_outs
|
|
204
261
|
```
|
|
205
262
|
|
|
263
|
+
Also, if you use `Mailkick.fetch_opt_outs`, [add a method](#bounces-and-spam-reports) to handle opt outs.
|
|
264
|
+
|
|
206
265
|
## History
|
|
207
266
|
|
|
208
267
|
View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
|
|
@@ -215,3 +274,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
|
|
|
215
274
|
- Fix bugs and [submit pull requests](https://github.com/ankane/mailkick/pulls)
|
|
216
275
|
- Write, clarify, or fix documentation
|
|
217
276
|
- Suggest or add new features
|
|
277
|
+
|
|
278
|
+
To get started with development and testing:
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
git clone https://github.com/ankane/mailkick.git
|
|
282
|
+
cd mailkick
|
|
283
|
+
bundle install
|
|
284
|
+
bundle exec rake test
|
|
285
|
+
```
|