test_assistant 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c14c4c6d990513adb024b4571090c7fc85dca59
4
- data.tar.gz: 1ab16e504b25feca6a2d2ab443684d4512e4a67e
3
+ metadata.gz: fd9da0b295791c6249e94172857509c44b58b7ac
4
+ data.tar.gz: ffb211e31de33220bfeea704961e844738597308
5
5
  SHA512:
6
- metadata.gz: 8361c96e295b176daf5c9aba592217be43174ba39876094fc5f7423e9f2ddfe14db46fc8e7b424b8ede85c8035c8f5b78074222f10a6be8631aea60a74e59577
7
- data.tar.gz: 33107a1cc37d9ffd6d645b02206699c0d8f6afdb392fbf76b1e2a72cbc1fb7d0efa49294c010f58a6a8da415b72962bb72d6f9a74a5126ceff09c95fb30c2fcf
6
+ metadata.gz: 3c98c15b60558a8615edfdfc7336e307848eb481f8167574a7208d559d48220b1f6686b454b38e9c6f9932329158d5fbac98b40f470b71e89e956b62cb6f34db
7
+ data.tar.gz: 3d0500451574c4b9bffd61a05b5a8380a9fc5a8eeac1bc555b5e38348945c3d7f7b8bf931fb832fc6faf419b20fcf8ee98792ccd8a754c0de5668481e9b3f804
data/README.md CHANGED
@@ -84,10 +84,40 @@ RSpec.describe 'making some valid request', type: :request do
84
84
  end
