teams_connector 0.1.4 → 0.1.5

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
  SHA256:
3
- metadata.gz: 46a69bacfa1eb6a6b46616d436ff4b8c7890db602ce30c7f082e004e53e161c3
4
- data.tar.gz: e98ac0f36a4fc64a1ec41f100ce6b062dc4b1ff4579a2094e2b6d49530b2b5f3
3
+ metadata.gz: 9ed38230a562264b9117ecea0aef7cd66b1bb7d947056f5b892e88cfaed906af
4
+ data.tar.gz: e3d01cfa5b8de620938e3f8bbd0c012591dc1ecbaf5b9dc742b03801b20c4d00
5
5
  SHA512:
6
- metadata.gz: f5183b39ff855da474a6417861020f44b2933a4e93fbc497207eab427802e88a33d41511ca30c90390741baf85f39a72b30804ddf78a302f1247e49bfb3edd69
7
- data.tar.gz: b68b7311f4ba4f7fd2b37c99bdc960fef80d0c7528fdad6a06002820df60131c0f4b5ae1eb2f5f08a9d57e54c5a7673ee96add2d9aca7219c76301ccc5d27f14
6
+ metadata.gz: 683b6a1095609d9f13263c71d7d17c4c466bd3041c334675985d13d4f2e9fd6f9b484354f21779c07b1ea4574fb11e3b10b6fae5e9d5f8fe9fdf2b34f72c27ea
7
+ data.tar.gz: c0144642fff244b53410dc78f4f6f59570f6354af3f431c6d429878c2fd7c9af377edcafe55a020b08765e40db11bac5a64819321a350d4d1ed05d92379645f6
data/CHANGES.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Teams Connector Changelog
2
2
 
