qiita_team_services 0.3.5 → 0.3.6

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
  SHA1:
3
- metadata.gz: 3704aa3fd1816af8903e4e9d6b1b4a30b212813a
4
- data.tar.gz: 6da5d69f29bfe6624b92caeeb0ba44895a502837
3
+ metadata.gz: fef4a03f843aba4fd94b121bb2bc3b167925c41c
4
+ data.tar.gz: 4fe8e266110be34bbc07f01dae2a46e4c3f580dc
5
5
  SHA512:
6
- metadata.gz: 0fb982dedd4396887380e660d90b6fbc05938e41287f498507298a8851181cff4627d2179a68e5fdb09fe3ab7078deb0ec3da10fb8d7184617deb3c5dcc206f4
7
- data.tar.gz: 3485b7c84bbcc067148714be6c0bedb40b74ec08fc56fb2a7f46aa2a9778a23448ba3dcc4e402f6ee34cf78bd5f50925034a6876d6219ac6c2b52374eef7c79f
6
+ metadata.gz: 581ea55242fad065de959775b300bc189c5ce7828ebb1cb7a3e1c68203e55eac9cfff6cf5dfd5c39be7cc3f645918c0159de0a087040d567842e04fde3cf30bf
7
+ data.tar.gz: 5e7d81e6e64d8e27afc29d0fa2772021897981ca0dcdc3d2186cfe696adf4da6a38271edddaff419cb4ec803d6be8f436a5df0a2c8224b69cff774eaef1e71b7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.3.6
2
+
3
+ - [#13] Escape special characters for slack markup.
4
+
1
5
  # 0.3.5
2
6
 
3
7
  - Add link to comments.
@@ -248,13 +248,13 @@ module Qiita::Team::Services
248
248
  # @param user [Qiita::Team::Services::Resources::User]
249
249
  # @return [String]
250
250
  def user_link(user)
251
- "<#{user.url}|#{user.name}>"
251
+ "<#{user.url}|#{markup_escape(user.name)}>"
252
252
  end
253
253
 
254
254
  # @param item [Qiita::Team::Services::Resources::Item]
255
255
  # @return [String]
256
256
  def item_link(item)
257
- "<#{item.url}|#{item.title}>"
257
+ "<#{item.url}|#{markup_escape(item.title)}>"
258
258
  end
259
259
 
260
260
  # @param comment [Qiita::Team::Services::Resources::Comment]
@@ -266,13 +266,27 @@ module Qiita::Team::Services
266
266
  # @param project [Qiita::Team::Services::Resources::Project]
267
267
  # @return [String]
268
268
  def project_link(project)
269
- "<#{project.url}|#{project.name}>"
269
+ "<#{project.url}|#{markup_escape(project.name)}>"
270
270
  end
271
271
 
272
272
  # @param team [Qiita::Team::Services::Resources::Team]
273
273
  # @return [String]
274
274
  def team_link(team)
275
- "<#{team.url}|#{team.name}>"
275
+ "<#{team.url}|#{markup_escape(team.name)}>"
276
+ end
277
+
278
+ # Escape special characters for Slack markup.
279
+ #
280
+ # @see https://api.slack.com/docs/formatting
281
+ # @param text [String]
282
+ # @return [String]
283
+ def markup_escape(text)
284
+ table_for_escape = {
285
+ "&" => "&amp;",
286
+ "<" => "&lt;",
287
+ ">" => "&gt;",
288
+ }
289
+ text.gsub(/[&<>]/, table_for_escape)
276
290
  end
277
291
  end
278
292
  end
@@ -1,3 +1,3 @@
1
1
  module Qiita::Team::Services
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
  end
@@ -5,7 +5,7 @@ FactoryGirl.define do
5
5
  id { generate(:id) }
6
6
  url_name { "url_name#{id}" }
7
7
  name { "name#{id}" }
8
- url { "#{build(:team).url}/#{name}" }
8
+ url { "#{build(:team).url}/#{url_name}" }
9
9
  profile_image_url "http://example.com"
10
10
  end
11
11
  end
@@ -28,15 +28,6 @@ module Qiita::Team::Services
28
28
  :team_member_removed,
29
29
  ].freeze
30
30
 
31
- EVENT_NAMES_TO_SEND_WITH_ATTACHMENTS = [
32
- :item_comment_created,
33
- :item_created,
34
- :project_comment_created,
35
- ].freeze
36
-
37
- EVENT_NAMES_TO_SEND_WITH_TEXT =
38
- (EXPECTED_AVAILABLE_EVENT_NAMES - EVENT_NAMES_TO_SEND_WITH_ATTACHMENTS).freeze
39
-
40
31
  included do
