weichat_rails 0.0.1 → 3.0.0

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.
data/lib/weichat_rails.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "weichat_rails/api"
2
2
  require "weichat_rails/auto_generate_secret_key"
3
+ require 'dalli'
3
4
 
4
5
  module WeichatRails
5
6
 
@@ -16,12 +17,20 @@ module WeichatRails
16
17
  end
17
18
  end
18
19
 
20
+ Config = Struct.new(:cache,:cache_namespace,:appid,:secret,:timeout,:skip_verify_ssl)
19
21
 
20
22
  class << self
23
+
21
24
  def config
22
- @config || OpenStruct.new({wechat_secret_string: nil,wechat_token_string: nil})
25
+ @config ||= Config.new(nil,'weichat_rails',nil,nil,20,true)
26
+ end
27
+
28
+ def api
29
+ @weichat_api ||= WeichatRails::Api.new(config.appid,config.secret,config.timeout,config.skip_verify_ssl)
23
30
  end
24
31
 
32
+
33
+
25
34
  #can configure the wechat_secret_string,wechat_token_string in weichat_rails_config.rb file
26
35
  def configure
27
36
  yield config if block_given?
@@ -29,15 +38,15 @@ module WeichatRails
29
38
 
30
39
  end
31
40
 
32
- #DEFAULT_TOKEN_COLUMN_NAME = "wechat_token".freeze
33
- #DEFAULT_WECHAT_SECRET_KEY = "wechat_secret_key".freeze
34
-
41
+ #config.cache_namespace = 'weichat_rails'
35
42
 
36
- #def self.api
37
- # # @api ||= WechatRails::Api.new(self.config.appid, self.config.secret, self.config.access_token)
38
- #end
43
+ #if use rails with dalli,you can set config.cache = Rails.cache
44
+ self.config.cache ||= if defined?(::Rails)
45
+ Rails.cache
46
+ else
47
+ Dalli::Client.new('localhost:11211',namespace: config.cache_namespace,conpress: true)
48
+ end
39
49
  end
40
-
41
50
  if defined? ActionController::Base
42
51
  class ActionController::Base
43
52
  def self.wechat_responder opts={}
