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 +4 -4
- data/CHANGES.md +7 -0
- data/README.md +47 -2
- data/lib/teams_connector/matchers/have_sent_notification_to.rb +163 -0
- data/lib/teams_connector/matchers.rb +11 -0
- data/lib/teams_connector/notification/adaptive_card.rb +1 -1
- data/lib/teams_connector/notification.rb +1 -1
- data/lib/teams_connector/rspec.rb +5 -0
- data/lib/teams_connector/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ed38230a562264b9117ecea0aef7cd66b1bb7d947056f5b892e88cfaed906af
|
4
|
+
data.tar.gz: e3d01cfa5b8de620938e3f8bbd0c012591dc1ecbaf5b9dc742b03801b20c4d00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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"
|
33
|
+
response = Net::HTTP.post(URI(url), content, { "Content-Type" => "application/json" })
|
34
34
|
response.value
|
35
35
|
end
|
36
36
|
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
|
+
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-
|
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
|