41
32
  shared_examples "Slack hook" do |hook:|
42
33
  describe ".service_name" do
@@ -80,19 +71,8 @@ module Qiita::Team::Services
80
71
  end
81
72
  end
82
73
 
83
- EVENT_NAMES_TO_SEND_WITH_TEXT.each do |event_name|
84
- describe "##{event_name}" do
85
- subject do
86
- send(hook).public_send(event_name, public_send("#{event_name}_event"))
87
- end
88
-
89
- it "sends proper text message" do
90
- expect(send(hook)).to receive(:send_message) do |request_body|
91
- expect(request_body).to match_slack_text_request
92
- end.once
93
- subject
94
- end
95
-
74
+ describe "hook methods" do
75
+ shared_examples "hook method" do
96
76
  context "when message is delivered successfully" do
97
77
  include_context "Delivery success"
98
78
 
@@ -105,31 +85,178 @@ module Qiita::Team::Services
105
85
  it { expect { subject }.to raise_error(Qiita::Team::Services::DeliveryError) }
106
86
  end
107
87
  end
108
- end
109
88
 
110
- EVENT_NAMES_TO_SEND_WITH_ATTACHMENTS.each do |event_name|
111
- describe "##{event_name}" do
112
- subject do
113
- send(hook).public_send(event_name, public_send("#{event_name}_event"))
89
+ shared_examples "text request hook method" do
90
+ it "sends proper text request message" do
91
+ expect(send(hook)).to receive(:send_message) do |request_body|
92
+ expect(request_body).to match_slack_text_request
93
+ end.once
94
+ subject
114
95
  end
96
+ end
115
97
 
98
+ shared_examples "attachments request hook method" do
116
99
  it "sends message with proper attachments" do
117
100
  expect(send(hook)).to receive(:send_message) do |request_body|
118
101
  expect(request_body).to match_slack_attachments_request
119
102
  end.once
120
103
  subject
121
104
  end
105
+ end
122
106
 
123
- context "when message is delivered successfully" do
124
- include_context "Delivery success"
107
+ subject do
108
+ send(hook).public_send(event_name,
109
+ public_send("#{event_name}_event",
110
+ try(:resource), try(:user), try(:team)))
111
+ end
125
112
 
126
- it { expect { subject }.not_to raise_error }
113
+ describe "#item_created" do
114
+ let(:event_name) { "item_created" }
115
+ it_behaves_like "hook method"
116
+ it_behaves_like "attachments request hook method"
117
+
118
+ context "when the item's title has angle bracket characters" do
119
+ let(:resource) { build(:item, title: "1 on 1 qiitan <> kobito") }
120
+ it_behaves_like "attachments request hook method"
127
121
  end
128
122
 
129
- context "when message is not delivered successfully" do
130
- include_context "Delivery fail"
123
+ context "when the user's name has angle bracket characters" do
124
+ let(:user) { build(:user, name: "<Qiitan>") }
125
+ it_behaves_like "attachments request hook method"
126
+ end
127
+ end
131
128
 