3
+ 0.1.5
4
+ ---
5
+ - RSpec Matchers for testing, thanks to [rspec-rails](https://github.com/rspec/rspec-rails) for their ActionCable `have_broadcasted_to` matcher as reference
6
+ - README update for testing
7
+ - Sometimes use testing mode internally
8
+ - Fixed code smells
9
+
3
10
  0.1.4
4
11
  ---
5
12
  - Add rudimentary testing method
data/README.md CHANGED
@@ -112,18 +112,63 @@ TeamsConnector::Notification::AdaptiveCard.new(content: builder).deliver_later
112
112
  ## Testing
113
113
 
114
114
  To test TeamsConnector integration in your application you can use the `:testing` method.
115
- Instead of performing real HTTP requests, an array in `TeamsConnector.testing.requests` is filled in chronological order.
115
+ Instead of performing real HTTP requests, an array in `TeamsConnector.testing.requests` is filled with your notifications in chronological order.
116
116
 
117
117
  The request elements have the following structure:
118
118
  ```ruby
119
119
  {
120
120
  channel: :default,
121
121
  template: :facts_card,
122
- content: "rendered content",
122
+ content: '{"rendered content": "in JSON format"}',
123
123
  time: Time.now
124
124
  }
125
125
  ```
126
126
 
127
+ ### RSpec Matcher
128
+ TeamsConnector provides the `have_sent_notification_to(channel = nil, template = nil)` matcher for RSpec.
129
+ It is available by adding `require "teams_connector/rspec"` to your `spec_helper.rb`.
130
+ The matcher supports filtering notifications by channel and template. If one is not given, it does not filter the notifications by it.
131
+ There exists the alias `send_notification_to` for `have_sent_notification_to`.
132
+
133
+ ```ruby
134
+ it "has sent exactly one notification to the channel" do
135
+ expect { notification.deliver_later }.to have_sent_notification_to(:channel)
136
+ end
137
+ ```
138
+
139
+ #### Expecting number of notifications
140
+ By default `have_sent_notification_to` expects exactly one matching notification.
141
+ You can change the expected amount by chaining `exactly`, `at_least` or `at_most`.
142
+
143
+ Example:
144
+ ```ruby
145
+ it "has sent less than 10 notifications to the channel" do
146
+ expect { notification.deliver_later }.to have_sent_notification_to(:channel).at_most(10)
147
+ end
148
+ ```
149
+
150
+ You can also use `once`, `twice` and `thrice` as an alias for `exactly(1..3)`.
151
+ For more readable expectations `times` can be chained.
152
+
153
+ #### Expecting templates
154
+ The template argument in the matcher does filter the notifications.
155
+ If you expect a template instead, you can chain with `with_template(:template)`.
156
+
157
+ #### Expecting content
158
+ To expect specific content, you can chain with `with(data = nil, &block)`.
159
+ Data supports other RSpec matchers like `hash_including`.
160
+ The block is called for every notification with the notification content hash and the raw notification itself.
161
+
162
+ Example:
163
+ ```ruby
164
+ expect {
165
+ notification(:default, :test_card).deliver_later
166
+ }.to have_sent_notification_to(:default).with { |content, notification|
167
+ expect(notification[:channel]).to eq :default
168
+ expect(notification[:template]).to eq :test_card
169
+ expect(content["sections"]).to include(hash_including("activityTitle", "activitySubtitle", "facts", "markdown" => true))
170
+ }
171
+ ```
127
172
  ## Development
128
173
 
129
174
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,163 @@
1
+ module TeamsConnector
2
+ module Matchers
3
+ class HaveSentNotificationTo
4
+ include RSpec::Matchers::Composable
5
+
6
+ def initialize(channel, template)
7
+ @filter = {
8
+ channel: channel,
9
+ template: template
10
+ }
11
+ @block = proc {}
12
+ @data = nil
13
+ @template_data = nil
14
+ set_expected_number(:exactly, 1)
15
+ end
16
+
17
+ def with(data = nil, &block)
18
+ @data = data
19
+ @block = block if block
20
+ self
21
+ end
22
+
23
+ def with_template(template = nil)
24
+ @template_data = template
25
+ self
26
+ end
27
+
28
+ def exactly(count)
29
+ set_expected_number(:exactly, count)
30
+ self
31
+ end
32
+
33
+ def at_least(count)
34
+ set_expected_number(:at_least, count)
35
+ self
36
+ end
37
+
38
+ def at_most(count)
39
+ set_expected_number(:at_most, count)
40
+ self
41
+ end
42
+
43
+ def times
44
+ self
45
+ end
46
+
47
+ def once
48
+ exactly(:once)
49
+ end
50
+
51
+ def twice
52
+ exactly(:twice)
53
+ end
54
+
55
+ def thrice
56
+ exactly(:thrice)
57
+ end
58
+
59
+ def failure_message
60
+ "expected to send #{base_message}".tap do |msg|
61
+ if @unmatching_ntfcts.any?
62
+ msg << "\nSent notifications"
63
+ msg << " to #{@filter[:channel]}" if @filter[:channel]
64
+ msg << " of #{@filter[:template]}" if @filter[:template]
65
+ msg << ":"
66
+ @unmatching_ntfcts.each do |data|
67
+ msg << "\n #{data}"
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def failure_message_when_negated
74
+ "expected not to send #{base_message}"
75
+ end
76
+
77
+ def matches?(expectation)
78
+ if Proc === expectation
79
+ original_count = TeamsConnector.testing.requests.size
80
+ expectation.call
81
+ in_block_notifications = TeamsConnector.testing.requests.drop(original_count)
82
+ else
83
+ in_block_notifications = expectation
84
+ end
85
+
86
+ in_block_notifications = in_block_notifications.select { |msg|
87
+ @filter.map { |k, v| msg[k] === v unless v.nil? }.compact.all?
88
+ }
89
+
90
+ check(in_block_notifications)
91
+ end
92
+
93
+ def supports_block_expectations?
94
+ true
95
+ end
96
+
97
+ private
98
+
99
+ def check(notifications)
100
+ @matching_ntfcts, @unmatching_ntfcts = notifications.partition do |ntfct|
101
+ result = true
102
+
103
+ result &= ntfct[:template] == @template_data unless @template_data.nil?
104
+
105
+ decoded = JSON.parse(ntfct[:content])
106
+ if @data.nil? || @data === decoded
107
+ @block.call(decoded, ntfct)
108
+ result &= true
109
+ else
110
+ result = false
111
+ end
112
+
113
+ result
114
+ end
115
+
116
+ @matching_count = @matching_ntfcts.size
117
+
118
+ case @expectation_type
119
+ when :exactly then @expected_number == @matching_count
120
+ when :at_most then @expected_number >= @matching_count
121
+ when :at_least then @expected_number <= @matching_count
122
+ end
123
+ end
124
+
125
+ def set_expected_number(relativity, count)
126
+ @expectation_type = relativity
127
+ @expected_number =
128
+ case count
129
+ when :once then 1
130
+ when :twice then 2
131
+ when :thrice then 3
132
+ else Integer(count)
133
+ end
134
+ end
135
+
136
+ def base_message
137
+ "#{message_expectation_modifier} #{@expected_number} notifications".tap do |msg|
138
+ msg << " to #{@filter[:channel]}" if @filter[:channel]
139
+ msg << " of #{@filter[:template]}" if @filter[:template]
140
+ msg << " with template #{@template_data}" if @template_data
141
+ msg << " with content #{data_description(@data)}" if @data
142
+ msg << ", but sent #{@matching_count}"
143
+ end
144
+ end
145
+
146
+ def message_expectation_modifier
147
+ case @expectation_type
148
+ when :exactly then "exactly"
149
+ when :at_most then "at most"
150
+ when :at_least then "at least"
151
+ end
152
+ end
153
+
154
+ def data_description(data)
155
+ if RSpec::Support.is_a_matcher?(data) && data.respond_to?(:description)
156
+ data.description
157
+ else
158
+ data
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,11 @@
1
+ require 'teams_connector/matchers/have_sent_notification_to'
2
+
3
+ module TeamsConnector
4
+ module Matchers
5
+ def have_sent_notification_to(channel = nil, template = nil)
6
+ HaveSentNotificationTo.new(channel, template)
7
+ end
8
+
9
+ alias_method :send_notification_to, :have_sent_notification_to
10
+ end
11
+ end
@@ -3,7 +3,7 @@ module TeamsConnector
3
3
  attr_accessor :content
4
4
 
5
5
  def initialize(template: :adaptive_card, content: {}, channel: TeamsConnector.configuration.default)
6
- super(template: template, channel: channel)
6
+ super(template: template, channels: channel)
7
7
  if content.instance_of? TeamsConnector::Builder
8
8
  @content = {
9
9
  card: [content.result]
@@ -30,7 +30,7 @@ module TeamsConnector
30
30
  elsif TeamsConnector.configuration.method == :testing
31
31
  TeamsConnector.testing.perform_request channel, @template, content
32
32
  else
33
- response = Net::HTTP.post(URI(url), content, { "Content-Type": "application/json" })
33
+ response = Net::HTTP.post(URI(url), content, { "Content-Type" => "application/json" })
34
34
  response.value
35
35
  end
36
36
  end
@@ -0,0 +1,5 @@
1
+ require "teams_connector/matchers"
2
+
3
+ RSpec.configure do |config|
4
+ config.include TeamsConnector::Matchers
5
+ end
@@ -1,3 +1,3 @@
1
1
  module TeamsConnector
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teams_connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Keune
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-02 00:00:00.000000000 Z
11
+ date: 2021-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -117,10 +117,13 @@ files:
117
117
  - lib/teams_connector.rb
118
118
  - lib/teams_connector/builder.rb
119
119
  - lib/teams_connector/configuration.rb
120
+ - lib/teams_connector/matchers.rb
121
+ - lib/teams_connector/matchers/have_sent_notification_to.rb
120
122
  - lib/teams_connector/notification.rb
121
123
  - lib/teams_connector/notification/adaptive_card.rb
122
124
  - lib/teams_connector/notification/message.rb
123
125
  - lib/teams_connector/post_worker.rb
126
+ - lib/teams_connector/rspec.rb
124
127
  - lib/teams_connector/testing.rb
125
128
  - lib/teams_connector/version.rb
126
129
  - teams_connector.gemspec