weichat_rails 0.1.0 → 2.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.
- 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 +69 -62
- data/lib/weichat_rails/version.rb +1 -1
- data/lib/weichat_rails.rb +17 -7
- 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 +9 -6
- metadata +102 -30
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,13 +38,14 @@ 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
50
|
|
41
51
|
if defined? ActionController::Base
|
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
|