132
- it { expect { subject }.to raise_error(Qiita::Team::Services::DeliveryError) }
129
+ %w(became_coediting destroyed updated).each do |action_name|
130
+ describe "#item_#{action_name}" do
131
+ let(:event_name) { "item_#{action_name}" }
132
+ it_behaves_like "hook method"
133
+ it_behaves_like "text request hook method"
134
+
135
+ context "when the item's title has angle bracket characters" do
136
+ let(:resource) { build(:item, title: "1 on 1 qiitan <> kobito") }
137
+ it_behaves_like "text request hook method"
138
+ end
139
+
140
+ context "when the user's name has angle bracket characters" do
141
+ let(:user) { build(:user, name: "<Qiitan>") }
142
+ it_behaves_like "text request hook method"
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#item_comment_created" do
148
+ let(:event_name) { "item_comment_created" }
149
+ it_behaves_like "hook method"
150
+ it_behaves_like "attachments request hook method"
151
+
152
+ context "when the item's title has angle bracket characters" do
153
+ let(:resource) do
154
+ build(:comment, item: build(:item, title: "1 on 1 qiitan <> kobito"))
155
+ end
156
+ it_behaves_like "attachments request hook method"
157
+ end
158
+
159
+ context "when the user's name has angle bracket characters" do
160
+ let(:user) { build(:user, name: "<Qiitan>") }
161
+ it_behaves_like "attachments request hook method"
162
+ end
163
+ end
164
+
165
+ %w(destroyed updated).each do |action_name|
166
+ describe "#item_comment_#{action_name}" do
167
+ let(:event_name) { "item_comment_#{action_name}" }
168
+ it_behaves_like "hook method"
169
+ it_behaves_like "text request hook method"
170
+
171
+ context "when the item's title has angle bracket characters" do
172
+ let(:resource) do
173
+ build(:comment, item: build(:item, title: "1 on 1 qiitan <> kobito"))
174
+ end
175
+ it_behaves_like "text request hook method"
176
+ end
177
+
178
+ context "when the user's name has angle bracket characters" do
179
+ let(:user) { build(:user, name: "<Qiitan>") }
180
+ it_behaves_like "text request hook method"
181
+ end
182
+ end
183
+ end
184
+
185
+ %w(activated archived created destroyed updated).each do |action_name|
186
+ describe "#project_#{action_name}" do
187
+ let(:event_name) { "project_#{action_name}" }
188
+ it_behaves_like "hook method"
189
+ it_behaves_like "text request hook method"
190
+
191
+ context "when the project's name has angle bracket characters" do
192
+ let(:resource) { build(:project, name: "1 on 1 project qiitan <> kobito") }
193
+ it_behaves_like "text request hook method"
194
+ end
195
+
196
+ context "when the user's name has angle bracket characters" do
197
+ let(:user) { build(:user, name: "<Qiitan>") }
198
+ it_behaves_like "text request hook method"
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "#project_comment_created" do
204
+ let(:event_name) { "project_comment_created" }
205
+ it_behaves_like "hook method"
206
+ it_behaves_like "attachments request hook method"
207
+
208
+ context "when the project's name has angle bracket characters" do
209
+ let(:resource) do
210
+ build(:project_comment,
211
+ item: build(:project, name: "1 on 1 project qiitan <> kobito"))
212
+ end
213
+ it_behaves_like "attachments request hook method"
214
+ end
215
+
216
+ context "when the user's name has angle bracket characters" do
217
+ let(:user) { build(:user, name: "<Qiitan>") }
218
+ it_behaves_like "attachments request hook method"
219
+ end
220
+ end
221
+
222
+ %w(destroyed updated).each do |action_name|
223
+ describe "#project_comment_#{action_name}" do
224
+ let(:event_name) { "project_comment_#{action_name}" }
225
+ it_behaves_like "hook method"
226
+ it_behaves_like "text request hook method"
227
+
228
+ context "when the project's name has angle bracket characters" do
229
+ let(:resource) do
230
+ build(:project_comment,
231
+ item: build(:project, name: "1 on 1 project qiitan <> kobito"))
232
+ end
233
+ it_behaves_like "text request hook method"
234
+ end
235
+
236
+ context "when the user's name has angle bracket characters" do
237
+ let(:user) { build(:user, name: "<Qiitan>") }
238
+ it_behaves_like "text request hook method"
239
+ end
240
+ end
241
+ end
242
+
243
+ %w(added removed).each do |action_name|
244
+ describe "#team_member_#{action_name}" do
245
+ let(:event_name) { "team_member_#{action_name}" }
246
+ it_behaves_like "hook method"
247
+ it_behaves_like "text request hook method"
248
+
249
+ context "when the team's name has angle bracket characters" do
250
+ let(:team) do
251
+ build(:team, name: "qiitan <> kobito team", url: "https://qiitan.qiita.com")
252
+ end
253
+ it_behaves_like "text request hook method"
254
+ end
255
+
256
+ context "when the user's name has angle bracket characters" do
257
+ let(:user) { build(:user, name: "<Qiitan>") }
258
+ it_behaves_like "text request hook method"
259
+ end
133
260
  end
134
261
  end
135
262
  end
@@ -3,6 +3,11 @@ RSpec::Matchers.define :match_slack_text_request do
3
3
  request_body.is_a?(Hash) && \
4
4
  request_body.key?(:text) && \
5
5
  !request_body.key?(:attachments) && \
6
- request_body[:text].is_a?(String)
6
+ request_body[:text].is_a?(String) && \
7
+ !illegal_slack_link_format?(request_body[:text])
8
+ end
9
+
10
+ def illegal_slack_link_format?(text)
11
+ text.match(/<[^>]+</)
7
12
  end
8
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita_team_services
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuku Takahashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-26 00:00:00.000000000 Z
11
+ date: 2015-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel-url_validator