data/spec/examples.txt ADDED
@@ -0,0 +1,74 @@
1
+ example_id | status | run_time |
2
+ ---------------------------------------------------- | ------ | --------------- |
3
+ ./spec/lib/weichat_rails/access_token_spec.rb[1:1:1] | passed | 0.00105 seconds |
4
+ ./spec/lib/weichat_rails/access_token_spec.rb[1:1:2] | passed | 0.00137 seconds |
5
+ ./spec/lib/weichat_rails/access_token_spec.rb[1:1:3] | passed | 0.00112 seconds |
6
+ ./spec/lib/weichat_rails/access_token_spec.rb[1:2:1] | passed | 0.01163 seconds |
7
+ ./spec/lib/weichat_rails/api_spec.rb[1:1:1] | passed | 0.00069 seconds |
8
+ ./spec/lib/weichat_rails/api_spec.rb[1:2:1] | passed | 0.00113 seconds |
9
+ ./spec/lib/weichat_rails/api_spec.rb[1:3:1] | passed | 0.00109 seconds |
10
+ ./spec/lib/weichat_rails/api_spec.rb[1:4:1] | passed | 0.00108 seconds |
11
+ ./spec/lib/weichat_rails/api_spec.rb[1:4:2] | passed | 0.00112 seconds |
12
+ ./spec/lib/weichat_rails/api_spec.rb[1:5:1] | passed | 0.00148 seconds |
13
+ ./spec/lib/weichat_rails/api_spec.rb[1:6:1] | passed | 0.00118 seconds |
14
+ ./spec/lib/weichat_rails/api_spec.rb[1:6:2] | passed | 0.00124 seconds |
15
+ ./spec/lib/weichat_rails/api_spec.rb[1:7:1] | passed | 0.00115 seconds |
16
+ ./spec/lib/weichat_rails/api_spec.rb[1:8:1] | passed | 0.00113 seconds |
17
+ ./spec/lib/weichat_rails/api_spec.rb[1:8:2] | passed | 0.00118 seconds |
18
+ ./spec/lib/weichat_rails/api_spec.rb[1:9:1] | passed | 0.00109 seconds |
19
+ ./spec/lib/weichat_rails/api_spec.rb[1:10:1] | passed | 0.00115 seconds |
20
+ ./spec/lib/weichat_rails/api_spec.rb[1:11:1] | passed | 0.00115 seconds |
21
+ ./spec/lib/weichat_rails/api_spec.rb[1:12:1] | passed | 0.00117 seconds |
22
+ ./spec/lib/weichat_rails/api_spec.rb[1:13:1] | passed | 0.00119 seconds |
23
+ ./spec/lib/weichat_rails/api_spec.rb[1:14:1] | passed | 0.00115 seconds |
24
+ ./spec/lib/weichat_rails/api_spec.rb[1:14:2] | passed | 0.00116 seconds |
25
+ ./spec/lib/weichat_rails/api_spec.rb[1:15:1] | passed | 0.00114 seconds |
26
+ ./spec/lib/weichat_rails/api_spec.rb[1:16:1] | passed | 0.00116 seconds |
27
+ ./spec/lib/weichat_rails/api_spec.rb[1:17:1] | passed | 0.0024 seconds |
28
+ ./spec/lib/weichat_rails/api_spec.rb[1:18:1] | passed | 0.00128 seconds |
29
+ ./spec/lib/weichat_rails/api_spec.rb[1:19:1] | passed | 0.00118 seconds |
30
+ ./spec/lib/weichat_rails/api_spec.rb[1:20:1] | passed | 0.00116 seconds |
31
+ ./spec/lib/weichat_rails/api_spec.rb[1:21:1] | passed | 0.00108 seconds |
32
+ ./spec/lib/weichat_rails/api_spec.rb[1:22:1] | passed | 0.00113 seconds |
33
+ ./spec/lib/weichat_rails/api_spec.rb[1:23:1] | passed | 0.00116 seconds |
34
+ ./spec/lib/weichat_rails/api_spec.rb[1:24:1] | passed | 0.00117 seconds |
35
+ ./spec/lib/weichat_rails/api_spec.rb[1:25:1] | passed | 0.00139 seconds |
36
+ ./spec/lib/weichat_rails/api_spec.rb[1:26:1] | passed | 0.00134 seconds |
37
+ ./spec/lib/weichat_rails/client_spec.rb[1:1:1] | passed | 0.00136 seconds |
38
+ ./spec/lib/weichat_rails/client_spec.rb[1:2:1] | passed | 0.0043 seconds |
39
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:1] | passed | 0.00085 seconds |
40
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:2] | passed | 0.00238 seconds |
41
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:3] | passed | 0.00357 seconds |
42
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:4] | passed | 0.0042 seconds |
43
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:5:1] | passed | 0.00078 seconds |
44
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:5:2] | passed | 0.00092 seconds |
45
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:5:3] | passed | 0.00184 seconds |
46
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:6:1] | passed | 0.01241 seconds |
47
+ ./spec/lib/weichat_rails/client_spec.rb[1:3:6:2] | passed | 0.0011 seconds |
48
+ ./spec/lib/weichat_rails/message_spec.rb[1:1:1] | passed | 0.00021 seconds |
49
+ ./spec/lib/weichat_rails/message_spec.rb[1:2:1] | passed | 0.00026 seconds |
50
+ ./spec/lib/weichat_rails/message_spec.rb[1:3:1] | passed | 0.00244 seconds |
51
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:1] | passed | 0.00033 seconds |
52
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:2] | passed | 0.00023 seconds |
53
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:3] | passed | 0.0005 seconds |
54
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:4] | passed | 0.00078 seconds |
55
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:5] | passed | 0.00115 seconds |
56
+ ./spec/lib/weichat_rails/message_spec.rb[1:4:6] | passed | 0.00076 seconds |
57
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:1:1] | passed | 0.00023 seconds |
58
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:2:1] | passed | 0.0002 seconds |
59
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:3:1] | passed | 0.00024 seconds |
60
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:4:1] | passed | 0.00023 seconds |
61
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:5:1] | passed | 0.00021 seconds |
62
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:6:1] | passed | 0.00037 seconds |
63
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:7:1] | passed | 0.00045 seconds |
64
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:8:1] | passed | 0.00056 seconds |
65
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:8:2] | passed | 0.00048 seconds |
66
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:9:1] | passed | 0.20899 seconds |
67
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:9:2] | passed | 0.00724 seconds |
68
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:1] | passed | 0.00029 seconds |
69
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:2] | passed | 0.00026 seconds |
70
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:3] | passed | 0.00028 seconds |
71
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:4] | passed | 0.0004 seconds |
72
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:5] | passed | 0.00051 seconds |
73
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:10:6] | passed | 0.00059 seconds |
74
+ ./spec/lib/weichat_rails/message_spec.rb[1:5:11:1] | passed | 0.0011 seconds |
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe WeichatRails::AccessToken do
4
+ let(:token) { '12345' }
5
+ let(:client) { double(:client) }
6
+
7
+ subject { WeichatRails::AccessToken.new(client,'appid','secret') }
8
+
9
+ before :each do
10
+ allow(client).to receive(:get).with('token', params: {grant_type: 'client_credential', appid: 'appid', secret: 'secret'})
11
+ .and_return("access_token" => '12345', "expires_in" => 7200)
12
+ end
13
+
14
+ after :each do
15
+ WeichatRails.config.cache.delete(subject.appid)
16
+ end
17
+
18
+ describe '#token' do
19
+ it 'read from mamcache if access_token is not initialized' do
20
+ WeichatRails.config.cache.set(subject.appid,'12345',7200)
21
+ expect(subject.token).to eq('12345')
22
+ end
23
+
24
+ it "refresh access_token if token file did'n exist" do
25
+ expect(WeichatRails.config.cache.get(subject.appid)).to be nil
26
+ expect(subject.token).to eq('12345')
27
+ expect(WeichatRails.config.cache.get(subject.appid)).to eq('12345')
28
+ end
29
+
30
+ it 'raise exception if token failed' do
31
+ allow(client).to receive(:get).and_raise('error')
32
+ expect{subject.token}.to raise_error('error')
33
+ end
34
+ end
35
+
36
+ describe '#refresh' do
37
+ it 'will delete access_token' do
38
+ expect(subject.refresh).to eq(WeichatRails.config.cache.get(subject.appid))
39
+ expect(subject.token).to eq('12345')
40
+ end
41
+
42
+ end
43
+
44
+
45
+
46
+
47
+
48
+ end
@@ -0,0 +1,276 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe WeichatRails::Api do
4
+
5
+ subject do
6
+ WeichatRails::Api.new('appid','secret',20,false)
7
+ end
8
+
9
+ before :each do
10
+ allow(subject.access_token).to receive(:token).and_return('access_token')
11
+ end
12
+
13
+ describe '#client.base' do
14
+ it 'with get correct API_BASE' do
15
+ expect(subject.client.base).to eq WeichatRails::Api::API_BASE
16
+ end
17
+ end
18
+
19
+ describe '#callbackip' do
20
+ it 'will get callbackip with access_token' do
21
+ server_ip_result = 'server_ip_result'
22
+ expect(subject.client).to receive(:get).with('getcallbackip', params: { access_token: 'access_token'}).and_return(server_ip_result)
23
+ expect(subject.callbackip).to eq server_ip_result
24
+
25
+ end
26
+ end
27
+
28
+ describe '#qcode' do
29
+ it 'will get showqrcode with ticket at file based api endpoint as file' do
30
+ ticket_result = 'ticket_result'
31
+
32
+ expect(subject.client).to receive(:get).with('showqrcode', params: {ticket: 'ticket'}, base: WeichatRails::Api::MP_BASE, as: :file).and_return(ticket_result)
33
+
34
+ expect(subject.qrcode('ticket')).to eq(ticket_result)
35
+ end
36
+ end
37
+
38
+ describe '#groups' do
39
+ before :each do
40
+ @groups_result = 'groups_result'
41
+ expect(subject.client).to receive(:get).with('groups/get', params: {access_token: 'access_token'}).and_return(@groups_result)
42
+ end
43
+
44
+ it 'will get groups with access_token' do
45
+ expect(subject.groups).to eq(@groups_result)
46
+ end
47
+
48
+ it 'will get groups with access_token by groups alias' do
49
+ expect(subject.group_get).to eq(@groups_result)
50
+ end
51
+ end
52
+
53
+ describe '#group_create' do
54
+ it 'will post groups/create with access_token and new group json_data' do
55
+ new_group = { group: {name: 'new_group_name'}}
56
+ expect(subject.client).to receive(:post).with('groups/create', new_group.to_json, params: {access_token: 'access_token'} ).and_return(true)
57
+ expect(subject.group_create('new_group_name')).to be_truthy
58
+ end
59
+ end
60
+
61
+ describe '#group_update' do
62
+ before :each do
63
+ update_group = { group: {id: 108, name: 'test2_modify'}}
64
+ expect(subject.client).to receive(:post).with('groups/update', update_group.to_json, params: {access_token: 'access_token'}).and_return(true)
65
+ end
66
+
67
+ it 'will post groups/update with access_token and json_data' do
68
+ expect(subject.group_update(108,'test2_modify')).to be_truthy
69
+ end
70
+
71
+ it 'will post group/update with access_token and json_data by alias method group_name_update' do
72
+ expect(subject.group_name_update(108, 'test2_modify')).to be_truthy
73
+ end
74
+ end
75
+
76
+
77
+ describe '#group_delete' do
78
+ it 'will post groups/delete with access_token' do
79
+ delete_group = {group: {id: 108}}
80
+ expect(subject.client).to receive(:post).with('groups/delete', delete_group.to_json, params: {access_token: 'access_token'}).and_return(true)
81
+ expect(subject.group_delete(108)).to be_truthy
82
+ end
83
+ end
84
+
85
+
86
+ describe '#users' do
87
+ it 'will get user/get with access_token' do
88
+ users_result = "users_result"
89
+ expect(subject.client).to receive(:get).with('user/get', params: {access_token: 'access_token'}).and_return(users_result)
90
+ expect(subject.users).to eq(users_result)
91
+ end
92
+
93
+ it 'will get user/get with access_token and next_openid' do
94
+ users_result = 'users_result'
95
+ expect(subject.client).to receive(:get).with('user/get', params: {access_token: 'access_token', next_openid: 'next_openid'}).and_return(users_result)
96
+ expect(subject.users('next_openid')).to eq(users_result)
97
+
98
+ end
99
+ end
100
+
101
+
102
+ describe '#user' do
103
+ it 'will get user/info with access_token and openid' do
104
+ user_result = 'user_result'
105
+ expect(subject.client).to receive(:get).with('user/info', params: {access_token: 'access_token', openid: 'openid'}).and_return(user_result)
106
+ expect(subject.user('openid')).to eq(user_result)
107
+ end
108
+ end
109
+
110
+ describe '#user_group' do
111
+ it 'will post groups/getid with access_token and openid to get user groups info' do
112
+ user_request = {openid: 'openid'}
113
+ user_response = {gruopid: 102}
114
+ expect(subject.client).to receive(:post).with('groups/getid', user_request.to_json, params: {access_token: 'access_token'}).and_return(user_response)
115
+ expect(subject.user_group('openid')).to eq(user_response)
116
+ end
117
+ end
118
+
119
+ describe '#user_change_group' do
120
+ it 'will post groups/members/update with access_token and openid to get user groups info' do
121
+ user_request = {openid: 'openid', to_groupid: 108}
122
+ expect(subject.client).to receive(:post).with('groups/members/update', user_request.to_json, params: {access_token: 'access_token'}).and_return(true)
123
+ expect(subject.user_change_group('openid',108)).to be_truthy
124
+ end
125
+ end
126
+
127
+ describe '#user_update_remark' do
128
+ it 'will post groups/info/updatermark with access_token and openid to set user remark' do
129
+ user_update_remark_request = {openid: 'openid', remark: 'remark'}
130
+ user_update_remark_result = {errorcode: 0, errmsg: 'ok'}
131
+ expect(subject.client).to receive(:post).with('user/info/updateremark', user_update_remark_request.to_json, params: {access_token: 'access_token'}).and_return(user_update_remark_result)
132
+ expect(subject.user_update_remark('openid','remark')).to eq(user_update_remark_result)
133
+ end
134
+ end
135
+
136
+ describe '#qrcode_create_scene' do
137
+ it 'will post qrcode/create with access_token, scene_id and expire_seconds' do
138
+ scene_id = 101
139
+ qrcode_scene_res = {expire_seconds: 60, action_name: 'QR_SCENE', action_info: {scene: {scene_id: scene_id}}}
140
+ qrcode_scene_result = {ticket: 'qr_code_ticket', expire_seconds: 60, url: 'qr_code_ticket_pic_url'}
141
+ expect(subject.client).to receive(:post).with('qrcode/create', qrcode_scene_res.to_json, params: {access_token: 'access_token'}).and_return(qrcode_scene_result)
142
+ expect(subject.qrcode_create_scene(scene_id, 60)).to eq(qrcode_scene_result)
143
+ end
144
+ end
145
+
146
+
147
+ describe '#qrcode_create_limit_scene' do
148
+ qrcode_limit_scene_result = {ticket: 'qr_code_ticket', url: 'qr_code_ticket_pic_url'}
149
+
150
+ it 'will post qrcode/create with access_token and scene_id' do
151
+ scene_id = 101
152
+ qrcode_limit_scene_req = {action_name: 'QR_LIMIT_SCENE', action_info: {scene: {scene_id: scene_id}}}
153
+ expect(subject.client).to receive(:post).with('qrcode/create', qrcode_limit_scene_req.to_json, params: {access_token: 'access_token'}).and_return(qrcode_limit_scene_result)
154
+ expect(subject.qrcode_create_limit_scene(scene_id)).to eq(qrcode_limit_scene_result)
155
+ end
156
+
157
+ it 'will post qrcode/create with access_token and scene_str' do
158
+ scene_str = 'scene_str'
159
+ qrcode_limit_str_scene_req = {action_name: 'QR_LIMIT_STR_SCENE', action_info: {scene: {scene_str: scene_str}}}
160
+ expect(subject.client).to receive(:post).with('qrcode/create', qrcode_limit_str_scene_req.to_json, params: {access_token: 'access_token'}).and_return(qrcode_limit_scene_result)
161
+ expect(subject.qrcode_create_limit_scene(scene_str)).to eq(qrcode_limit_scene_result)
162
+ end
163
+ end
164
+
165
+ describe '#menu' do
166
+ it 'will get menu/get with access_token' do
167
+ menu_result = 'menu_result'
168
+ expect(subject.client).to receive(:get).with('menu/get', params: {access_token: 'access_token'}).and_return(menu_result)
169
+ expect(subject.menu).to eq(menu_result)
170
+ end
171
+ end
172
+
173
+ describe '#menu_create' do
174
+ it 'will post menu/create with access_token and json_data' do
175
+ menu = {buttons: ['a_button']}
176
+ expect(subject.client).to receive(:post).with('menu/create', menu.to_json, params: {access_token: 'access_token'}).and_return(true)
177
+ expect(subject.menu_create(menu)).to be true
178
+ end
179
+ end
180
+
181
+ describe '#menu_delete' do
182
+ it 'will get menu/delete with access_token' do
183
+ expect(subject.client).to receive(:get).with('menu/delete', params: {access_token: 'access_token'}).and_return(true)
184
+ expect(subject.menu_delete).to be true
185
+ end
186
+ end
187
+
188
+ describe '#media' do
189
+ it 'will get media/get with access_token and media_id at file based api endpoint as file' do
190
+ media_result = 'media_result'
191
+ expect(subject.client).to receive(:get).with('media/get', params: {access_token: 'access_token', media_id: 'media_id'}, as: :file).and_return(media_result)
192
+ expect(subject.media('media_id')).to eq(media_result)
193
+
194
+ end
195
+ end
196
+
197
+ describe '#media_create' do
198
+ it 'will post media/upload with access_token,type and media payload at file based api endpoint' do
199
+ file = "README.md"
200
+ expect(subject.client).to receive(:post_file).with('media/upload',file, params: {type: 'image', access_token: 'access_token'}).and_return(true)
201
+ expect(subject.media_create('image',file)).to be true
202
+ end
203
+ end
204
+
205
+ describe '#material' do
206
+ it 'will get material/get with access_token and media_id at file based api endpoint as file' do
207
+ material_result = 'material_result'
208
+ expect(subject.client).to receive(:get).with('material/get', params: {access_token: 'access_token', media_id: 'media_id'}, as: :file).and_return(material_result)
209
+ expect(subject.material('media_id')).to eq(material_result)
210
+ end
211
+ end
212
+
213
+ describe '#material_count' do
214
+ it 'will get material_count with access_token' do
215
+ material_count_result = {voice_count: 1, video_count: 2, image_count: 3, news_count: 4}
216
+ expect(subject.client).to receive(:get).with('material/get_materialcount', params: { access_token: 'access_token'}).and_return(material_count_result)
217
+ expect(subject.material_count).to eq(material_count_result)
218
+
219
+ end
220
+ end
221
+
222
+ describe '#material_list' do
223
+ it 'will get material list with access_token' do
224
+ material_list_request = {type: 'image', offset: 0, count: 20}
225
+ material_list_result = {total_count: 1, item_count: 1, item: [{media_id: 'media_id', name: 'name', update_time: 12345, url: 'url'}]}
226
+ expect(subject.client).to receive(:post).with('material/batchget_material', material_list_request.to_json, params: { access_token: 'access_token'}).and_return(material_list_result)
227
+ expect(subject.material_list('image', 0, 20)).to eq(material_list_result)
228
+ end
229
+ end
230
+
231
+ describe '#material_add' do
232
+ it 'will post material/add_material with access_token, type and media payload at file based api endpoint' do
233
+ file = "README.md"
234
+ expect(subject.client).to receive(:post_file).with('material/add_material', file, params: {type: 'image', access_token: 'access_token'}).and_return(true)
235
+ expect(subject.material_add('image',file)).to be true
236
+ end
237
+ end
238
+
239
+ describe '#material_delete' do
240
+ it 'will post material/del_material with access_token and media_id in payload' do
241
+ media_id = 'media_id'
242
+ material_delete_result = {errcode: 0, errmsg: 'deleted'}
243
+ expect(subject.client).to receive(:post).with('material/del_material', {media_id: media_id}, params: {access_token: 'access_token'}).and_return(material_delete_result)
244
+ expect(subject.material_delete(media_id)).to eq(material_delete_result)
245
+ end
246
+ end
247
+
248
+ describe '#custom_message_send' do
249
+ it 'will post message/custom/send with access_token, and json payload' do
250
+ payload = {touser: 'openid', msgtype: 'text', text: {content: 'message content'}}
251
+ expect(subject.client).to receive(:post).with('message/custom/send', payload.to_json, params: { access_token: 'access_token'}, content_type: :json).and_return(true)
252
+ expect(subject.custom_message_send(WeichatRails::Message.to('openid').text('message content'))).to be true
253
+ end
254
+ end
255
+
256
+ describe '#template_message_send' do
257
+ it 'will post message/template/send with access_token, and json payload' do
258
+ payload = { touser: 'OPENID',
259
+ template_id: 'ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY',
260
+ url: 'http://weixin.qq.com/download',
261
+ topcolor: '#FF0000',
262
+ data: { first: { value: '恭喜你购买成功!', color: '#173177' },
263
+ keynote1: { value: '巧克力', color: '#173177' },
264
+ keynote2: { value: '39.8元', color: '#173177' },
265
+ keynote3: { value: '2014年9月16日', color: '#173177' },
266
+ remark: { value: '欢迎再次购买!', color: '#173177' } } }
267
+ response_result = { errcode: 0, errmsg: 'ok', msgid: 332 }
268
+
269
+ expect(subject.client).to receive(:post).with('message/template/send', payload.to_json, params: {access_token: 'access_token'},content_type: :json).and_return(response_result)
270
+ expect(subject.template_message_send(payload)).to eq(response_result)
271
+ end
272
+ end
273
+
274
+
275
+
276
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe WeichatRails::Client do
4
+ subject { WeichatRails::Client.new('http://host/',20,false) }
5
+
6
+ let(:response_params) do
7
+ {
8
+ headers: {content_type: 'text/plain'},
9
+ status: 200
10
+ }
11
+ end
12
+
13
+ let(:response_404) { double '404', response_params.merge(status: 404) }
14
+ let(:response_text) { double 'text', response_params.merge(body: 'some text') }
15
+ let(:response_json) { double 'json', response_params.merge(body: {result: 'success'}.to_json, headers: {content_type: 'application/json'}) }
16
+ let(:response_image) { double 'image', response_params.merge(body: 'image data', headers: {content_type: 'image/gif'}) }
17
+
18
+ describe '#get' do
19
+ it 'will use http get method to request data' do
20
+ allow(HTTP).to receive_message_chain('headers.get') {response_json}
21
+ subject.get('token')
22
+ end
23
+ end
24
+
25
+ describe '#post' do
26
+ it 'Will use http post method to request data' do
27
+ allow(HTTP).to receive_message_chain('headers.post') {response_json}
28
+ subject.post('token','some_data')
29
+ end
30
+ end
31
+
32
+ describe '#request' do
33
+ it 'will add accept => :json for request' do
34
+ block = lambda do |url, headers|
35
+ expect(url).to eq('http://host/token')
36
+ expect(headers).to eq(params: { access_token: '1234'}, 'Accept' => 'application/json')
37
+ response_json
38
+ end
39
+
40
+ subject.send(:request, 'token', params: {access_token: '1234'}, &block )
41
+ end
42
+
43
+ it 'will use base option to construct url' do
44
+ block = lambda do |url,_headers|
45
+ expect(url).to eq('http://override/token')
46
+ response_json
47
+ end
48
+ subject.send(:request, 'token', base: 'http://override/', &block)
49
+
50
+ end
51
+
52
+ it 'will not pass as option for request' do
53
+ block = lambda do |_url,headers|
54
+ expect(headers[:as]).to be_nil
55
+ response_json
56
+ end
57
+ subject.send(:request, 'token', as: :text, &block)
58
+
59
+ end
60
+
61
+ it 'will raise error if response code is not 200' do
62
+ expect { subject.send(:request, 'token'){ response_404} }.to raise_error(/Request not OK/)
63
+ end
64
+
65
+
66
+ context 'parse response body' do
67
+ it 'will return response body for text response' do
68
+ expect(subject.send(:request, 'text', as: :text){ response_text }).to eq(response_text.body)
69
+ end
70
+
71
+ it 'will return response body as file for image' do
72
+ expect(subject.send(:request, 'image'){ response_image }).to be_a(Tempfile)
73
+ end
74
+
75
+ it 'will return response body as file for unknown content_type' do
76
+ response_stream = double 'image', response_params.merge(body: 'stream', headers: {content_type: 'stream'})
77
+ expect(subject.send(:request, 'image', as: :file){response_stream}).to be_a(Tempfile)
78
+ end
79
+
80
+ end
81
+
82
+ context 'json error' do
83
+ it 'raise ResponseError given response has error json' do
84
+ allow(response_json).to receive(:body).and_return({ errcode: 1106, errmsg: 'error message'}.to_json)
85
+ expect { subject.send(:request, 'image', as: :file){response_json} }.to raise_error(WeichatRails::ResponseError)
86
+ end
87
+
88
+ it 'raise AccessTokenExpiredError given response has error json with errorcode 40014' do
89
+ allow(response_json).to receive(:body).and_return( {errcode: 40014, errmsg: 'error_message'}.to_json )
90
+ expect { subject.send(:request, 'image', as: :file) {response_json} }.to raise_error(WeichatRails::AccessTokenExpiredError)
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ end