Commit 1ec92e44 by Francis Zhou

run rubocop

parent bce93b30
Style/AsciiComments:
Enabled: false
\ No newline at end of file
source "https://rubygems.org" # frozen_string_literal: true
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } source 'https://rubygems.org'
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# Specify your gem's dependencies in dingtalk.gemspec # Specify your gem's dependencies in dingtalk.gemspec
gemspec gemspec
require "bundler/gem_tasks" # frozen_string_literal: true
require "rspec/core/rake_task"
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
RSpec::Core::RakeTask.new(:spec) RSpec::Core::RakeTask.new(:spec)
task :default => :spec task default: :spec
RuboCop::RakeTask.new(:rubocop) do |task|
task.options = ['-A']
end
#!/usr/bin/env ruby #!/usr/bin/env ruby
# frozen_string_literal: true
require "bundler/setup" require 'bundler/setup'
require "dingtalk" require 'dingtalk'
# You can add fixtures and/or initialization code here to make experimenting # You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like. # with your gem easier. You can also use a different console, if you like.
...@@ -10,5 +11,5 @@ require "dingtalk" ...@@ -10,5 +11,5 @@ require "dingtalk"
# require "pry" # require "pry"
# Pry.start # Pry.start
require "irb" require 'irb'
IRB.start(__FILE__) IRB.start(__FILE__)
# frozen_string_literal: true
lib = File.expand_path("../lib", __FILE__) lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "dingtalk_sdk/version" require 'dingtalk_sdk/version'
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = "dingtalk_sdk" spec.name = 'dingtalk_sdk'
spec.version = DingtalkSdk::VERSION spec.version = DingtalkSdk::VERSION
spec.authors = ["francis"] spec.authors = ['francis']
spec.email = ["francis.tm@gmail.com"] spec.email = ['francis.tm@gmail.com']
spec.summary = %q{Dingtalk integration} spec.summary = 'Dingtalk integration'
spec.description = %q{Dingtalk ruby SKD} spec.description = 'Dingtalk ruby SKD'
spec.homepage = "https://github.com/francistm/dingtalk-sdk" spec.homepage = 'https://github.com/francistm/dingtalk-sdk'
spec.license = "MIT" spec.license = 'MIT'
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host. # to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata) if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "https://rubygems.pkg.github.com" spec.metadata['allowed_push_host'] = 'https://rubygems.pkg.github.com'
spec.metadata["homepage_uri"] = spec.homepage spec.metadata['homepage_uri'] = spec.homepage
spec.metadata["source_code_uri"] = "https://github.com/francistm/dingtalk-sdk" spec.metadata['source_code_uri'] = 'https://github.com/francistm/dingtalk-sdk'
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
else else
raise "RubyGems 2.0 or newer is required to protect against " \ raise 'RubyGems 2.0 or newer is required to protect against ' \
"public gem pushes." 'public gem pushes.'
end end
# Specify which files should be added to the gem when it is released. # Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git. # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end end
spec.bindir = "exe" spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"] spec.require_paths = ['lib']
spec.required_ruby_version = '> 2.4'
spec.add_runtime_dependency "httparty", "~> 0.18"
spec.add_runtime_dependency "activesupport", "~> 6.0" spec.add_runtime_dependency 'activesupport', '~> 6.0'
spec.add_runtime_dependency 'httparty', '~> 0.18'
spec.add_development_dependency "pry", "~> 0.13"
spec.add_development_dependency "webmock", "~> 3.8" spec.add_development_dependency 'bundler', '~> 2.1.0'
spec.add_development_dependency "bundler", "~> 2.1.0" spec.add_development_dependency 'pry', '~> 0.13'
spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency "rspec", "~> 3.0" spec.add_development_dependency 'rspec', '~> 3.0'
spec.add_development_dependency 'rubocop', '~> 0.80'
spec.add_development_dependency 'webmock', '~> 3.8'
end end
# frozen_string_literal: true
require 'uri' require 'uri'
require 'base64' require 'base64'
require 'openssl' require 'openssl'
require "dingtalk_sdk/version" require 'dingtalk_sdk/version'
require "dingtalk_sdk/auth" require 'dingtalk_sdk/auth'
require "dingtalk_sdk/user" require 'dingtalk_sdk/user'
require "dingtalk_sdk/department" require 'dingtalk_sdk/department'
require "dingtalk_sdk/access_token" require 'dingtalk_sdk/access_token'
require "dingtalk_sdk/corp_conversation" require 'dingtalk_sdk/corp_conversation'
module DingtalkSdk module DingtalkSdk
class Error < StandardError; end class Error < StandardError; end
...@@ -16,7 +18,8 @@ module DingtalkSdk ...@@ -16,7 +18,8 @@ module DingtalkSdk
attr_reader :code, :message attr_reader :code, :message
def initialize(code:, message:) def initialize(code:, message:)
@code, @message, = code, message @code = code
@message = message
end end
end end
...@@ -44,7 +47,9 @@ module DingtalkSdk ...@@ -44,7 +47,9 @@ module DingtalkSdk
attr_reader :agent_id, :app_key, :app_secret attr_reader :agent_id, :app_key, :app_secret
def initialize(agent_id:, app_key:, app_secret:) def initialize(agent_id:, app_key:, app_secret:)
@agent_id, @app_key, @app_secret = agent_id, app_key, app_secret @agent_id = agent_id
@app_key = app_key
@app_secret = app_secret
end end
end end
...@@ -56,18 +61,18 @@ module DingtalkSdk ...@@ -56,18 +61,18 @@ module DingtalkSdk
def login_free_signature(app_secret, options = {}) def login_free_signature(app_secret, options = {})
default_options = { default_options = {
timestamp: nil, timestamp: nil,
url_encode: true, url_encode: true
} }
options = default_options.merge(options) options = default_options.merge(options)
timestamp = unless options[:timestamp].nil? timestamp = if options[:timestamp].nil?
options[:timestamp] (Time.now.localtime('+08:00').to_f * 1000).to_i
else else
(Time.now.localtime("+08:00").to_f * 1000).to_i options[:timestamp]
end end
signature_str = OpenSSL::HMAC.digest("SHA256", app_secret, timestamp.to_s) signature_str = OpenSSL::HMAC.digest('SHA256', app_secret, timestamp.to_s)
signature_str_base64 = Base64.encode64(signature_str).strip signature_str_base64 = Base64.encode64(signature_str).strip
Signature.new(signature_str_base64) Signature.new(signature_str_base64)
......
require "dingtalk_sdk/core" # frozen_string_literal: true
require "dingtalk_sdk/request_url"
require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url'
module DingtalkSdk module DingtalkSdk
module AccessToken module AccessToken
......
require "dingtalk_sdk/core" # frozen_string_literal: true
require "dingtalk_sdk/request_url"
require "active_support/core_ext/object/to_query" require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url'
require 'active_support/core_ext/object/to_query'
module DingtalkSdk module DingtalkSdk
module Auth module Auth
...@@ -17,11 +19,11 @@ module DingtalkSdk ...@@ -17,11 +19,11 @@ module DingtalkSdk
# 生成扫码登录跳转地址 # 生成扫码登录跳转地址
# {https://ding-doc.dingtalk.com/doc#/serverapi2/kymkv6} # {https://ding-doc.dingtalk.com/doc#/serverapi2/kymkv6}
def get_qr_connect_uri(redirect_uri, state = "") def get_qr_connect_uri(redirect_uri, state = '')
qs = {}.tap do |h| qs = {}.tap do |h|
h[:appid] = @app_key h[:appid] = @app_key
h[:response_type] = "code" h[:response_type] = 'code'
h[:scope] = "snsapi_login" h[:scope] = 'snsapi_login'
h[:state] = state h[:state] = state
h[:redirect_uri] = redirect_uri h[:redirect_uri] = redirect_uri
end end
......
require "json" # frozen_string_literal: true
require "httparty"
require "active_support"
require "active_support/core_ext/hash/keys"
require "active_support/core_ext/hash/deep_merge"
require "dingtalk_sdk" require 'json'
require 'httparty'
require 'active_support'
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/deep_merge'
require 'dingtalk_sdk'
module DingtalkSdk module DingtalkSdk
module Core module Core
...@@ -22,41 +24,39 @@ module DingtalkSdk ...@@ -22,41 +24,39 @@ module DingtalkSdk
@query_const = {} @query_const = {}
end end
def is_json? def json?
@format == :json @format == :json
end end
def is_x_form? def x_form?
@format == :x_form @format == :x_form
end end
def is_form_data? def form_data?
@format == :form_data @format == :form_data
end end
def is_arg_required?(arg_name) def arg_required?(arg_name)
@required_args.include? arg_name @required_args.include? arg_name
end end
def has_body? def body?
!@body_args.empty? || !@body_const.empty? !@body_args.empty? || !@body_const.empty?
end end
def has_query? def query?
!@query_args.empty? || !@query_const.empty? !@query_args.empty? || !@query_const.empty?
end end
def has_body_const? def body_const?
!@body_const.empty? !@body_const.empty?
end end
def has_query_const? def query_const?
!@query_const.empty? !@query_const.empty?
end end
def format=(format) attr_writer :format
@format = format
end
def add_arg(arg_name, option) def add_arg(arg_name, option)
case option[:in] case option[:in]
...@@ -65,14 +65,14 @@ module DingtalkSdk ...@@ -65,14 +65,14 @@ module DingtalkSdk
when :query when :query
@query_args << arg_name @query_args << arg_name
else else
raise DingtalkSdk::Error.new("unknown argument '#{arg_name}' position") raise DingtalkSdk::Error, "unknown argument '#{arg_name}' position"
end end
@required_args << arg_name if option[:required] @required_args << arg_name if option[:required]
end end
def add_const(arg_name, value, option) def add_const(arg_name, value, option)
const_hash = {arg_name => value} const_hash = { arg_name => value }
case option[:in] case option[:in]
when :body when :body
...@@ -80,7 +80,7 @@ module DingtalkSdk ...@@ -80,7 +80,7 @@ module DingtalkSdk
when :query when :query
@query_const.merge! const_hash @query_const.merge! const_hash
else else
raise DingtalkSdk::Error.new("unknown argument '#{arg_name}' position") raise DingtalkSdk::Error, "unknown argument '#{arg_name}' position"
end end
end end
end end
...@@ -92,33 +92,34 @@ module DingtalkSdk ...@@ -92,33 +92,34 @@ module DingtalkSdk
define_method request_name do |method_args = {}| define_method request_name do |method_args = {}|
request_options = {}.tap do |h| request_options = {}.tap do |h|
builder.required_args.each do |arg| builder.required_args.each do |arg|
raise DingtalkSdk::Error.new("missing required argument '#{arg}' when invoke request #{request_name}") \ raise DingtalkSdk::Error, "missing required argument '#{arg}' when invoke request #{request_name}" \
if method_args[arg].nil? if method_args[arg].nil?
end end
[:body, :query].each do |arg_pos| %i[body query].each do |arg_pos|
h[arg_pos] = {} if builder.send(:"has_#{arg_pos}?") h[arg_pos] = {} if builder.send(:"#{arg_pos}?")
builder.send(:"#{arg_pos}_args").each do |arg_name| builder.send(:"#{arg_pos}_args").each do |arg_name|
arg_value = method_args[arg_name] arg_value = method_args[arg_name]
next if arg_pos == :query && arg_value.nil? next if arg_pos == :query && arg_value.nil?
h[arg_pos][arg_name] = arg_value h[arg_pos][arg_name] = arg_value
end end
builder.send(:"#{arg_pos}_const").each do |arg_name, arg_value| builder.send(:"#{arg_pos}_const").each do |arg_name, arg_value|
if arg_value.respond_to?(:call) h[arg_pos][arg_name] = if arg_value.respond_to?(:call)
h[arg_pos][arg_name] = arg_value.call(self) arg_value.call(self)
else else
h[arg_pos][arg_name] = arg_value arg_value
end end
end end
end end
if builder.is_form_data? if builder.form_data?
h[:multipart] = true h[:multipart] = true
elsif builder.is_json? elsif builder.json?
h[:body] = h[:body].to_json if Hash === h[:body] h[:body] = h[:body].to_json if h[:body].is_a?(Hash)
h[:headers] = {:"Content-Type" => "application/json"} h[:headers] = { "Content-Type": 'application/json' }
end end
end end
...@@ -128,7 +129,7 @@ module DingtalkSdk ...@@ -128,7 +129,7 @@ module DingtalkSdk
if symbolized_response[:errcode] != 0 if symbolized_response[:errcode] != 0
raise DingtalkSdk::RequestFailedError.new( raise DingtalkSdk::RequestFailedError.new(
code: symbolized_response[:errcode], code: symbolized_response[:errcode],
message: symbolized_response[:errmsg], message: symbolized_response[:errmsg]
) )
end end
......
# frozen_string_literal: true
require 'dingtalk_sdk/core' require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url' require 'dingtalk_sdk/request_url'
......
require "dingtalk_sdk/core" # frozen_string_literal: true
require "dingtalk_sdk/request_url"
require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url'
module DingtalkSdk module DingtalkSdk
module Department module Department
......
...@@ -3,58 +3,58 @@ ...@@ -3,58 +3,58 @@
module DingtalkSdk module DingtalkSdk
module RequestUrl module RequestUrl
# 获取 AccessToken # 获取 AccessToken
ACCESS_TOKEN = "https://oapi.dingtalk.com/gettoken" ACCESS_TOKEN = 'https://oapi.dingtalk.com/gettoken'
# 扫码登录第三方网站 OAuth 跳转地址 # 扫码登录第三方网站 OAuth 跳转地址
# {https://ding-doc.dingtalk.com/doc#/serverapi2/kymkv6} # {https://ding-doc.dingtalk.com/doc#/serverapi2/kymkv6}
CONNECT_QR_REDIRECT = "https://oapi.dingtalk.com/connect/qrconnect" CONNECT_QR_REDIRECT = 'https://oapi.dingtalk.com/connect/qrconnect'
# 企业内应用免登录获取用户ID # 企业内应用免登录获取用户ID
# {https://ding-doc.dingtalk.com/doc#/serverapi2/clotub} # {https://ding-doc.dingtalk.com/doc#/serverapi2/clotub}
INT_LOGIN_FREE_GET_USER_INFO = "https://oapi.dingtalk.com/user/getuserinfo" INT_LOGIN_FREE_GET_USER_INFO = 'https://oapi.dingtalk.com/user/getuserinfo'
# 服务端通过临时授权码获取授权用户的个人信息 # 服务端通过临时授权码获取授权用户的个人信息
# {https://ding-doc.dingtalk.com/doc#/serverapi2/etaarr} # {https://ding-doc.dingtalk.com/doc#/serverapi2/etaarr}
GET_USER_INFO_SNS = "https://oapi.dingtalk.com/sns/getuserinfo_bycode" GET_USER_INFO_SNS = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode'
# 获取用户详情 # 获取用户详情
# {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/AaRQe} # {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/AaRQe}
GET_USER_PROFILE = "https://oapi.dingtalk.com/user/get" GET_USER_PROFILE = 'https://oapi.dingtalk.com/user/get'
# 通过 unionId 获取 userId # 通过 unionId 获取 userId
# {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/602f4b15} # {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/602f4b15}
GET_USERID_FROM_UNIONID = "https://oapi.dingtalk.com/user/getUseridByUnionid" GET_USERID_FROM_UNIONID = 'https://oapi.dingtalk.com/user/getUseridByUnionid'
# 根据手机号获取 userId # 根据手机号获取 userId
# {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/soV11} # {https://ding-doc.dingtalk.com/doc#/serverapi2/ege851/soV11}
GET_USERID_FROM_MOBILE = "https://oapi.dingtalk.com/user/get_by_mobile" GET_USERID_FROM_MOBILE = 'https://oapi.dingtalk.com/user/get_by_mobile'
# 获取部门列表 # 获取部门列表
# {https://ding-doc.dingtalk.com/doc#/serverapi2/dubakq/e6e1604e} # {https://ding-doc.dingtalk.com/doc#/serverapi2/dubakq/e6e1604e}
GET_DEPARTMENT_LIST = "https://oapi.dingtalk.com/department/list" GET_DEPARTMENT_LIST = 'https://oapi.dingtalk.com/department/list'
# 获取部门详情 # 获取部门详情
# {https://ding-doc.dingtalk.com/doc#/serverapi2/dubakq/5bf960de} # {https://ding-doc.dingtalk.com/doc#/serverapi2/dubakq/5bf960de}
GET_DEPARTMENT_PROFILE = "https://oapi.dingtalk.com/department/get" GET_DEPARTMENT_PROFILE = 'https://oapi.dingtalk.com/department/get'
# 发送工作通知消息 # 发送工作通知消息
# {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy} # {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy}
SEND_CORP_CONVERSATION = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2" SEND_CORP_CONVERSATION = 'https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2'
# 查询工作通知消息的发送进度 # 查询工作通知消息的发送进度
# {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/e2262dad} # {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/e2262dad}
CORP_CONVERSATION_SEND_PROGRESS = "https://oapi.dingtalk.com/topapi/message/corpconversation/getsendprogress" CORP_CONVERSATION_SEND_PROGRESS = 'https://oapi.dingtalk.com/topapi/message/corpconversation/getsendprogress'
# 查询工作通知消息的发送结果 # 查询工作通知消息的发送结果
# {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/a5920210} # {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/a5920210}
CORP_CONVERSATION_SEND_RESULT = "https://oapi.dingtalk.com/topapi/message/corpconversation/getsendresult" CORP_CONVERSATION_SEND_RESULT = 'https://oapi.dingtalk.com/topapi/message/corpconversation/getsendresult'
# 工作通知消息撤回 # 工作通知消息撤回
# {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/hYyV8} # {https://ding-doc.dingtalk.com/doc#/serverapi2/pgoxpy/hYyV8}
RECALL_CORP_CONVERSATION = "https://oapi.dingtalk.com/topapi/message/corpconversation/recall" RECALL_CORP_CONVERSATION = 'https://oapi.dingtalk.com/topapi/message/corpconversation/recall'
# 上传媒体文件 # 上传媒体文件
# {https://ding-doc.dingtalk.com/doc#/serverapi2/bcmg0i/08d5a73b} # {https://ding-doc.dingtalk.com/doc#/serverapi2/bcmg0i/08d5a73b}
UPLOAD_MEDIA_FILE = "https://oapi.dingtalk.com/media/upload" UPLOAD_MEDIA_FILE = 'https://oapi.dingtalk.com/media/upload'
end end
end end
# frozen_string_literal: true
require 'dingtalk_sdk/core' require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url' require 'dingtalk_sdk/request_url'
......
require "dingtalk_sdk/core" # frozen_string_literal: true
require "dingtalk_sdk/request_url"
require 'dingtalk_sdk/core'
require 'dingtalk_sdk/request_url'
module DingtalkSdk module DingtalkSdk
module User module User
......
# frozen_string_literal: true
module DingtalkSdk module DingtalkSdk
VERSION = "0.1.0" VERSION = '0.1.0'
end end
require "json" # frozen_string_literal: true
require "dingtalk_sdk"
require "dingtalk_sdk/access_token" require 'json'
require 'dingtalk_sdk'
require 'dingtalk_sdk/access_token'
RSpec.describe DingtalkSdk::AccessToken do RSpec.describe DingtalkSdk::AccessToken do
before :each do before :each do
@agent_id = "mocked_agent_id" @agent_id = 'mocked_agent_id'
@app_key = "mocked_app_key" @app_key = 'mocked_app_key'
@app_secret = "mocked_app_secret" @app_secret = 'mocked_app_secret'
@mocked_access_token = "mocked_access_token" @mocked_access_token = 'mocked_access_token'
@dingtalk_request = DingtalkSdk::Request.new( @dingtalk_request = DingtalkSdk::Request.new(
agent_id: @agent_id, agent_id: @agent_id,
app_key: @app_key, app_key: @app_key,
app_secret: @app_secret, app_secret: @app_secret
) )
response_body = {}.tap do |h| response_body = {}.tap do |h|
...@@ -23,10 +25,10 @@ RSpec.describe DingtalkSdk::AccessToken do ...@@ -23,10 +25,10 @@ RSpec.describe DingtalkSdk::AccessToken do
stub_request(:get, /oapi.dingtalk.com/) stub_request(:get, /oapi.dingtalk.com/)
.with(query: { appkey: @app_key, appsecret: @app_secret }) .with(query: { appkey: @app_key, appsecret: @app_secret })
.to_return(status: 200, body: response_body.to_json ) .to_return(status: 200, body: response_body.to_json)
end end
it "should return correct access_token from request" do it 'should return correct access_token from request' do
response = @dingtalk_request.get_access_token response = @dingtalk_request.get_access_token
expect(response[:access_token]).to eq(@mocked_access_token) expect(response[:access_token]).to eq(@mocked_access_token)
......
require "cgi" # frozen_string_literal: true
require "uri"
require "json"
require "securerandom"
require "dingtalk_sdk" require 'cgi'
require "dingtalk_sdk/auth" require 'uri'
require 'json'
require 'securerandom'
require 'dingtalk_sdk'
require 'dingtalk_sdk/auth'
RSpec.describe DingtalkSdk::Auth do RSpec.describe DingtalkSdk::Auth do
before :each do before :each do
@agent_id = "mocked_agent_id" @agent_id = 'mocked_agent_id'
@app_key = "mocked_app_key" @app_key = 'mocked_app_key'
@app_secret = "mocked_app_secret" @app_secret = 'mocked_app_secret'
@int_user_id = 100 @int_user_id = 100
@access_token = "mocked_access_token" @access_token = 'mocked_access_token'
@int_login_code = "mocked_int_login_code" @int_login_code = 'mocked_int_login_code'
@timestamp = (Time.now.localtime("+08:00").to_f * 1000).to_i @timestamp = (Time.now.localtime('+08:00').to_f * 1000).to_i
@signature = DingtalkSdk.login_free_signature(@app_secret, timestamp: @timestamp) @signature = DingtalkSdk.login_free_signature(@app_secret, timestamp: @timestamp)
@dingtalk_request = DingtalkSdk::Request.new( @dingtalk_request = DingtalkSdk::Request.new(
agent_id: @agent_id, agent_id: @agent_id,
app_key: @app_key, app_key: @app_key,
app_secret: @app_secret, app_secret: @app_secret
) )
# 企业内部免登 响应结果 # 企业内部免登 响应结果
get_user_info_response_body = {}.tap do |h| get_user_info_response_body = {}.tap do |h|
h[:errcode] = 0 h[:errcode] = 0
h[:errmsg] = "ok" h[:errmsg] = 'ok'
h[:userid] = @int_user_id h[:userid] = @int_user_id
h[:is_sys] = false h[:is_sys] = false
h[:sys_level] = 0 h[:sys_level] = 0
...@@ -37,31 +39,32 @@ RSpec.describe DingtalkSdk::Auth do ...@@ -37,31 +39,32 @@ RSpec.describe DingtalkSdk::Auth do
# 钉钉内免登第三方网站 响应结果 # 钉钉内免登第三方网站 响应结果
get_user_info_by_code_response_body = {}.tap do |h| get_user_info_by_code_response_body = {}.tap do |h|
h[:errcode] = 0 h[:errcode] = 0
h[:errmsg] = "ok" h[:errmsg] = 'ok'
h[:user_info] = { h[:user_info] = {
nick: "张三", nick: '张三',
openid: "liSii8KCxxxxx", openid: 'liSii8KCxxxxx',
unionid: "7Huu46kk" unionid: '7Huu46kk'
} }
end end
stub_request(:get, /oapi.dingtalk.com\/user\/getuserinfo/) stub_request(:get, %r{oapi.dingtalk.com/user/getuserinfo})
.with( .with(
query: { query: {
code: @int_login_code, code: @int_login_code,
access_token: @access_token, access_token: @access_token
}) }
)
.to_return(status: 200, body: get_user_info_response_body.to_json) .to_return(status: 200, body: get_user_info_response_body.to_json)
stub_request(:post, /oapi.dingtalk.com\/sns\/getuserinfo_bycode/) stub_request(:post, %r{oapi.dingtalk.com/sns/getuserinfo_bycode})
.with( .with(
query: { query: {
accessKey: @app_key, accessKey: @app_key,
timestamp: @timestamp.to_s, timestamp: @timestamp.to_s,
signature: @signature.to_s, signature: @signature.to_s
}, },
body: { tmp_auth_code: "23152698ea18304da4d0ce1xxxxx" }.to_json, body: { tmp_auth_code: '23152698ea18304da4d0ce1xxxxx' }.to_json,
headers: { :"Content-Type" => "application/json" } headers: { "Content-Type": 'application/json' }
) )
.to_return(status: 200, body: get_user_info_by_code_response_body.to_json) .to_return(status: 200, body: get_user_info_by_code_response_body.to_json)
end end
...@@ -69,7 +72,7 @@ RSpec.describe DingtalkSdk::Auth do ...@@ -69,7 +72,7 @@ RSpec.describe DingtalkSdk::Auth do
it 'should get user id in internal app login-free scenario' do it 'should get user id in internal app login-free scenario' do
response = @dingtalk_request.get_int_login_free_user_id( response = @dingtalk_request.get_int_login_free_user_id(
code: @int_login_code, code: @int_login_code,
access_token: @access_token, access_token: @access_token
) )
expect(response[:userid]).to eq(@int_user_id) expect(response[:userid]).to eq(@int_user_id)
...@@ -83,25 +86,25 @@ RSpec.describe DingtalkSdk::Auth do ...@@ -83,25 +86,25 @@ RSpec.describe DingtalkSdk::Auth do
accessKey: @app_key, accessKey: @app_key,
timestamp: @timestamp, timestamp: @timestamp,
signature: @signature.to_s, signature: @signature.to_s,
tmp_auth_code: "23152698ea18304da4d0ce1xxxxx" tmp_auth_code: '23152698ea18304da4d0ce1xxxxx'
) )
expect(response[:user_info]).to be_a(Hash) expect(response[:user_info]).to be_a(Hash)
expect(response[:user_info][:nick]).to eq("张三") expect(response[:user_info][:nick]).to eq('张三')
expect(response[:user_info][:openid]).to eq("liSii8KCxxxxx") expect(response[:user_info][:openid]).to eq('liSii8KCxxxxx')
expect(response[:user_info][:unionid]).to eq("7Huu46kk") expect(response[:user_info][:unionid]).to eq('7Huu46kk')
end end
it 'should create connect qr scan page url in dingtalk.com' do it 'should create connect qr scan page url in dingtalk.com' do
state = SecureRandom.hex(6) state = SecureRandom.hex(6)
redirect_uri = "http://example.org/callback" redirect_uri = 'http://example.org/callback'
qr_connect_uri = @dingtalk_request.get_qr_connect_uri(redirect_uri, state) qr_connect_uri = @dingtalk_request.get_qr_connect_uri(redirect_uri, state)
uri = URI(qr_connect_uri) uri = URI(qr_connect_uri)
query = CGI::parse(uri.query) query = CGI.parse(uri.query)
expect(query["appid"].first).to eq(@app_key) expect(query['appid'].first).to eq(@app_key)
expect(query["state"].first).to eq(state) expect(query['state'].first).to eq(state)
expect(query["redirect_uri"].first).to eq(redirect_uri) expect(query['redirect_uri'].first).to eq(redirect_uri)
end end
end end
# frozen_string_literal: true
RSpec.describe DingtalkSdk do RSpec.describe DingtalkSdk do
it "has a version number" do it 'has a version number' do
expect(DingtalkSdk::VERSION).not_to be nil expect(DingtalkSdk::VERSION).not_to be nil
end end
# 测试样本见 https://ding-doc.dingtalk.com/doc#/faquestions/hxs5v9 底部 # 测试样本见 https://ding-doc.dingtalk.com/doc#/faquestions/hxs5v9 底部
it "sign correct timestamp with app_secret in personal login-free scenario" do it 'sign correct timestamp with app_secret in personal login-free scenario' do
timestamp = 1546084445901 timestamp = 1_546_084_445_901
app_secret = "testappSecret" app_secret = 'testappSecret'
signature = DingtalkSdk.login_free_signature(app_secret, timestamp: timestamp) signature = DingtalkSdk.login_free_signature(app_secret, timestamp: timestamp)
expect(signature).to be_a(DingtalkSdk::Signature) expect(signature).to be_a(DingtalkSdk::Signature)
expect(signature.url_encoded).to eq("HCbG3xNE3vzhO%2Bu7qCUL1jS5hsu2n5r2cFhnTrtyDAE%3D") expect(signature.url_encoded).to eq('HCbG3xNE3vzhO%2Bu7qCUL1jS5hsu2n5r2cFhnTrtyDAE%3D')
end end
end end
require "pry" # frozen_string_literal: true
require "bundler/setup"
require "webmock/rspec" require 'pry'
require "dingtalk_sdk" require 'bundler/setup'
require 'webmock/rspec'
require 'dingtalk_sdk'
RSpec.configure do |config| RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure # Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status" config.example_status_persistence_file_path = '.rspec_status'
# Disable RSpec exposing methods globally on `Module` and `main` # Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching! config.disable_monkey_patching!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment