teams_connector 0.1.4 → 0.1.5

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 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