85
85
  ```
86
86
 
87
+ ## Email expectations
88
+
89
+
90
+ ```ruby
91
+ TestAssistant.configure(config) do |ta_config|
92
+ ta_config.include_email_helpers type: :request
93
+ end
94
+ ```
95
+
96
+ ```ruby
97
+ RSpec.describe 'making some valid request', type: :request do
98
+ context 'some important context' do
99
+ it 'should send an email' do
100
+ expect(email).to have_been_sent
101
+ .to('user@email.com')
102
+ .from('admin@site.com')
103
+ .with_subject('Welcome!')
104
+ .with_text('Welcome, user@email.com').and('Thanks for signing up')
105
+ .with_selector('#password').and('#username')
106
+ .with_link('www.site.com/onboarding/1')
107
+ .with_image('www.site.com/assets/images/welcome.png')
108
+ end
109
+ end
110
+ end
111
+ ```
112
+
87
113
  ## Contributing
88
114
 
89
- 1. Fork it ( https://github.com/[my-github-username]/test_assistant/fork )
115
+ 1. Fork it ( https://github.com/greena13/test_assistant/fork )
90
116
  2. Create your feature branch (`git checkout -b my-new-feature`)
91
117
  3. Commit your changes (`git commit -am 'Add some feature'`)
92
118
  4. Push to the branch (`git push origin my-new-feature`)
93
119
  5. Create a new Pull Request
120
+
121
+ ## Inspirations
122
+
123
+ * [CapybaraEmail](https://github.com/DockYard/capybara-email)
@@ -1,5 +1,6 @@
1
1
  module TestAssistant
2
2
  autoload :JSONHelpers, 'test_assistant/json_helpers'
3
+ autoload :Email, 'test_assistant/email/helpers'
3
4
  autoload :FailureReporter, 'test_assistant/failure_reporter'
4
5
 
5
6
  class Configuration
@@ -11,6 +12,10 @@ module TestAssistant
11
12
  @rspec_config.include JSONHelpers, options
12
13
  end
13
14
 
15
+ def include_email_helpers(options = {})
16
+ @rspec_config.include Email::Helpers, options
17
+ end
18
+
14
19
  def render_failed_responses(options = {})
15
20
  tag_filter = options[:tag]
16
21
  no_tag_filter = !tag_filter
@@ -0,0 +1,209 @@
1
+ require 'capybara/rspec'
2
+
3
+ module TestAssistant::Email
4
+ class Expectation
5
+ def initialize
6
+ @expectations = {}
7
+ @failure_message = 'Expected email to be sent'
8
+ @and_scope = nil
9
+ end
10
+
11
+ MATCHERS = {
12
+ to: :to,
13
+ from: :from,
14
+ with_subject: :subject,
15
+ with_text: {
16
+ match: ->(_, email, value){ value.all?{|text| email.has_content?(text) }},
17
+ actual: ->(_, email){ email.text}
18
+ },
19
+ with_selector: {
20
+ match: ->(_, email, value){ value.all?{|text| email.has_selector?(text) }},
21
+ actual: ->(_, email){ email.native },
22
+ actual_name: :with_body
23
+ },
24
+ with_link: {
25
+ match: ->(_, email, value){ value.all?{|value| email.has_selector?("a[href='#{value}']") }},
26
+ actual: ->(_, email){ email.native },
27
+ actual_name: :with_body
28
+ },
29
+ with_image: {
30
+ match: ->(_, email, value){ value.all?{|value| email.has_selector?("img[src='#{value}']") }},
31
+ actual: ->(_, email){ email.native },
32
+ actual_name: :with_body
33
+ }
34
+ }
35
+
36
+ def and(*arguments)
37
+ if @and_scope
38
+ self.send(@and_scope, *arguments)
39
+ else
40
+ ArugmentError.new("Cannot use and without a proceeding assertion.")
41
+ end
42
+ end
43
+
44
+ def to(email_address)
45
+ if email_address.kind_of?(Array)
46
+ @expectations[:to] = email_address
47
+ else
48
+ @expectations[:to] ||= []
49
+ @expectations[:to] << email_address
50
+ end
51
+
52
+ @and_scope = :to
53
+
54
+ self
55
+ end
56
+
57
+ def from(email_address)
58
+ if email_address.kind_of?(Array)
59
+ @expectations[:from] = email_address
60
+ else
61
+ @expectations[:from] ||= []
62
+ @expectations[:from] << email_address
63
+ end
64
+
65
+ @and_scope = :from
66
+
67
+ self
68
+ end
69
+
70
+ def with_subject(subject)
71
+ if @expectations[:with_subject]
72
+ raise ArgumentError('An email can only have one subject, but you tried to assert the presence of 2 or more values')
73
+ else
74
+ @expectations[:with_subject] = subject
75
+ end
76
+
77
+ self
78
+ end
79
+
80
+ def with_text(text)
81
+ @expectations[:with_text] ||= []
82
+ @expectations[:with_text].push(text)
83
+
84
+ @and_scope = :with_text
85
+ self
86
+ end
87
+
88
+ def with_selector(selector)
89
+ @expectations[:with_selector] ||= []
90
+ @expectations[:with_selector].push(selector)
91
+
92
+ @and_scope = :with_selector
93
+ self
94
+ end
95
+
96
+ def with_link(href)
97
+ @expectations[:with_link] ||= []
98
+ @expectations[:with_link].push(href)
99
+
100
+ @and_scope = :with_link
101
+ self
102
+ end
103
+
104
+ def with_image(src)
105
+ @expectations[:with_image] ||= []
106
+ @expectations[:with_image].push(src)
107
+
108
+ @and_scope = :with_image
109
+ self
110
+ end
111
+
112
+ def diffable?
113
+ false
114
+ end
115
+
116
+ def matches?(emails)
117
+ @emails = emails
118
+
119
+ matching_emails = @emails
120
+
121
+ @expectations.each do |attribute, expected|
122
+
123
+ matching_emails =
124
+ matching_emails.select do |email|
125
+ email_matches?(email, MATCHERS[attribute], expected)
126
+ end
127
+
128
+ if matching_emails.empty?
129
+ @failed_attribute = attribute
130
+ @failed_expected = expected
131
+ return false
132
+ end
133
+ end
134
+
135
+ true
136
+ end
137
+
138
+ def failure_message
139
+ field_description = @failed_attribute.to_s.gsub('_', ' ')
140
+ value_description =
141
+ case @failed_expected
142
+ when String
143
+ "'#{@failed_expected}'"
144
+ when Array
145
+ @failed_expected.map{|val| "'#{val}'"}.to_sentence
146
+ else
147
+ @failed_expected
148
+ end
149
+
150
+ base_clause = "Expected an email to be sent #{field_description} #{value_description}."
151
+
152
+ if @emails.length == 0
153
+ base_clause + ' However, no emails were sent.'
154
+ else
155
+ pluralisation = @emails.length == 1 ? 'email' : 'emails'
156
+
157
+ email_values = @emails.inject([]) do |memo, email|
158
+ matcher = MATCHERS[@failed_attribute]
159
+
160
+ value =
161
+ case matcher
162
+ when String, Symbol
163
+ email.send(matcher)
164
+ when Hash
165
+ field_description = matcher[:actual_name] if matcher[:actual_name]
166
+ matcher[:actual].(email, parsed_emails(email))
167
+ end
168
+
169
+ value = value.kind_of?(String) ? "'#{value}'" : value
170
+ memo << value
171
+
172
+ memo
173
+ end
174
+
175
+
176
+ if email_values.any?
177
+ base_clause + " However, #{pluralisation} were sent #{field_description} #{email_values.to_sentence}"
178
+ else
179
+ base_clause
180
+ end
181
+ end
182
+ end
183
+
184
+ private
185
+
186
+ def parsed_emails(email)
187
+ @parsed_emails ||= {}
188
+ @parsed_emails[email] ||= parser(email)
189
+ @parsed_emails[email]
190
+ end
191
+
192
+ def parser(email)
193
+ Capybara::Node::Simple.new(email.parts.first.body.decoded)
194
+ end
195
+
196
+ def email_matches?(email, assertion, expected)
197
+ case assertion
198
+ when String, Symbol
199
+ email.send(assertion) == expected
200
+ when Hash
201
+ assertion[:match].(email, parsed_emails(email), expected)
202
+ else
203
+ raise RuntimeError.new(
204
+ "Unsupported assertion mapping '#{assertion_match}' of type #{assertion_match.class.name}"
205
+ )
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_assistant/email/expectation'
2
+
3
+ module TestAssistant::Email
4
+ module Helpers
5
+ def email
6
+ ActionMailer::Base.deliveries
7
+ end
8
+
9
+ def have_been_sent
10
+ TestAssistant::Email::Expectation.new
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module TestAssistant
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "rspec-rails", "~> 3.0"
22
+ spec.add_dependency 'capybara', '~> 2.5', '>= 2.5.0'
22
23
  spec.add_development_dependency "bundler", "~> 1.6"
23
24
  spec.add_development_dependency "rake", "~> 0"
24
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test_assistant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleck Greenham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-30 00:00:00.000000000 Z
11
+ date: 2016-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails
@@ -24,6 +24,26 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capybara
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.5'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.5.0
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.5'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.5.0
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: bundler
29
49
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +87,8 @@ files:
67
87
  - Rakefile
68
88
  - lib/test_assistant.rb
69
89
  - lib/test_assistant/configuration.rb
90
+ - lib/test_assistant/email/expectation.rb
91
+ - lib/test_assistant/email/helpers.rb
70
92
  - lib/test_assistant/failure_reporter.rb
71
93
  - lib/test_assistant/json_helpers.rb
72
94
  - lib/test_assistant/version.rb