mp_weixin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +7 -0
  4. data/.travis.yml +20 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +5 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +308 -0
  9. data/Rakefile +31 -0
  10. data/lib/config/mp_weixin_error.yml +82 -0
  11. data/lib/mp_weixin.rb +59 -0
  12. data/lib/mp_weixin/access_token.rb +172 -0
  13. data/lib/mp_weixin/client.rb +199 -0
  14. data/lib/mp_weixin/config.rb +36 -0
  15. data/lib/mp_weixin/error.rb +27 -0
  16. data/lib/mp_weixin/interface/base.rb +43 -0
  17. data/lib/mp_weixin/interface/group.rb +92 -0
  18. data/lib/mp_weixin/interface/menu.rb +73 -0
  19. data/lib/mp_weixin/interface/message.rb +38 -0
  20. data/lib/mp_weixin/interface/promotion.rb +48 -0
  21. data/lib/mp_weixin/interface/user.rb +39 -0
  22. data/lib/mp_weixin/models/event.rb +123 -0
  23. data/lib/mp_weixin/models/message.rb +227 -0
  24. data/lib/mp_weixin/models/reply_message.rb +180 -0
  25. data/lib/mp_weixin/response.rb +93 -0
  26. data/lib/mp_weixin/response_rule.rb +46 -0
  27. data/lib/mp_weixin/server.rb +39 -0
  28. data/lib/mp_weixin/server_helper.rb +94 -0
  29. data/lib/mp_weixin/version.rb +3 -0
  30. data/lib/support/active_model.rb +3 -0
  31. data/lib/support/active_model/model.rb +99 -0
  32. data/mp_weixin.gemspec +44 -0
  33. data/spec/client_spec.rb +87 -0
  34. data/spec/mp_weixin/access_token_spec.rb +140 -0
  35. data/spec/mp_weixin/client_spec.rb +111 -0
  36. data/spec/mp_weixin/config_spec.rb +24 -0
  37. data/spec/mp_weixin/interface/base_spec.rb +16 -0
  38. data/spec/mp_weixin/interface/group_spec.rb +133 -0
  39. data/spec/mp_weixin/interface/menu_spec.rb +72 -0
  40. data/spec/mp_weixin/interface/message_spec.rb +36 -0
  41. data/spec/mp_weixin/interface/promotion_spec.rb +48 -0
  42. data/spec/mp_weixin/interface/user_spec.rb +76 -0
  43. data/spec/mp_weixin/models/event_spec.rb +94 -0
  44. data/spec/mp_weixin/models/message_spec.rb +300 -0
  45. data/spec/mp_weixin/models/reply_message_spec.rb +365 -0
  46. data/spec/mp_weixin/server_helper_spec.rb +165 -0
  47. data/spec/mp_weixin/server_spec.rb +56 -0
  48. data/spec/spec_helper.rb +51 -0
  49. data/spec/support/mp_weixin.rb +7 -0
  50. data/spec/support/rspec_mixin.rb +8 -0
  51. data/spec/support/weixin.yml +12 -0
  52. metadata +363 -0
