Class: TestAssistant::Email::Expectation

Inherits:
Object
  • Object
show all
Defined in:
lib/test_assistant/email/expectation.rb

Constant Summary collapse

MATCHERS =
{
    to: :to,
    from: :from,
    with_subject: :subject,
    with_text: {
        match: ->(_, email, value){ value.all?{|text| email.has_content?(text) }},
        actual: ->(_, email){ email.text}
    },
    matching_selector: {
        match: ->(_, email, value){ value.all?{|text| email.has_selector?(text) }},
        actual: ->(_, email){ email.native },
        actual_name: :with_body
    },
    with_link: {
        match: ->(_, email, value){ value.all?{|value| email.has_selector?("a[href='#{value}']") }},
        actual: ->(_, email){ email.native },
        actual_name: :with_body
    },
    with_image: {
        match: ->(_, email, value){ value.all?{|value| email.has_selector?("img[src='#{value}']") }},
        actual: ->(_, email){ email.native },
        actual_name: :with_body
    }
}

Instance Method Summary collapse

Constructor Details

#initializeExpectation

Returns a new instance of Expectation.



6
7
8
9
10
# File 'lib/test_assistant/email/expectation.rb', line 6

def initialize
  @expectations = {}
  @failure_message = 'Expected email to be sent'
  @and_scope = nil
end

Instance Method Details

#and(*arguments) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/test_assistant/email/expectation.rb', line 37

def and(*arguments)
  if @and_scope
    self.send(@and_scope, *arguments)
  else
    ArugmentError.new("Cannot use and without a proceeding assertion.")
  end
end

#diffable?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/test_assistant/email/expectation.rb', line 114

def diffable?
  false
end

#failure_messageObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/test_assistant/email/expectation.rb', line 144

def failure_message
  field_descs = attribute_descriptions
  value_descs = value_descriptions

  base_clause = expectation_description(
      'Expected an email to be sent',
      field_descs,
      value_descs
  )

  if @emails.length == 0
    "#{base_clause} However, no emails were sent."
  else
    email_values = sent_email_values

    if email_values.any?
      base_clause + " However, #{email_pluralisation(@emails)} sent #{result_description(field_descs, [to_sentence(email_values)])}."
    else
      base_clause
    end
  end
end

#failure_message_when_negatedObject



181
182
183
184
185
186
187
188
189
190
# File 'lib/test_assistant/email/expectation.rb', line 181

def failure_message_when_negated
  field_descs = attribute_descriptions(negated: true)
  value_descs = value_descriptions(negated: true)

  expectation_description(
      'Expected no emails to be sent',
      field_descs,
      value_descs
  )
end

#from(email_address) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/test_assistant/email/expectation.rb', line 58

def from(email_address)
  if @expectations[:from]
    raise ArgumentError('An email can only have one from address, but you tried to assert the presence of 2 or more values')
  else
    @expectations[:from] = email_address
  end

  @and_scope = :from

  self
end

#matches?(emails) ⇒ Boolean

Returns:

  • (Boolean)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/test_assistant/email/expectation.rb', line 118

def matches?(emails)
  @emails = emails

  matching_emails = @emails

  if @expectations.any?
    @expectations.each do |attribute, expected|
      @failed_attribute = attribute
      @failed_expected = expected

      matching_emails =
          matching_emails.select do |email|
            email_matches?(email, MATCHERS[attribute], expected)
          end

      if matching_emails.empty?
        return false
      end
    end

    true
  else
    @emails.any?
  end
end

#matching_selector(selector) ⇒ Object



90
91
92
93
94
95
96
# File 'lib/test_assistant/email/expectation.rb', line 90

def matching_selector(selector)
  @expectations[:matching_selector] ||= []
  @expectations[:matching_selector].push(selector)

  @and_scope = :matching_selector
  self
end

#result_description(field_descriptions, values) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/test_assistant/email/expectation.rb', line 167

def result_description(field_descriptions, values)
  to_sentence(
    field_descriptions.map.with_index do |field_description, index|
      value = values[index]

      if [ 'matching selector', 'with link', 'with image' ].include?(field_description)
        "with body #{value}"
      else
        "#{field_description} #{value}"
      end
    end
  )
end

#to(email_address) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/test_assistant/email/expectation.rb', line 45

def to(email_address)
  if email_address.kind_of?(Array)
    @expectations[:to] = email_address
  else
    @expectations[:to] ||= []
    @expectations[:to] << email_address
  end

  @and_scope = :to

  self
end

#with_image(src) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/test_assistant/email/expectation.rb', line 106

def with_image(src)
  @expectations[:with_image] ||= []
  @expectations[:with_image].push(src)

  @and_scope = :with_image
  self
end


98
99
100
101
102
103
104
# File 'lib/test_assistant/email/expectation.rb', line 98

def with_link(href)
  @expectations[:with_link] ||= []
  @expectations[:with_link].push(href)

  @and_scope = :with_link
  self
end

#with_subject(subject) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/test_assistant/email/expectation.rb', line 70

def with_subject(subject)
  if @expectations[:with_subject]
    raise ArgumentError('An email can only have one subject, but you tried to assert the presence of 2 or more values')
  else
    @expectations[:with_subject] = subject
  end

  @and_scope = :with_subject

  self
end

#with_text(text) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/test_assistant/email/expectation.rb', line 82

def with_text(text)
  @expectations[:with_text] ||= []
  @expectations[:with_text].push(text)

  @and_scope = :with_text
  self
end