weichat_rails 0.0.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +1 -1
- data/lib/weichat_rails/access_token.rb +2 -3
- data/lib/weichat_rails/api.rb +122 -27
- data/lib/weichat_rails/auto_generate_secret_key.rb +1 -0
- data/lib/weichat_rails/client.rb +34 -17
- data/lib/weichat_rails/message.rb +53 -26
- data/lib/weichat_rails/responder.rb +70 -63
- data/lib/weichat_rails/version.rb +1 -1
- data/lib/weichat_rails.rb +17 -8
- data/spec/examples.txt +74 -0
- data/spec/lib/weichat_rails/access_token_spec.rb +48 -0
- data/spec/lib/weichat_rails/api_spec.rb +276 -0
- data/spec/lib/weichat_rails/client_spec.rb +96 -0
- data/spec/lib/weichat_rails/message_spec.rb +283 -0
- data/spec/lib/weichat_rails/responder_spec.rb +5 -0
- data/spec/spec_helper.rb +99 -0
- data/weichat_rails.gemspec +10 -8
- metadata +105 -34
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
|
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
|
-
#
|
33
|
-
#DEFAULT_WECHAT_SECRET_KEY = "wechat_secret_key".freeze
|
34
|
-
|
41
|
+
#config.cache_namespace = 'weichat_rails'
|
35
42
|
|
36
|
-
#
|
37
|
-
|
38
|
-
|
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
|