@@ -0,0 +1,365 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe "MpWeixin::ReplyMessage" do
5
+ let(:text_message_hash) {
6
+ {
7
+ ToUserName: "toUser",
8
+ FromUserName: "fromUser",
9
+ CreateTime: "12345678",
10
+ MsgType: "text",
11
+ Content: "你好"
12
+ }
13
+ }
14
+
15
+ let(:text_message_xml) {
16
+ %(
17
+ <xml>
18
+ <ToUserName><![CDATA[toUser]]></ToUserName>
19
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
20
+ <CreateTime>12345678</CreateTime>
21
+ <MsgType><![CDATA[text]]></MsgType>
22
+ <Content><![CDATA[你好]]></Content>
23
+ </xml>
24
+ )
25
+ }
26
+
27
+ let(:image_message_hash) {
28
+ {
29
+ ToUserName: "toUser",
30
+ FromUserName: "fromUser",
31
+ CreateTime: "12345678",
32
+ MsgType: "image",
33
+ Image: {MediaId: 'media_id'}
34
+ }
35
+ }
36
+
37
+ let(:image_message_xml) {
38
+ %(
39
+ <xml>
40
+ <ToUserName><![CDATA[toUser]]></ToUserName>
41
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
42
+ <CreateTime>12345678</CreateTime>
43
+ <MsgType><![CDATA[image]]></MsgType>
44
+ <Image>
45
+ <MediaId><![CDATA[media_id]]></MediaId>
46
+ </Image>
47
+ </xml>
48
+ )
49
+ }
50
+
51
+ let(:voice_message_hash) {
52
+ {
53
+ ToUserName: "toUser",
54
+ FromUserName: "fromUser",
55
+ CreateTime: "12345678",
56
+ MsgType: "voice",
57
+ Voice: {MediaId: 'media_id'}
58
+ }
59
+ }
60
+ let(:voice_message_xml) {
61
+ %(
62
+ <xml>
63
+ <ToUserName><![CDATA[toUser]]></ToUserName>
64
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
65
+ <CreateTime>12345678</CreateTime>
66
+ <MsgType><![CDATA[voice]]></MsgType>
67
+ <Voice>
68
+ <MediaId><![CDATA[media_id]]></MediaId>
69
+ </Voice>
70
+ </xml>
71
+ )
72
+ }
73
+
74
+ let(:video_message_hash) {
75
+ {
76
+ ToUserName: "toUser",
77
+ FromUserName: "fromUser",
78
+ CreateTime: "12345678",
79
+ MsgType: "video",
80
+ Video: {
81
+ MediaId: "media_id",
82
+ Title: "title",
83
+ Description: "description"
84
+ }
85
+ }
86
+ }
87
+ let(:video_message_xml) {
88
+ %(
89
+ <xml>
90
+ <ToUserName><![CDATA[toUser]]></ToUserName>
91
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
92
+ <CreateTime>12345678</CreateTime>
93
+ <MsgType><![CDATA[video]]></MsgType>
94
+ <Video>
95
+ <MediaId><![CDATA[media_id]]></MediaId>
96
+ <Title><![CDATA[title]]></Title>
97
+ <Description><![CDATA[description]]></Description>
98
+ </Video>
99
+ </xml>
100
+ )
101
+ }
102
+
103
+ let(:music_message_hash) {
104
+ {
105
+ ToUserName: "toUser",
106
+ FromUserName: "fromUser",
107
+ CreateTime: "12345678",
108
+ MsgType: "music",
109
+ Music: {
110
+ Title: "TITLE",
111
+ Description: "DESCRIPTION",
112
+ MusicUrl: "MUSIC_Url",
113
+ HQMusicUrl: "HQ_MUSIC_Url",
114
+ ThumbMediaId: "media_id"
115
+ }
116
+ }
117
+ }
118
+ let(:music_message_xml) {
119
+ %(
120
+ <xml>
121
+ <ToUserName><![CDATA[toUser]]></ToUserName>
122
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
123
+ <CreateTime>12345678</CreateTime>
124
+ <MsgType><![CDATA[music]]></MsgType>
125
+ <Music>
126
+ <Title><![CDATA[TITLE]]></Title>
127
+ <Description><![CDATA[DESCRIPTION]]></Description>
128
+ <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
129
+ <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
130
+ <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
131
+ </Music>
132
+ </xml>
133
+ )
134
+ }
135
+
136
+
137
+ let(:news_message_simple_hash) {
138
+ {
139
+ ToUserName: "toUser",
140
+ FromUserName: "fromUser",
141
+ CreateTime: "12345678",
142
+ MsgType: "news",
143
+ ArticleCount: "2",
144
+ Articles: [
145
+ {
146
+ Title: "title1",
147
+ Description: "description1",
148
+ PicUrl: "picurl",
149
+ Url: "url"
150
+ },
151
+ {
152
+ Title: "title",
153
+ Description: "description",
154
+ PicUrl: "picurl",
155
+ Url: "url"
156
+ }
157
+ ]
158
+ }
159
+ }
160
+
161
+ let(:news_message_hash) {
162
+ {
163
+ ToUserName: "toUser",
164
+ FromUserName: "fromUser",
165
+ CreateTime: "12345678",
166
+ MsgType: "news",
167
+ ArticleCount: "2",
168
+ Articles: {
169
+ item: [
170
+ {
171
+ Title: "title1",
172
+ Description: "description1",
173
+ PicUrl: "picurl",
174
+ Url: "url"
175
+ },
176
+ {
177
+ Title: "title",
178
+ Description: "description",
179
+ PicUrl: "picurl",
180
+ Url: "url"
181
+ }
182
+ ]
183
+ }
184
+ }
185
+ }
186
+
187
+ let(:news_message_xml) {
188
+ %(
189
+ <xml>
190
+ <ToUserName><![CDATA[toUser]]></ToUserName>
191
+ <FromUserName><![CDATA[fromUser]]></FromUserName>
192
+ <CreateTime>12345678</CreateTime>
193
+ <MsgType><![CDATA[news]]></MsgType>
194
+ <ArticleCount>2</ArticleCount>
195
+ <Articles>
196
+ <item>
197
+ <Title><![CDATA[title1]]></Title>
198
+ <Description><![CDATA[description1]]></Description>
199
+ <PicUrl><![CDATA[picurl]]></PicUrl>
200
+ <Url><![CDATA[url]]></Url>
201
+ </item>
202
+ <item>
203
+ <Title><![CDATA[title]]></Title>
204
+ <Description><![CDATA[description]]></Description>
205
+ <PicUrl><![CDATA[picurl]]></PicUrl>
206
+ <Url><![CDATA[url]]></Url>
207
+ </item>
208
+ </Articles>
209
+ </xml>
210
+ )
211
+ }
212
+
213
+ context "TextReplyMessage" do
214
+ subject { MpWeixin::TextReplyMessage.new(text_message_hash) }
215
+
216
+ context "initialize new" do
217
+
218
+ it "should return an instance of TextReplyMessage" do
219
+ expect(subject).to be_a(MpWeixin::TextReplyMessage)
220
+ end
221
+
222
+ it "should have correct MsgType" do
223
+ expect(subject.MsgType).to eq("text")
224
+ end
225
+ end
226
+
227
+ context ":to_xml" do
228
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
229
+ let(:weixin_xml_hash) { Hash.from_xml(text_message_xml).deep_symbolize_keys[:xml] }
230
+
231
+ it "should return correct xml" do
232
+ expect(want_be_hash).to eq(weixin_xml_hash)
233
+ end
234
+ end
235
+ end
236
+
237
+ context "ImageReplyMessage" do
238
+ subject { MpWeixin::ImageReplyMessage.new(image_message_hash) }
239
+
240
+ context "initialize new" do
241
+
242
+ it "should return an instance of ImageReplyMessage" do
243
+ expect(subject).to be_a(MpWeixin::ImageReplyMessage)
244
+ end
245
+
246
+ it "should have correct MsgType" do
247
+ expect(subject.MsgType).to eq("image")
248
+ end
249
+ end
250
+
251
+ context ":to_xml" do
252
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
253
+ let(:weixin_xml_hash) { Hash.from_xml(image_message_xml).deep_symbolize_keys[:xml] }
254
+
255
+ it "should return correct xml" do
256
+ expect(want_be_hash).to eq(weixin_xml_hash)
257
+ end
258
+ end
259
+ end
260
+
261
+ context "VoiceReplyMessage" do
262
+ subject { MpWeixin::VoiceReplyMessage.new(voice_message_hash) }
263
+
264
+ context "initialize new" do
265
+
266
+ it "should return an instance of VoiceReplyMessage" do
267
+ expect(subject).to be_a(MpWeixin::VoiceReplyMessage)
268
+ end
269
+
270
+ it "should have correct MsgType" do
271
+ expect(subject.MsgType).to eq("voice")
272
+ end
273
+ end
274
+
275
+ context ":to_xml" do
276
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
277
+ let(:weixin_xml_hash) { Hash.from_xml(voice_message_xml).deep_symbolize_keys[:xml] }
278
+
279
+ it "should return correct xml" do
280
+ expect(want_be_hash).to eq(weixin_xml_hash)
281
+ end
282
+ end
283
+ end
284
+
285
+ context "VideoReplyMessage" do
286
+ subject { MpWeixin::VideoReplyMessage.new(video_message_hash) }
287
+
288
+ context "initialize new" do
289
+
290
+ it "should return an instance of VideoReplyMessage" do
291
+ expect(subject).to be_a(MpWeixin::VideoReplyMessage)
292
+ end
293
+
294
+ it "should have correct MsgType" do
295
+ expect(subject.MsgType).to eq("video")
296
+ end
297
+ end
298
+
299
+ context ":to_xml" do
300
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
301
+ let(:weixin_xml_hash) { Hash.from_xml(video_message_xml).deep_symbolize_keys[:xml] }
302
+
303
+ it "should return correct xml" do
304
+ expect(want_be_hash).to eq(weixin_xml_hash)
305
+ end
306
+ end
307
+ end
308
+
309
+ context "MusicReplyMessage" do
310
+ subject { MpWeixin::MusicReplyMessage.new(music_message_hash) }
311
+
312
+ context "initialize new" do
313
+
314
+ it "should return an instance of MusicReplyMessage" do
315
+ expect(subject).to be_a(MpWeixin::MusicReplyMessage)
316
+ end
317
+
318
+ it "should have correct MsgType" do
319
+ expect(subject.MsgType).to eq("music")
320
+ end
321
+ end
322
+
323
+ context ":to_xml" do
324
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
325
+ let(:weixin_xml_hash) { Hash.from_xml(music_message_xml).deep_symbolize_keys[:xml] }
326
+
327
+ it "should return correct xml" do
328
+ expect(want_be_hash).to eq(weixin_xml_hash)
329
+ end
330
+ end
331
+ end
332
+
333
+ context "NewsReplyMessage" do
334
+ subject { MpWeixin::NewsReplyMessage.new(news_message_hash) }
335
+
336
+ context "initialize new" do
337
+
338
+ it "should return an instance of NewsReplyMessage" do
339
+ expect(subject).to be_a(MpWeixin::NewsReplyMessage)
340
+ end
341
+
342
+ it "should have correct MsgType" do
343
+ expect(subject.MsgType).to eq("news")
344
+ end
345
+ end
346
+
347
+ context ":to_xml" do
348
+ let(:want_be_hash) { Hash.from_xml(subject.to_xml).deep_symbolize_keys[:xml] }
349
+ let(:weixin_xml_hash) { Hash.from_xml(news_message_xml).deep_symbolize_keys[:xml] }
350
+
351
+ it "should return correct xml" do
352
+ expect(want_be_hash).to eq(weixin_xml_hash)
353
+ end
354
+ end
355
+
356
+ context ":to_xml simple type" do
357
+ let(:want_be_hash) { Hash.from_xml(MpWeixin::NewsReplyMessage.new(news_message_simple_hash).to_xml).deep_symbolize_keys[:xml] }
358
+ let(:weixin_xml_hash) { Hash.from_xml(news_message_xml).deep_symbolize_keys[:xml] }
359
+
360
+ it "should return correct xml" do
361
+ expect(want_be_hash).to eq(weixin_xml_hash)
362
+ end
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::ServerHelper do
5
+ include MpWeixin::ServerHelper
6
+
7
+ let(:config) { MpWeixin::Config }
8
+ let(:token) { config.token }
9
+ let(:timestamp) { "1388028695" } #{ "#{Time.now.to_i}" }
10
+ let(:nonce) { "121212121" }
11
+ let(:signature) { "9dc548e8c7fe32ac53f887e834a8c719a73cafc3" }# { generate_signature(token, timestamp, nonce) }
12
+ let(:incorrent_signature) { SecureRandom.hex(64) }
13
+
14
+ context "#generate_signature" do
15
+ it "should generate an signature" do
16
+ generate_signature(token, timestamp, nonce).should be_a(String)
17
+ end
18
+ end
19
+
20
+ context "#valid_signature?" do
21
+ it "should return true when every are well" do
22
+ expect(valid_signature?(signature, timestamp, nonce)).to be_true
23
+ end
24
+
25
+ it "should return false if valid with incorrent_signature" do
26
+ expect(valid_signature?(incorrent_signature, timestamp, nonce)).to be_false
27
+ end
28
+ end
29
+
30
+ context "#reply message" do
31
+ let(:text_message_hash) {
32
+ {
33
+ ToUserName: "toUser",
34
+ FromUserName: "fromUser",
35
+ CreateTime: "12345678",
36
+ MsgType: "text",
37
+ Content: "你好"
38
+ }
39
+ }
40
+
41
+ let(:image_message_hash) {
42
+ {
43
+ ToUserName: "toUser",
44
+ FromUserName: "fromUser",
45
+ CreateTime: "12345678",
46
+ MsgType: "image",
47
+ Image: {MediaId: 'media_id'}
48
+ }
49
+ }
50
+
51
+ let(:voice_message_hash) {
52
+ {
53
+ ToUserName: "toUser",
54
+ FromUserName: "fromUser",
55
+ CreateTime: "12345678",
56
+ MsgType: "voice",
57
+ Voice: {MediaId: 'media_id'}
58
+ }
59
+ }
60
+
61
+ let(:video_message_hash) {
62
+ {
63
+ ToUserName: "toUser",
64
+ FromUserName: "fromUser",
65
+ CreateTime: "12345678",
66
+ MsgType: "video",
67
+ Video: {
68
+ MediaId: "media_id",
69
+ Title: "title",
70
+ Description: "description"
71
+ }
72
+ }
73
+ }
74
+
75
+ let(:music_message_hash) {
76
+ {
77
+ ToUserName: "toUser",
78
+ FromUserName: "fromUser",
79
+ CreateTime: "12345678",
80
+ MsgType: "music",
81
+ Music: {
82
+ Title: "TITLE",
83
+ Description: "DESCRIPTION",
84
+ MusicUrl: "MUSIC_Url",
85
+ HQMusicUrl: "HQ_MUSIC_Url",
86
+ ThumbMediaId: "media_id"
87
+ }
88
+ }
89
+ }
90
+
91
+ let(:news_message_simple_hash) {
92
+ {
93
+ ToUserName: "toUser",
94
+ FromUserName: "fromUser",
95
+ CreateTime: "12345678",
96
+ MsgType: "news",
97
+ ArticleCount: "2",
98
+ Articles: [
99
+ {
100
+ Title: "title1",
101
+ Description: "description1",
102
+ PicUrl: "picurl",
103
+ Url: "url"
104
+ },
105
+ {
106
+ Title: "title",
107
+ Description: "description",
108
+ PicUrl: "picurl",
109
+ Url: "url"
110
+ }
111
+ ]
112
+ }
113
+ }
114
+
115
+ let(:news_message_hash) {
116
+ {
117
+ ToUserName: "toUser",
118
+ FromUserName: "fromUser",
119
+ CreateTime: "12345678",
120
+ MsgType: "news",
121
+ ArticleCount: "2",
122
+ Articles: {
123
+ item: [
124
+ {
125
+ Title: "title1",
126
+ Description: "description1",
127
+ PicUrl: "picurl",
128
+ Url: "url"
129
+ },
130
+ {
131
+ Title: "title",
132
+ Description: "description",
133
+ PicUrl: "picurl",
134
+ Url: "url"
135
+ }
136
+ ]
137
+ }
138
+ }
139
+ }
140
+
141
+ it "reply_text_message with attributes should be_a TextReplyMessage" do
142
+ expect(reply_text_message(text_message_hash)).to be_a(MpWeixin::TextReplyMessage)
143
+ end
144
+
145
+ it "reply_image_message with attributes should be_a ImageReplyMessage" do
146
+ expect(reply_image_message(image_message_hash)).to be_a(MpWeixin::ImageReplyMessage)
147
+ end
148
+
149
+ it "reply_voice_message with attributes should be_a VoiceReplyMessage" do
150
+ expect(reply_voice_message(voice_message_hash)).to be_a(MpWeixin::VoiceReplyMessage)
151
+ end
152
+
153
+ it "reply_video_message with attributes should be_a VideoReplyMessage" do
154
+ expect(reply_video_message(video_message_hash)).to be_a(MpWeixin::VideoReplyMessage)
155
+ end
156
+
157
+ it "reply_music_message with attributes should be_a MusicReplyMessage" do
158
+ expect(reply_music_message(music_message_hash)).to be_a(MpWeixin::MusicReplyMessage)
159
+ end
160
+
161
+ it "reply_news_message with attributes should be_a NewsReplyMessage" do
162
+ expect(reply_news_message(news_message_hash)).to be_a(MpWeixin::NewsReplyMessage)
163
+ end
164
+ end
165
+ end