weixin_authorize_905 1.6.5
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/lib/weixin_authorize.rb +97 -0
- data/lib/weixin_authorize/api.rb +3 -0
- data/lib/weixin_authorize/api/custom.rb +176 -0
- data/lib/weixin_authorize/api/data_cube.rb +8 -0
- data/lib/weixin_authorize/api/groups.rb +60 -0
- data/lib/weixin_authorize/api/mass.rb +80 -0
- data/lib/weixin_authorize/api/media.rb +149 -0
- data/lib/weixin_authorize/api/menu.rb +36 -0
- data/lib/weixin_authorize/api/oauth.rb +50 -0
- data/lib/weixin_authorize/api/qrcode.rb +62 -0
- data/lib/weixin_authorize/api/template.rb +34 -0
- data/lib/weixin_authorize/api/user.rb +69 -0
- data/lib/weixin_authorize/carrierwave/weixin_uploader.rb +4 -0
- data/lib/weixin_authorize/client.rb +95 -0
- data/lib/weixin_authorize/config.rb +35 -0
- data/lib/weixin_authorize/handler.rb +3 -0
- data/lib/weixin_authorize/handler/exceptions.rb +5 -0
- data/lib/weixin_authorize/handler/global_code.rb +127 -0
- data/lib/weixin_authorize/handler/result_handler.rb +52 -0
- data/lib/weixin_authorize/js_ticket/object_store.rb +21 -0
- data/lib/weixin_authorize/js_ticket/redis_store.rb +41 -0
- data/lib/weixin_authorize/js_ticket/store.rb +40 -0
- data/lib/weixin_authorize/token/object_store.rb +25 -0
- data/lib/weixin_authorize/token/redis_store.rb +38 -0
- data/lib/weixin_authorize/token/store.rb +72 -0
- data/lib/weixin_authorize/version.rb +3 -0
- data/spec/1_fetch_access_token_spec.rb +43 -0
- data/spec/2_fetch_jsticket_spec.rb +10 -0
- data/spec/api/custom_spec.rb +71 -0
- data/spec/api/groups_spec.rb +74 -0
- data/spec/api/mass_spec.rb +70 -0
- data/spec/api/media_spec.rb +82 -0
- data/spec/api/medias/favicon.ico +0 -0
- data/spec/api/medias/ruby-logo.jpg +0 -0
- data/spec/api/menu_spec.rb +26 -0
- data/spec/api/qrcode_spec.rb +22 -0
- data/spec/api/template_spec.rb +40 -0
- data/spec/api/user_spec.rb +26 -0
- data/spec/spec_helper.rb +130 -0
- data/weixin_authorize.gemspec +48 -0
- metadata +301 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Token
|
4
|
+
class RedisStore < Store
|
5
|
+
|
6
|
+
def valid?
|
7
|
+
weixin_redis.del(client.redis_key)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def token_expired?
|
12
|
+
weixin_redis.hvals(client.redis_key).empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh_token
|
16
|
+
super
|
17
|
+
weixin_redis.hmset(
|
18
|
+
client.redis_key, "access_token",
|
19
|
+
client.access_token, "expired_at",
|
20
|
+
client.expired_at
|
21
|
+
)
|
22
|
+
weixin_redis.expireat(client.redis_key, client.expired_at.to_i)
|
23
|
+
end
|
24
|
+
|
25
|
+
def access_token
|
26
|
+
super
|
27
|
+
client.access_token = weixin_redis.hget(client.redis_key, "access_token")
|
28
|
+
client.expired_at = weixin_redis.hget(client.redis_key, "expired_at")
|
29
|
+
client.access_token
|
30
|
+
end
|
31
|
+
|
32
|
+
def weixin_redis
|
33
|
+
WeixinAuthorize.weixin_redis
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Token
|
4
|
+
class Store
|
5
|
+
|
6
|
+
attr_accessor :client
|
7
|
+
|
8
|
+
def initialize(client)
|
9
|
+
@client = client
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.init_with(client)
|
13
|
+
if WeixinAuthorize.weixin_redis.nil?
|
14
|
+
ObjectStore.new(client)
|
15
|
+
else
|
16
|
+
RedisStore.new(client)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
authenticate["valid"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticate
|
25
|
+
auth_result = http_get_access_token
|
26
|
+
auth = false
|
27
|
+
if auth_result.is_ok?
|
28
|
+
set_access_token(auth_result.result)
|
29
|
+
auth = true
|
30
|
+
end
|
31
|
+
{"valid" => auth, "handler" => auth_result}
|
32
|
+
end
|
33
|
+
|
34
|
+
def refresh_token
|
35
|
+
handle_valid_exception
|
36
|
+
set_access_token
|
37
|
+
end
|
38
|
+
|
39
|
+
def access_token
|
40
|
+
refresh_token if token_expired?
|
41
|
+
end
|
42
|
+
|
43
|
+
def token_expired?
|
44
|
+
raise NotImplementedError, "Subclasses must implement a token_expired? method"
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_access_token(access_token_infos=nil)
|
48
|
+
token_infos = access_token_infos || http_get_access_token.result
|
49
|
+
client.access_token = token_infos["access_token"]
|
50
|
+
client.expired_at = WeixinAuthorize.calculate_expire(token_infos["expires_in"])
|
51
|
+
end
|
52
|
+
|
53
|
+
def http_get_access_token
|
54
|
+
WeixinAuthorize.http_get_without_token("/token", authenticate_headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
def authenticate_headers
|
58
|
+
{grant_type: GRANT_TYPE, appid: client.app_id, secret: client.app_secret}
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_valid_exception
|
64
|
+
auth_result = authenticate
|
65
|
+
if !auth_result["valid"]
|
66
|
+
result_handler = auth_result["handler"]
|
67
|
+
raise ValidAccessTokenException, result_handler.full_error_message
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# NOTE: the rspec should be test alonely.
|
2
|
+
describe WeixinAuthorize::Client do
|
3
|
+
describe "#get access_token" do
|
4
|
+
it "return a access_token nil value before authenticate" do
|
5
|
+
expect($client.access_token).to eq(nil)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "appid and appsecret shoud be valid" do
|
9
|
+
valid_info = $client.is_valid?
|
10
|
+
expect(valid_info).to eq(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "return the same access_token in the same thing twice" do
|
14
|
+
access_token_1 = $client.get_access_token
|
15
|
+
sleep 5
|
16
|
+
access_token_2 = $client.get_access_token
|
17
|
+
expect(access_token_1).to eq(access_token_2)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "return errorcode and errormsg when appid or appsecret is invalid" do
|
21
|
+
$client_1 = WeixinAuthorize::Client.new("appid", "app_secret")
|
22
|
+
valid_info = $client_1.is_valid?
|
23
|
+
expect(valid_info).to eq(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "#get_access_token should raise error if app_secret or appid is invalid" do
|
27
|
+
$client_2 = WeixinAuthorize::Client.new("appid_2", "app_secret_2")
|
28
|
+
expect{$client_2.get_access_token}.to raise_error(RuntimeError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "#token_expired return the different access_token after token is expired" do
|
32
|
+
token_1 = $client.get_access_token
|
33
|
+
if WeixinAuthorize.weixin_redis.nil?
|
34
|
+
$client.expired_at = Time.now.to_i - 7300
|
35
|
+
else
|
36
|
+
WeixinAuthorize.weixin_redis.del($client.redis_key)
|
37
|
+
end
|
38
|
+
token_2 = $client.get_access_token
|
39
|
+
expect(token_1).to_not eq(token_2)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
describe WeixinAuthorize::Client do
|
2
|
+
describe "#get jsticket" do
|
3
|
+
it "return the same jsticket in the same thing twice" do
|
4
|
+
js_ticket_1 = $client.get_jsticket
|
5
|
+
sleep 5
|
6
|
+
js_ticket_2 = $client.get_jsticket
|
7
|
+
expect(js_ticket_1).to eq(js_ticket_2)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
describe WeixinAuthorize::Api::Custom do
|
2
|
+
let(:text_message) do
|
3
|
+
"text Custom message"
|
4
|
+
end
|
5
|
+
|
6
|
+
let(:image_path) do
|
7
|
+
"#{File.dirname(__FILE__)}/medias/ruby-logo.jpg"
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:image_file) do
|
11
|
+
File.new(image_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "#send_text_custom" do
|
15
|
+
response = $client.send_text_custom(ENV["OPENID"], text_message)
|
16
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#send_news_custom" do
|
20
|
+
articles = [{
|
21
|
+
"title" => "Happy Day",
|
22
|
+
"description" => "Is Really A Happy Day",
|
23
|
+
"url" => "http://www.baidu.com",
|
24
|
+
"picurl" => "http://www.baidu.com/img/bdlogo.gif"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"title" => "Happy Day",
|
28
|
+
"description" => "Is Really A Happy Day",
|
29
|
+
"url" => "http://www.baidu.com",
|
30
|
+
"picurl"=> "http://www.baidu.com/img/bdlogo.gif"
|
31
|
+
}]
|
32
|
+
response = $client.send_news_custom(ENV["OPENID"], articles)
|
33
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "#send_image_custom" do
|
37
|
+
image = $client.upload_media(image_file, "image")
|
38
|
+
media_id = image.result["media_id"]
|
39
|
+
response = $client.send_image_custom(ENV["OPENID"], media_id)
|
40
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#send_video_custom" do
|
44
|
+
pending("The test must have a media_id")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "#send_mpnews_custom" do
|
48
|
+
pending("The test must have a media_id")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "#send_music_custom" do
|
52
|
+
pending("The test must have a media_id")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "#send_voice_custom" do
|
56
|
+
pending("The test must have a media_id")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "#get_custom_msg_record" do
|
60
|
+
option = {pageindex: 1, pagesize: 10}
|
61
|
+
response = $client.get_custom_msg_record(Time.now - 10.days, Time.now, option)
|
62
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
63
|
+
expect(response.result.keys).to eq(["recordlist", "retcode"])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "#create_kf_session" do
|
67
|
+
response = $client.create_kf_session("test1@test", ENV["APPID"], "test kfsession")
|
68
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
describe WeixinAuthorize::Api::Groups do
|
2
|
+
|
3
|
+
let(:group_name) do
|
4
|
+
"test group_name"
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:group_name_2) do
|
8
|
+
"test group_name_2"
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:groups) do
|
12
|
+
$client.groups
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:last_group_id) do
|
16
|
+
groups.result["groups"][-1]["id"]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#delete all group step by step" do
|
20
|
+
group_ids = groups.result["groups"].collect{|group|group["id"]}
|
21
|
+
group_ids.each do |group_id|
|
22
|
+
res = $client.delete_group(group_id)
|
23
|
+
if res.code.to_s != "45009"
|
24
|
+
expect(res.code).to eq(WeixinAuthorize::OK_CODE)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "create a group" do
|
30
|
+
response = $client.create_group(group_name)
|
31
|
+
if response.code == WeixinAuthorize::OK_CODE
|
32
|
+
expect(response.result["group"]["name"]).to eq(group_name)
|
33
|
+
else
|
34
|
+
expect(response.code).to eq(-1)
|
35
|
+
puts "WEIXIN says: system error"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "get groups" do
|
40
|
+
expect(groups.result["groups"][-1]["name"]).to eq(group_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#get_group_for ENV['OPENID']" do
|
44
|
+
group = $client.get_group_for(ENV["OPENID"])
|
45
|
+
expect(group.result.keys).to eq(["groupid"])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "#update_group_name" do
|
49
|
+
response = $client.create_group(group_name)
|
50
|
+
if response.code != WeixinAuthorize::OK_CODE
|
51
|
+
expect(response.code).to eq(-1)
|
52
|
+
puts "WEIXIN says: system error"
|
53
|
+
else
|
54
|
+
expect(response.result["group"]["name"]).to eq(group_name)
|
55
|
+
response = $client.update_group_name(response.result["group"]["id"], group_name_2)
|
56
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
57
|
+
groups = $client.groups
|
58
|
+
expect(groups.result["groups"][-1]["name"]).to eq(group_name_2)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#update_group_for_openid" do
|
63
|
+
$client.update_group_for_openid(ENV["OPENID"], last_group_id)
|
64
|
+
group = $client.get_group_for(ENV["OPENID"])
|
65
|
+
expect(group.result["groupid"]).to eq(last_group_id)
|
66
|
+
$client.update_group_for_openid(ENV["OPENID"], 0)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "#batch update group for openids" do
|
70
|
+
res = $client.batch_update_group_for_openids([ENV["OPENID"]], last_group_id)
|
71
|
+
expect(res.code).to eq(WeixinAuthorize::OK_CODE)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe WeixinAuthorize::Api::Mass do
|
4
|
+
|
5
|
+
let(:image_jpg_path) do
|
6
|
+
"#{File.dirname(__FILE__)}/medias/ruby-logo.jpg"
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:news_media_1) do
|
10
|
+
{
|
11
|
+
"thumb_media_id" => "",
|
12
|
+
"author" => "lanrion",
|
13
|
+
"title" => "Happy Day",
|
14
|
+
"content_source_url" => "www.qq.com",
|
15
|
+
"content" => "content",
|
16
|
+
"digest" => "digest"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:image_media_id) do
|
21
|
+
# Get image media_id
|
22
|
+
image_media = $client.upload_media(image_jpg_path, "image")
|
23
|
+
media_id = image_media.result["media_id"]
|
24
|
+
media_id
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:mass_media_id) do
|
28
|
+
media = {"thumb_media_id" => image_media_id}
|
29
|
+
news_media = news_media_1.merge(media)
|
30
|
+
|
31
|
+
# upload news media
|
32
|
+
response = $client.upload_mass_news([news_media])
|
33
|
+
mass_media_id = response.result["media_id"]
|
34
|
+
mass_media_id
|
35
|
+
end
|
36
|
+
|
37
|
+
it "#upload_mass_news" do
|
38
|
+
media = {"thumb_media_id" => image_media_id}
|
39
|
+
news_media = news_media_1.merge(media)
|
40
|
+
|
41
|
+
# upload news media
|
42
|
+
response = $client.upload_mass_news([news_media])
|
43
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
44
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "#mass_with_group with mpnews" do
|
48
|
+
response = $client.mass_with_group("1", "mass_group_text", "text")
|
49
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#mass_with_groug send to all" do
|
53
|
+
response = $client.mass_with_group("1", "mass_group_text_to_all", "text", true)
|
54
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "#mass_with_openids with mpnews and can delete message" do
|
58
|
+
response = $client.mass_with_openids([ENV["OPENID"]], mass_media_id)
|
59
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
60
|
+
expect(response.result.keys).to eq(["msg_id"])
|
61
|
+
delete_res = $client.mass_delete_with_msgid(response.result["msg_id"])
|
62
|
+
expect(delete_res.code).to eq(WeixinAuthorize::OK_CODE)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "#mass_preview can preview by openid" do
|
66
|
+
response = $client.mass_preview(ENV["OPENID"], "mass_text", "text")
|
67
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
describe WeixinAuthorize::Api::Media do
|
2
|
+
|
3
|
+
let(:image_jpg_path) do
|
4
|
+
"#{File.dirname(__FILE__)}/medias/ruby-logo.jpg"
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:image_ico_path) do
|
8
|
+
"#{File.dirname(__FILE__)}/medias/favicon.ico"
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:image_jpg_file) do
|
12
|
+
File.new(image_jpg_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:image_ico_file) do
|
16
|
+
File.new(image_ico_path)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:remote_png_path) do
|
20
|
+
"https://ruby-china-files.b0.upaiyun.com/photo/5982eaaa64f467d9dbda03ad4f40ea27.png"
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:remote_jpg_path) do
|
24
|
+
"http://g.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=ce55457e4334970a537e187df4a3baad/03087bf40ad162d99455ef4d13dfa9ec8b13632762d0ed14.jpg"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can upload a jpg image and get url" do
|
28
|
+
response = $client.upload_image(image_jpg_file)
|
29
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
30
|
+
expect(response.result.keys).to eq(["url"])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can upload a png image and get url" do
|
34
|
+
response = $client.upload_image(remote_png_path)
|
35
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
36
|
+
expect(response.result.keys).to eq(["url"])
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can upload a jpg File image" do
|
40
|
+
response = $client.upload_media(image_jpg_file, "image")
|
41
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
42
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can upload a ico File image" do
|
46
|
+
response = $client.upload_media(image_ico_file, "image")
|
47
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
48
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can upload a local image" do
|
52
|
+
response = $client.upload_media(image_jpg_path, "image")
|
53
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
54
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can upload a local ico image" do
|
58
|
+
response = $client.upload_media(image_ico_path, "image")
|
59
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
60
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can upload a remote png image" do
|
64
|
+
response = $client.upload_media(remote_png_path, "image")
|
65
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
66
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
67
|
+
end
|
68
|
+
|
69
|
+
it "can upload a remote jpg image" do
|
70
|
+
response = $client.upload_media(remote_jpg_path, "image")
|
71
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
72
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "#download_media_url return a String url" do
|
76
|
+
image = $client.upload_media(image_ico_path, "image")
|
77
|
+
media_id = image.result["media_id"]
|
78
|
+
image_url = $client.download_media_url(media_id)
|
79
|
+
expect(image_url.class).to eq(String)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|