mp_weixin 0.1.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.
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,111 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Client do
5
+ let(:client) { MpWeixin::Client.new }
6
+ let(:access_token) { 'ACCESS_TOKEN' }
7
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
8
+
9
+
10
+ context "#initialize config" do
11
+ it "should have correct site" do
12
+ client.site.should eq("https://api.weixin.qq.com/")
13
+ end
14
+
15
+ # it "should have correct authorize url" do
16
+ # client.options[:authorize_url].should eq('/oauth/authorize')
17
+ # end
18
+
19
+ it "should have correct token url" do
20
+ client.options[:token_url].should eq('/cgi-bin/token')
21
+ end
22
+
23
+ it 'is_authorized? should been false' do
24
+ expect(subject.is_authorized?).to eq(false)
25
+ end
26
+ end
27
+
28
+ context "#taken_code" do
29
+ let(:json_token) {MultiJson.encode(:expires_in => 7200, :access_token => 'salmon')}
30
+
31
+ let(:client) do
32
+ MpWeixin::Client.new do |builder|
33
+ builder.request :url_encoded
34
+ builder.adapter :test do |stub|
35
+ stub.get("/cgi-bin/token") do |env|
36
+ [200, {'Content-Type' => 'application/json'}, json_token]
37
+ end
38
+ stub.post('/cgi-bin/token') do |env|
39
+ [200, {'Content-Type' => 'application/json'}, json_token]
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ subject do
46
+ client.get_token
47
+ client
48
+ end
49
+
50
+
51
+ it "returns AccessToken with #token" do
52
+ expect(subject.token.token).to eq('salmon')
53
+ end
54
+
55
+ it 'is_authorized? should been true' do
56
+ expect(subject.is_authorized?).to eq(true)
57
+ end
58
+ end
59
+
60
+ context "get_token_from_hash" do
61
+ subject { client.get_token_from_hash(token_hash) }
62
+
63
+ it "return token the initalized AccessToken" do
64
+ expect(subject).to be_a(MpWeixin::AccessToken)
65
+ end
66
+
67
+ it "return token with provide access_token" do
68
+ expect(subject.token).to eq(access_token)
69
+ end
70
+ end
71
+
72
+ context "#from_hash" do
73
+ subject { MpWeixin::Client.from_hash(token_hash) }
74
+
75
+ it "return client the initalized Client" do
76
+ expect(subject).to be_a(MpWeixin::Client)
77
+ end
78
+
79
+ it "return token with provide access_token" do
80
+ expect(subject.token.token).to eq(access_token)
81
+ end
82
+
83
+ it 'is_authorized? should been true' do
84
+ expect(subject.is_authorized?).to eq(true)
85
+ end
86
+ end
87
+
88
+ context "#apis" do
89
+ subject { MpWeixin::Client.from_hash(token_hash) }
90
+
91
+ it "should have instance of Interface::Message" do
92
+ expect(subject.message).to be_a(MpWeixin::Interface::Message)
93
+ end
94
+
95
+ it "should have instance of Interface::Menu" do
96
+ expect(subject.menu).to be_a(MpWeixin::Interface::Menu)
97
+ end
98
+
99
+ it "should have instance of Interface::Promotion" do
100
+ expect(subject.promotion).to be_a(MpWeixin::Interface::Promotion)
101
+ end
102
+
103
+ it "should have instance of Interface::Group" do
104
+ expect(subject.group).to be_a(MpWeixin::Interface::Group)
105
+ end
106
+
107
+ it "should have instance of Interface::User" do
108
+ expect(subject.user).to be_a(MpWeixin::Interface::User)
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Config do
5
+ let(:config) { MpWeixin::Config }
6
+
7
+ context "#initialize config" do
8
+ it "should have correct app_id" do
9
+ config.app_id.should eq("12341432134")
10
+ end
11
+
12
+ it "should have correct app_secret" do
13
+ config.app_secret.should eq('app_secret')
14
+ end
15
+
16
+ it "should have correct url" do
17
+ config.url.should eq('http://www.example.com')
18
+ end
19
+
20
+ it "should have correct token" do
21
+ config.token.should eq('secret')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe MpWeixin::Interface::Base do
4
+ let(:access_token) { 'ACCESS_TOKEN' }
5
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
6
+ let (:client) { MpWeixin::Client.from_hash(token_hash) }
7
+
8
+ context "#initialize interface" do
9
+ subject { MpWeixin::Interface::Base.new(client) }
10
+
11
+ it "should have default_request_params" do
12
+ expect(subject.default_request_params).to eq({"access_token" => access_token})
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Interface::Group do
5
+ let(:access_token) { 'ACCESS_TOKEN' }
6
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
7
+ let(:group_create_json) {
8
+ MultiJson.encode({
9
+ group: {
10
+ name: "test"
11
+ }
12
+ })
13
+ }
14
+
15
+ let (:sucess_create_group) {
16
+ MultiJson.encode({
17
+ group: {
18
+ id: 107,
19
+ name: "test"
20
+ }
21
+ })
22
+ }
23
+ let (:all_groups) {
24
+ MultiJson.encode({
25
+ groups: [
26
+ {
27
+ id: 0,
28
+ name: "未分组",
29
+ count: 72596
30
+ },
31
+ {
32
+ id: 1,
33
+ name: "黑名单",
34
+ count: 36
35
+ },
36
+ {
37
+ id: 2,
38
+ name: "星标组",
39
+ count: 8
40
+ },
41
+ {
42
+ id: 104,
43
+ name: "华东媒",
44
+ count: 4
45
+ },
46
+ {
47
+ id: 106,
48
+ name: "★不测试组★",
49
+ count: 1
50
+ }
51
+ ]
52
+ })
53
+ }
54
+ let(:getid_json) {
55
+ MultiJson.encode({
56
+ openid: "od8XIjsmk6QdVTETa9jLtGWA6KBc"
57
+ })
58
+ }
59
+ let(:sucess_getid) {
60
+ MultiJson.encode({
61
+ groupid: 102
62
+ })
63
+ }
64
+ let(:update_json) {
65
+ MultiJson.encode({
66
+ group: {
67
+ id: 108,
68
+ name: "test2_modify2"
69
+ }
70
+ })
71
+ }
72
+
73
+ let(:update_members_json) {
74
+ MultiJson.encode({
75
+ openid: "oDF3iYx0ro3_7jD4HFRDfrjdCM58",
76
+ to_groupid: 108
77
+ })
78
+ }
79
+
80
+ let (:client) {
81
+ MpWeixin::Client.from_hash(token_hash) do |builder|
82
+ builder.request :url_encoded
83
+ builder.adapter :test do |stub|
84
+ stub.send(:post, "/cgi-bin/groups/create") {|env|
85
+ if env[:body].eql?(group_create_json)
86
+ [200, {'Content-Type' => 'application/json'}, sucess_create_group]
87
+ end
88
+ }
89
+ stub.send(:get, "/cgi-bin/groups/get") {|env| [200, {'Content-Type' => 'application/json'}, all_groups]}
90
+ stub.send(:post, "/cgi-bin/groups/getid") {|env|
91
+ if env[:body].eql?(getid_json)
92
+ [200, {'Content-Type' => 'application/json'}, sucess_getid]
93
+ end
94
+ }
95
+ stub.send(:post, "/cgi-bin/groups/update") {|env|
96
+ [200, {'Content-Type' => 'application/json'}, env[:body]]
97
+ }
98
+ stub.send(:post, "/cgi-bin/groups/members/update") {|env|
99
+ [200, {'Content-Type' => 'application/json'}, env[:body]]
100
+ }
101
+ end
102
+ end
103
+ }
104
+
105
+ context "#group" do
106
+
107
+ subject { MpWeixin::Interface::Group.new(client) }
108
+
109
+ it "create group with group_create_json" do
110
+ group_create_hash = JSON.parse group_create_json
111
+ expect(subject.create(group_create_hash).body).to eq(sucess_create_group)
112
+ end
113
+
114
+ it "get_groups all group have been created" do
115
+ expect(subject.get_groups.body).to eq(all_groups)
116
+ end
117
+
118
+ it "getid return groupid getid_hash within openid have been joined in" do
119
+ getid_hash = JSON.parse getid_json
120
+ expect(subject.getid(getid_hash).body).to eq(sucess_getid)
121
+ end
122
+
123
+ it "update update_hash have been created" do
124
+ update_hash = JSON.parse update_json
125
+ expect(subject.update(update_hash).body).to eq(update_json)
126
+ end
127
+
128
+ it "update_memgers move openid to groupid" do
129
+ update_members_hash = JSON.parse update_members_json
130
+ expect(subject.update_memgers(update_members_hash).body).to eq(update_members_json)
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Interface::Menu do
5
+ let(:access_token) { 'ACCESS_TOKEN' }
6
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
7
+ let(:menu_create_json) {
8
+ MultiJson.encode({
9
+ button: [
10
+ {
11
+ type: "click",
12
+ name: "今日歌曲",
13
+ key: "V1001_TODAY_MUSIC"
14
+ },
15
+ {
16
+ type: "click",
17
+ name: "歌手简介",
18
+ key: "V1001_TODAY_SINGER"
19
+ },
20
+ {
21
+ name: "菜单",
22
+ sub_button: [
23
+ {
24
+ type: "view",
25
+ name: "搜索",
26
+ url: "http://www.soso.com/"
27
+ },
28
+ {
29
+ type: "view",
30
+ name: "视频",
31
+ url: "http://v.qq.com/"
32
+ },
33
+ {
34
+ type: "click",
35
+ name: "赞一下我们",
36
+ key: "V1001_GOOD"
37
+ }]
38
+ }]
39
+ })
40
+ }
41
+
42
+ let (:sucess_delete) {
43
+ MultiJson.encode({errcode: 0, errmsg: "ok"})
44
+ }
45
+ let (:client) {
46
+ MpWeixin::Client.from_hash(token_hash) do |builder|
47
+ builder.request :url_encoded
48
+ builder.adapter :test do |stub|
49
+ stub.send(:post, "/cgi-bin/menu/create") {|env| [200, {'Content-Type' => 'application/json'}, menu_create_json]}
50
+ stub.send(:get, "/cgi-bin/menu/get") {|env| [200, {'Content-Type' => 'application/json'}, menu_create_json]}
51
+ stub.send(:get, "/cgi-bin/menu/delete") {|env| [200, {'Content-Type' => 'application/json'}, sucess_delete]}
52
+ end
53
+ end
54
+ }
55
+
56
+ context "#menu" do
57
+
58
+ subject { MpWeixin::Interface::Menu.new(client) }
59
+
60
+ it "create menu with menu_create_json" do
61
+ expect(subject.create(menu_create_json).body).to eq(menu_create_json)
62
+ end
63
+
64
+ it "get_menu menu have been created" do
65
+ expect(subject.get_menus.body).to eq(menu_create_json)
66
+ end
67
+
68
+ it "delete menu have been created" do
69
+ expect(subject.delete.body).to eq(sucess_delete)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Interface::Message do
5
+ let(:access_token) { 'ACCESS_TOKEN' }
6
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
7
+ let(:text_json) {
8
+ MultiJson.encode({
9
+ touser: "OPENID",
10
+ msgtype: "text",
11
+ text:
12
+ {
13
+ content: "Hello World"
14
+ }
15
+ })
16
+
17
+ }
18
+ let (:client) {
19
+ MpWeixin::Client.from_hash(token_hash) do |builder|
20
+ builder.request :url_encoded
21
+ builder.adapter :test do |stub|
22
+ stub.send(:post, "/cgi-bin/message/custom/send") {|env| [200, {'Content-Type' => 'application/json'}, text_json]}
23
+ end
24
+ end
25
+ }
26
+
27
+ context "#custom_send" do
28
+
29
+ subject { MpWeixin::Interface::Message.new(client) }
30
+
31
+ it "should have can post text_json" do
32
+ expect(subject.custom_send(text_json).body).to eq(text_json)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MpWeixin::Interface::Promotion do
5
+ let(:access_token) { 'ACCESS_TOKEN' }
6
+ let(:token_hash) { {"expires_in" => "7200", "access_token" => access_token} }
7
+ let(:qrcode_create_json) {
8
+ MultiJson.encode({
9
+ expire_seconds: 1800,
10
+ action_name: "QR_SCENE",
11
+ action_info: {
12
+ scene: { scene_id: 123}
13
+ }
14
+ })
15
+ }
16
+ let (:ticket) { "gQG28DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0FuWC1DNmZuVEhvMVp4NDNMRnNRAAIEesLvUQMECAcAAA==" }
17
+
18
+ let (:sucess_create) {
19
+ MultiJson.encode({
20
+ ticket: ticket,
21
+ expire_seconds: 1800
22
+ })
23
+ }
24
+ let (:client) {
25
+ MpWeixin::Client.from_hash(token_hash) do |builder|
26
+ builder.request :url_encoded
27
+ builder.adapter :test do |stub|
28
+ stub.send(:post, '/cgi-bin/qrcode/create') {|env| [200, {'Content-Type' => 'application/json'}, sucess_create]}
29
+ stub.send(:get, '/cgi-bin/showqrcode') {|env|
30
+ [200, {'Content-Type' => 'image/jpg'}, nil] if env[:url].to_s.include?("https://mp.weixin.qq.com/cgi-bin/showqrcode")
31
+ }
32
+ end
33
+ end
34
+ }
35
+
36
+ context "#promotion" do
37
+
38
+ subject { MpWeixin::Interface::Promotion.new(client) }
39
+
40
+ it "create qrcode with qrcode_create_json" do
41
+ expect(subject.create(qrcode_create_json).body).to eq(sucess_create)
42
+ end
43
+
44
+ it "showqrcode qrcode with ticket" do
45
+ expect(subject.showqrcode(ticket).content_type).to eq("image/jpg")
46
+ end
47
+ end
48
+ end