rfetion 0.5.4 → 0.5.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.
- data/README.textile +2 -0
- data/VERSION +1 -1
- data/lib/rfetion.rb +1 -0
- data/lib/rfetion/buddy_list.rb +17 -4
- data/lib/rfetion/contact.rb +37 -10
- data/lib/rfetion/fetion.rb +87 -22
- data/lib/rfetion/pic_certificate.rb +12 -0
- data/lib/rfetion/sipc_message.rb +6 -1
- data/rfetion.gemspec +7 -4
- data/spec/rfetion/buddy_list_spec.rb +22 -0
- data/spec/rfetion/fetion_spec.rb +147 -12
- data/spec/rfetion/sipc_message_spec.rb +37 -2
- metadata +29 -13
data/README.textile
CHANGED
@@ -2,6 +2,8 @@ h1. rfetion
|
|
2
2
|
|
3
3
|
rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
4
4
|
|
5
|
+
I'm still developing according to the Fetion 2010 version which adds the verification code to protect bot. You should download the version before 0.5.0 which does not trigger the verification.
|
6
|
+
|
5
7
|
**************************************************************************
|
6
8
|
|
7
9
|
h2. Demo
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.5
|
data/lib/rfetion.rb
CHANGED
@@ -2,5 +2,6 @@ require 'rubygems'
|
|
2
2
|
require File.dirname(__FILE__) + '/rfetion/buddy_list'
|
3
3
|
require File.dirname(__FILE__) + '/rfetion/contact'
|
4
4
|
require File.dirname(__FILE__) + '/rfetion/message'
|
5
|
+
require File.dirname(__FILE__) + '/rfetion/pic_certificate'
|
5
6
|
require File.dirname(__FILE__) + '/rfetion/sipc_message'
|
6
7
|
require File.dirname(__FILE__) + '/rfetion/fetion'
|
data/lib/rfetion/buddy_list.rb
CHANGED
@@ -1,14 +1,27 @@
|
|
1
1
|
class Fetion
|
2
2
|
class BuddyList
|
3
|
-
|
3
|
+
attr_reader :bid, :name, :contacts
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(bid, name)
|
6
|
+
@bid = bid
|
7
7
|
@name = name
|
8
|
+
@contacts = []
|
8
9
|
end
|
9
10
|
|
10
11
|
def self.parse(buddy_list)
|
11
12
|
self.new(buddy_list['id'], buddy_list['name'])
|
12
13
|
end
|
14
|
+
|
15
|
+
def add_contact(contact)
|
16
|
+
@contacts << contact
|
17
|
+
end
|
18
|
+
|
19
|
+
def online_contacts_count
|
20
|
+
@contacts.select {|contact| contact.status == "400"}.size
|
21
|
+
end
|
22
|
+
|
23
|
+
def total_contacts_count
|
24
|
+
@contacts.size
|
25
|
+
end
|
13
26
|
end
|
14
|
-
end
|
27
|
+
end
|
data/lib/rfetion/contact.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#coding: utf-8
|
2
2
|
class Fetion
|
3
3
|
class Contact
|
4
|
-
attr_accessor :
|
4
|
+
attr_accessor :uid, :sid, :bid, :uri, :mobile_no, :nickname, :impresa, :status
|
5
5
|
|
6
6
|
STATUS = {
|
7
7
|
"400" => "在线",
|
@@ -10,17 +10,44 @@ class Fetion
|
|
10
10
|
"0" => "脱机"
|
11
11
|
}
|
12
12
|
|
13
|
+
def self.parse_buddy(b)
|
14
|
+
self.new(:uid => b['i'], :uri => b['u'], :nickname => b['n'], :bid => b['l'].empty? ? "0" : b['l'])
|
15
|
+
end
|
16
|
+
|
13
17
|
def self.parse(c)
|
14
|
-
contact = self.new
|
15
|
-
contact.id = c['id']
|
16
18
|
p = c.children.first
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
self.new(:uid => c['id'], :sid => p['sid'], :uri => p['su'], :mobile_no => p['m'], :nickname => p['n'], :impresa => p['i'], :status => p['b'], :bid => p['l'])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse_request(c)
|
23
|
+
self.new(:uri => c['uri'], :uid => c['user-id'], :sid => c['sid'], :mobile_no => c['mobile-no'], :nickname => c['nickname'])
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(options={})
|
27
|
+
options.each do |key, value|
|
28
|
+
send("#{key}=", value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(p)
|
33
|
+
self.sid = p["sid"] if p["sid"] and !p["sid"].empty?
|
34
|
+
self.uri = p["su"] if p["su"] and !p["su"].empty?
|
35
|
+
self.mobile_no = p["m"] if p["m"] and !p["m"].empty?
|
36
|
+
self.nickname = p["n"] if p["n"] and !p["n"].empty?
|
37
|
+
self.impresa = p["i"] if p["i"] and !p["i"].empty?
|
38
|
+
self.status = p["b"] if p["b"] and !p["b"].empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def display
|
42
|
+
if self.impresa and !self.impresa.empty?
|
43
|
+
"#{self.nickname}(#{self.impresa})"
|
44
|
+
elsif self.nickname and !self.nickname.empty?
|
45
|
+
self.nickname
|
46
|
+
else
|
47
|
+
if self.uri =~ /^(tel|sip):(\d+)/
|
48
|
+
$2
|
49
|
+
end
|
50
|
+
end
|
24
51
|
end
|
25
52
|
end
|
26
53
|
end
|
data/lib/rfetion/fetion.rb
CHANGED
@@ -9,10 +9,11 @@ require 'logger'
|
|
9
9
|
|
10
10
|
class Fetion
|
11
11
|
attr_accessor :mobile_no, :sid, :password, :call, :seq, :alive, :ssic, :guid, :uri
|
12
|
-
attr_reader :
|
12
|
+
attr_reader :uid, :buddy_lists, :add_requests, :response, :nickname, :impresa, :receives
|
13
13
|
|
14
14
|
FETION_URL = 'http://221.176.31.39/ht/sd.aspx'
|
15
15
|
FETION_LOGIN_URL = 'https://uid.fetion.com.cn/ssiportal/SSIAppSignInV4.aspx?mobileno=%mobileno%sid=%sid%&domains=fetion.com.cn;m161.com.cn;www.ikuwa.cn&v4digest-type=1&v4digest=%digest%'
|
16
|
+
FETION_PIC_URL = 'http://nav.fetion.com.cn/nav/GetPicCodeV4.aspx?algorithm=%algorithm'
|
16
17
|
|
17
18
|
SIPP = 'SIPP'
|
18
19
|
USER_AGENT = "IIC2.0/PC 3.6.2020"
|
@@ -21,10 +22,10 @@ class Fetion
|
|
21
22
|
|
22
23
|
def initialize
|
23
24
|
@call = @alive = @seq = 0
|
24
|
-
@buddy_lists = []
|
25
|
-
@buddies = []
|
25
|
+
@buddy_lists = [Fetion::BuddyList.new("0", "未分组")]
|
26
26
|
@contacts = []
|
27
27
|
@receives = []
|
28
|
+
@add_requests = []
|
28
29
|
@logger = Logger.new(STDOUT)
|
29
30
|
@logger.level = Logger::INFO
|
30
31
|
@guid = Guid.new.to_s
|
@@ -198,7 +199,7 @@ class Fetion
|
|
198
199
|
def register_second
|
199
200
|
@logger.debug "fetion register second"
|
200
201
|
|
201
|
-
body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{@mobile_no}" user-id="#{@
|
202
|
+
body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{@mobile_no}" user-id="#{@uid}"><personal version="0" attributes="v4default" /><custom-config version="0" /><contact-list version="0" buddy-attributes="v4default" /></user-info><credentials domains="fetion.com.cn;m161.com.cn;www.ikuwa.cn;games.fetion.com.cn" /><presence><basic value="400" desc="" /></presence></args>|
|
202
203
|
curl_exec(SipcMessage.register_second(self))
|
203
204
|
pulse
|
204
205
|
|
@@ -267,19 +268,30 @@ class Fetion
|
|
267
268
|
# mobile_no
|
268
269
|
# sip
|
269
270
|
def get_contact_info(options)
|
270
|
-
uri =
|
271
|
+
uri = if options[:mobile_no]
|
272
|
+
"tel:#{options[:mobile_no]}"
|
273
|
+
elsif options[:sip]
|
274
|
+
"sip:#{options[:sip]}"
|
275
|
+
else
|
276
|
+
"uri:#{options[:uri]}"
|
277
|
+
end
|
271
278
|
@logger.info "fetion get contact info of #{uri}"
|
272
279
|
|
273
280
|
curl_exec(SipcMessage.get_contact_info(self, uri))
|
274
|
-
pulse
|
281
|
+
sipc_response = pulse
|
282
|
+
results = sipc_response.sections.first.scan(%r{<results>.*?</results>}).first
|
283
|
+
doc = Nokogiri::XML(results)
|
284
|
+
c = doc.root.xpath("/results/contact").first
|
285
|
+
contact = Contact.parse_request(c)
|
275
286
|
|
276
287
|
@logger.info "fetion get contact info of #{uri} success"
|
288
|
+
contact
|
277
289
|
end
|
278
290
|
|
279
291
|
def keep_alive
|
280
292
|
@logger.info "fetion keep alive"
|
281
293
|
|
282
|
-
|
294
|
+
curl_exec(SipcMessage.keep_alive(self))
|
283
295
|
|
284
296
|
@logger.info "fetion keep alive success"
|
285
297
|
end
|
@@ -287,9 +299,10 @@ class Fetion
|
|
287
299
|
def pulse(expected=SipcMessage::OK)
|
288
300
|
@logger.info "fetion pulse"
|
289
301
|
|
290
|
-
curl_exec(SIPP, next_url, expected)
|
302
|
+
sipc_response = curl_exec(SIPP, next_url, expected)
|
291
303
|
|
292
304
|
@logger.info "fetion pulse success"
|
305
|
+
sipc_response
|
293
306
|
end
|
294
307
|
|
295
308
|
def logout
|
@@ -327,14 +340,39 @@ class Fetion
|
|
327
340
|
end
|
328
341
|
|
329
342
|
def close_session
|
330
|
-
@logger.info "fetion
|
343
|
+
@logger.info "fetion close session"
|
331
344
|
|
332
345
|
curl_exec(SipcMessage.close_session(self))
|
333
346
|
|
334
|
-
@logger.info "fetion
|
347
|
+
@logger.info "fetion close session success"
|
348
|
+
end
|
349
|
+
|
350
|
+
def handle_contact_request(uid, options)
|
351
|
+
@logger.info "fetion handle contact request"
|
352
|
+
|
353
|
+
contact = @add_requests.find {|contact| contact.uid == uid}
|
354
|
+
curl_exec(SipcMessage.handle_contact_request(self, contact, options))
|
355
|
+
pulse
|
356
|
+
|
357
|
+
@logger.info "fetion handle contact request success"
|
358
|
+
end
|
359
|
+
|
360
|
+
def get_pic_certificate(algorithm)
|
361
|
+
@logger.info "fetion get pic"
|
362
|
+
|
363
|
+
uri = URI.parse(FETION_PIC_URL.sub('%algorithm', algorithm))
|
364
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
365
|
+
headers = {'User-Agent' => USER_AGENT}
|
366
|
+
response = http.request_get(uri.request_uri, headers)
|
367
|
+
pic_certificate = parse_pic_certificate(response)
|
368
|
+
|
369
|
+
@logger.info "fetion get pic success"
|
370
|
+
pic_certificate
|
335
371
|
end
|
336
372
|
|
337
373
|
def parse_ssic(response)
|
374
|
+
raise Fetion::PasswordError.new('Fetion Error: 帐号或密码不正确') if Net::HTTPUnauthorized === response
|
375
|
+
raise Fetion::PasswordMaxError.new('Fetion Error: 您已连续输入错误密码,为了保障您的帐户安全,请输入图形验证码:') if Net::HTTPClientError === response
|
338
376
|
raise Fetion::LoginException.new('Fetion Error: Login failed.') unless Net::HTTPSuccess === response
|
339
377
|
raise Fetion::LoginException.new('Fetion Error: No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
|
340
378
|
|
@@ -347,7 +385,7 @@ class Fetion
|
|
347
385
|
@user_status = user['user-status']
|
348
386
|
@uri = user['uri']
|
349
387
|
@mobile_no = user['mobile-no']
|
350
|
-
@
|
388
|
+
@uid = user['user-id']
|
351
389
|
if @uri =~ /sip:(\d+)@(.+);/
|
352
390
|
@sid = $1
|
353
391
|
end
|
@@ -357,10 +395,17 @@ class Fetion
|
|
357
395
|
@logger.debug "user_status: " + @user_status
|
358
396
|
@logger.debug "uri: " + @uri
|
359
397
|
@logger.debug "mobile_no: " + @mobile_no
|
360
|
-
@logger.debug "
|
398
|
+
@logger.debug "uid: " + @uid
|
361
399
|
@logger.debug "sid: " + @sid
|
362
400
|
end
|
363
401
|
|
402
|
+
def parse_pic_certificate(response)
|
403
|
+
raise FetionException.new('Fetion Error: Get verification code failed.') unless Net::HTTPSuccess === response
|
404
|
+
doc = Nokogiri::XML(response.body)
|
405
|
+
certificate = doc.root.xpath('/results/pic-certificate').first
|
406
|
+
PicCertificate.parse(certificate)
|
407
|
+
end
|
408
|
+
|
364
409
|
def curl_exec(body='', url=next_url, expected=SipcMessage::OK)
|
365
410
|
@logger.debug "fetion curl exec"
|
366
411
|
@logger.debug "url: #{url}"
|
@@ -397,8 +442,7 @@ class Fetion
|
|
397
442
|
create_session(sipc_response) if sipc_response.contain?('I')
|
398
443
|
session_connected(sipc_response) if sipc_response.contain?('O')
|
399
444
|
if sipc_response.contain?('M')
|
400
|
-
receive_messages =
|
401
|
-
receive_messages = response.body.scan(%r{M #{@sid} SIP-C/4.0.*?SIPP\r?\n?$}m) if receive_messages.empty?
|
445
|
+
receive_messages = sipc_response.sections.select {|section| section =~ /^M/}
|
402
446
|
receive_messages.each do |message_response|
|
403
447
|
message_header, message_content = message_response.split(/\r\n\r\n/)
|
404
448
|
sip = sent_at = length = nil
|
@@ -419,26 +463,37 @@ class Fetion
|
|
419
463
|
doc = Nokogiri::XML(results)
|
420
464
|
doc.root.xpath("/results/user-info/personal").each do |personal_element|
|
421
465
|
@nickname = personal_element['nickname']
|
422
|
-
@
|
466
|
+
@impresa = personal_element['impresa']
|
423
467
|
end
|
424
468
|
doc.root.xpath("/results/user-info/contact-list/buddy-lists/buddy-list").each do |buddy_list|
|
425
469
|
@buddy_lists << Fetion::BuddyList.parse(buddy_list)
|
426
470
|
end
|
427
471
|
doc.root.xpath("/results/user-info/contact-list/buddies/b").each do |buddy|
|
428
|
-
|
472
|
+
contact = Fetion::Contact.parse_buddy(buddy)
|
473
|
+
@buddy_lists.find {|buddy_list| buddy_list.bid == contact.bid}.add_contact(contact)
|
429
474
|
end
|
430
475
|
end
|
431
476
|
|
432
477
|
response.body.scan(%r{<events>.*?</events>}).each do |events|
|
433
478
|
doc = Nokogiri::XML(events)
|
434
479
|
doc.root.xpath("/events/event[@type='PresenceChanged']/contacts/c").each do |c|
|
435
|
-
|
436
|
-
|
437
|
-
contact
|
438
|
-
|
439
|
-
|
480
|
+
unless self.uid == c['id']
|
481
|
+
contact = contacts.find {|contact| contact.uid == c['id']}
|
482
|
+
if contact
|
483
|
+
contact.update(c.children.first)
|
484
|
+
else
|
485
|
+
contact = Fetion::Contact.parse(c)
|
486
|
+
if @buddy_lists.size > 1
|
487
|
+
@buddy_lists.find {|buddy_list| buddy_list.bid == contact.bid}.add_contact(contact)
|
488
|
+
else
|
489
|
+
@contacts << contact
|
490
|
+
end
|
491
|
+
end
|
440
492
|
end
|
441
493
|
end
|
494
|
+
doc.root.xpath("/events/event[@type='AddBuddyApplication']/application").each do |application|
|
495
|
+
@add_requests << get_contact_info(:uri => application['uri'])
|
496
|
+
end
|
442
497
|
end
|
443
498
|
end
|
444
499
|
sipc_response
|
@@ -461,7 +516,7 @@ class Fetion
|
|
461
516
|
end
|
462
517
|
|
463
518
|
def calc_response
|
464
|
-
encrypted_password = Digest::SHA1.hexdigest([@
|
519
|
+
encrypted_password = Digest::SHA1.hexdigest([@uid.to_i].pack("V*") + [Digest::SHA1.hexdigest("#{DOMAIN}:#{@password}")].pack("H*"))
|
465
520
|
rsa_result = "4A026855890197CFDF768597D07200B346F3D676411C6F87368B5C2276DCEDD2"
|
466
521
|
str = @nonce + [encrypted_password].pack("H*") + [rsa_result].pack("H*")
|
467
522
|
rsa_key = OpenSSL::PKey::RSA.new
|
@@ -476,10 +531,20 @@ class Fetion
|
|
476
531
|
def self?(mobile_or_sid)
|
477
532
|
mobile_or_sid == @mobile_no or mobile_or_sid == @sid
|
478
533
|
end
|
534
|
+
|
535
|
+
def contacts
|
536
|
+
if @buddy_lists.size > 1
|
537
|
+
@buddy_lists.collect {|buddy_list| buddy_list.contacts}.flatten
|
538
|
+
else
|
539
|
+
@contacts
|
540
|
+
end
|
541
|
+
end
|
479
542
|
end
|
480
543
|
|
481
544
|
class FetionException < Exception; end
|
482
545
|
class Fetion::LoginException < FetionException; end
|
546
|
+
class Fetion::PasswordError < Fetion::LoginException; end
|
547
|
+
class Fetion::PasswordMaxError < Fetion::LoginException; end
|
483
548
|
class Fetion::NoNonceException < FetionException; end
|
484
549
|
class Fetion::RegisterException < FetionException; end
|
485
550
|
class Fetion::SendSmsException < FetionException; end
|
data/lib/rfetion/sipc_message.rb
CHANGED
@@ -6,7 +6,7 @@ class SipcMessage
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.register_second(fetion)
|
9
|
-
body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{fetion.mobile_no}" user-id="#{fetion.
|
9
|
+
body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{fetion.mobile_no}" user-id="#{fetion.uid}"><personal version="0" attributes="v4default" /><custom-config version="0" /><contact-list version="0" buddy-attributes="v4default" /></user-info><credentials domains="fetion.com.cn;m161.com.cn;www.ikuwa.cn;games.fetion.com.cn" /><presence><basic value="400" desc="" /></presence></args>|
|
10
10
|
sipc_create(:command => 'R', :F => fetion.sid, :I => 1, :Q => "#{fetion.next_alive} R", :A => %Q|Digest response="#{fetion.response}",algorithm="SHA1-sess-v4"|, :AK => 'ak-value', :body => body)
|
11
11
|
end
|
12
12
|
|
@@ -110,6 +110,11 @@ class SipcMessage
|
|
110
110
|
sipc_create(:command => 'R', :F => fetion.sid, :I => 1, :Q => "#{fetion.next_alive} R", :N => 'KeepAlive', :body => body)
|
111
111
|
end
|
112
112
|
|
113
|
+
def self.handle_contact_request(fetion, contact, options)
|
114
|
+
body = %Q|<args><contacts><buddies><buddy user-id="#{contact.uid}" uri="#{contact.uri}" result="#{options[:result]}" buddy-lists="" expose-mobile-no="0" expose-name="0" /></buddies></contacts></args>|
|
115
|
+
sipc_create(:command => 'S', :F => fetion.sid, :I => fetion.next_call, :Q => "1 S", :N => "HandleContactRequestV4", :body => body)
|
116
|
+
end
|
117
|
+
|
113
118
|
def self.sipc_response(http_response_body, fetion)
|
114
119
|
return if http_response_body == Fetion::SIPP
|
115
120
|
|
data/rfetion.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rfetion}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Richard Huang"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-23}
|
13
13
|
s.description = %q{rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.}
|
14
14
|
s.email = %q{flyerhzm@gmail.com}
|
15
15
|
s.executables = ["rfetion", "rfetion"]
|
@@ -27,8 +27,10 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/rfetion/contact.rb",
|
28
28
|
"lib/rfetion/fetion.rb",
|
29
29
|
"lib/rfetion/message.rb",
|
30
|
+
"lib/rfetion/pic_certificate.rb",
|
30
31
|
"lib/rfetion/sipc_message.rb",
|
31
32
|
"rfetion.gemspec",
|
33
|
+
"spec/rfetion/buddy_list_spec.rb",
|
32
34
|
"spec/rfetion/fetion_spec.rb",
|
33
35
|
"spec/rfetion/sipc_message_spec.rb",
|
34
36
|
"spec/spec.opts",
|
@@ -37,10 +39,11 @@ Gem::Specification.new do |s|
|
|
37
39
|
s.homepage = %q{http://github.com/flyerhzm/rfetion}
|
38
40
|
s.rdoc_options = ["--charset=UTF-8"]
|
39
41
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version = %q{1.3.
|
42
|
+
s.rubygems_version = %q{1.3.6}
|
41
43
|
s.summary = %q{rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.}
|
42
44
|
s.test_files = [
|
43
|
-
"spec/rfetion/
|
45
|
+
"spec/rfetion/buddy_list_spec.rb",
|
46
|
+
"spec/rfetion/fetion_spec.rb",
|
44
47
|
"spec/rfetion/sipc_message_spec.rb",
|
45
48
|
"spec/spec_helper.rb"
|
46
49
|
]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Fetion::BuddyList do
|
4
|
+
before :each do
|
5
|
+
@buddy_list = Fetion::BuddyList.new("1", "我的好友")
|
6
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "226911221", :uri => "sip:572512981@fetion.com.cn;p=3544", :bid => "1", :status => "400"))
|
7
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "295098062", :uri => "sip:638993408@fetion.com.cn;p=2242", :bid => "1"))
|
8
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "579113578", :uri => "sip:838271744@fetion.com.cn;p=4805", :bid => "1"))
|
9
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "665046562", :uri => "sip:926157269@fetion.com.cn;p=12906", :bid => "1", :status => "400"))
|
10
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "687455743", :uri => "sip:881033150@fetion.com.cn;p=5493", :bid => "1"))
|
11
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "714355089", :uri => "sip:973921799@fetion.com.cn;p=12193", :bid => "1", :status => "400"))
|
12
|
+
@buddy_list.add_contact(Fetion::Contact.new(:uid => "732743291", :uri => "sip:480867781@fetion.com.cn;p=16105", :bid => "1"))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get total contacts count" do
|
16
|
+
@buddy_list.total_contacts_count.should == 7
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should get online contacts count" do
|
20
|
+
@buddy_list.online_contacts_count.should == 3
|
21
|
+
end
|
22
|
+
end
|
data/spec/rfetion/fetion_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
2
2
|
|
3
3
|
describe Fetion do
|
4
4
|
class Fetion
|
5
|
-
attr_accessor :mobile_no, :sid, :password, :status_code, :user_status, :
|
5
|
+
attr_accessor :mobile_no, :sid, :password, :status_code, :user_status, :uid, :ssic, :nonce, :key, :signature, :response
|
6
6
|
end
|
7
7
|
|
8
8
|
before :each do
|
@@ -23,11 +23,25 @@ describe Fetion do
|
|
23
23
|
@fetion.status_code.should == "200"
|
24
24
|
@fetion.user_status.should == "101"
|
25
25
|
@fetion.mobile_no.should == "15800681509"
|
26
|
-
@fetion.
|
26
|
+
@fetion.uid.should == "390937727"
|
27
27
|
@fetion.sid.should == "730020377"
|
28
28
|
@fetion.ssic.should == "DhIOAADVEY68pV4EcRHsJ/GIIeltaYJsYJR2pj7b2+hCYLtgUd2j2mFaOqoqR98S3dm5pPH9t7W1yH5Cp/lVRP6VTwpLVvwxhhvj8qDz/p8rrW/Ljor6P4ZQKUZYz80JHjMt8R4AAA=="
|
29
29
|
end
|
30
30
|
|
31
|
+
it "should login failed with wrong password" do
|
32
|
+
@fetion.mobile_no = '15800681509'
|
33
|
+
@fetion.password = 'password'
|
34
|
+
FakeWeb.register_uri(:get, 'https://uid.fetion.com.cn/ssiportal/SSIAppSignInV4.aspx?mobileno=15800681509&domains=fetion.com.cn;m161.com.cn;www.ikuwa.cn&v4digest-type=1&v4digest=79cd56b93f21298dc8ae9d26de1258e3d6ce85a7', :body => %Q|<?xml version="1.0" encoding="utf-8" ?><results status-code="401" desc="password error" />|, :status => ['401', 'password error'])
|
35
|
+
lambda { @fetion.login }.should raise_exception(Fetion::PasswordError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should get verification code when password error max" do
|
39
|
+
@fetion.mobile_no = '15800681509'
|
40
|
+
@fetion.password = 'password'
|
41
|
+
FakeWeb.register_uri(:get, 'https://uid.fetion.com.cn/ssiportal/SSIAppSignInV4.aspx?mobileno=15800681509&domains=fetion.com.cn;m161.com.cn;www.ikuwa.cn&v4digest-type=1&v4digest=79cd56b93f21298dc8ae9d26de1258e3d6ce85a7', :body => %Q|<?xml version="1.0" encoding="utf-8" ?><results status-code="421" desc="password error max"><verification algorithm="picc-PasswordErrorMax" type="GeneralPic" text="您已连续输入错误密码,为了保障您的帐户安全,请输入图形验证码:" tips="温馨提示:建议您直接用手机编辑短信P发送到12520获取新密码。"></verification></results>|, :status => ['421'])
|
42
|
+
lambda { @fetion.login }.should raise_exception(Fetion::PasswordMaxError)
|
43
|
+
end
|
44
|
+
|
31
45
|
it "should login by sid" do
|
32
46
|
@fetion.sid = "730020377"
|
33
47
|
@fetion.password = 'password'
|
@@ -37,7 +51,7 @@ describe Fetion do
|
|
37
51
|
@fetion.status_code.should == "200"
|
38
52
|
@fetion.user_status.should == "101"
|
39
53
|
@fetion.mobile_no.should == "15800681509"
|
40
|
-
@fetion.
|
54
|
+
@fetion.uid.should == "390937727"
|
41
55
|
@fetion.sid.should == "730020377"
|
42
56
|
@fetion.ssic.should == "DhIOAADVEY68pV4EcRHsJ/GIIeltaYJsYJR2pj7b2+hCYLtgUd2j2mFaOqoqR98S3dm5pPH9t7W1yH5Cp/lVRP6VTwpLVvwxhhvj8qDz/p8rrW/Ljor6P4ZQKUZYz80JHjMt8R4AAA=="
|
43
57
|
end
|
@@ -52,7 +66,7 @@ describe Fetion do
|
|
52
66
|
|
53
67
|
describe "register" do
|
54
68
|
before :each do
|
55
|
-
@fetion.instance_variable_set(:@
|
69
|
+
@fetion.instance_variable_set(:@uid, "390937727")
|
56
70
|
@fetion.instance_variable_set(:@password, "password")
|
57
71
|
end
|
58
72
|
|
@@ -100,7 +114,7 @@ EOF
|
|
100
114
|
describe "register second" do
|
101
115
|
before :each do
|
102
116
|
@fetion.mobile_no = "15800681509"
|
103
|
-
@fetion.
|
117
|
+
@fetion.uid = "390937727"
|
104
118
|
@fetion.response = "458F72ED91E149D28D8467772AB7AD366527B55AC1A10CD18BA1B9BD95F2E082B1594B6C9B116E0BDECC315A2ABA0F4DD20591BF305FCDCDA4CA7B6434EA7788B893E0BB26E4E02097B6707BE0BD60E704D560DDDCB539A3E6FD49B985631FCA02C44D09A6713358BF1D323BA62B5273C7096B97D6A75C6BF9708768FF0113D0"
|
105
119
|
@fetion.instance_variable_set(:@seq, 3)
|
106
120
|
end
|
@@ -127,7 +141,10 @@ EOF
|
|
127
141
|
@fetion.register_second
|
128
142
|
|
129
143
|
@fetion.nickname.should == "flyerhzm"
|
130
|
-
@fetion.
|
144
|
+
@fetion.impresa.should == "http://www.fetionrobot.com"
|
145
|
+
@fetion.buddy_lists.collect {|buddy_list| buddy_list.name}.should == ['未分组', '我的好友', '好友', '同学']
|
146
|
+
@fetion.buddy_lists[1].contacts.collect {|contact| contact.uid}.should == ['226911221', '295098062', '579113578', '665046562', '687455743', '714355089', '732743291']
|
147
|
+
@fetion.buddy_lists.last.contacts.collect {|contact| contact.uid}.should == ['222516658', '227091544', '228358286', '229415466', '296436724']
|
131
148
|
end
|
132
149
|
end
|
133
150
|
end
|
@@ -136,7 +153,25 @@ EOF
|
|
136
153
|
before :each do
|
137
154
|
@fetion.instance_variable_set(:@seq, 5)
|
138
155
|
@fetion.instance_variable_set(:@sid, "730020377")
|
139
|
-
@fetion.instance_variable_set(:@
|
156
|
+
@fetion.instance_variable_set(:@uid, "390937727")
|
157
|
+
@buddy_list0 = Fetion::BuddyList.new("0", "未分组")
|
158
|
+
@buddy_list1 = Fetion::BuddyList.new("1", "我的好友")
|
159
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "226911221", :uri => "sip:572512981@fetion.com.cn;p=3544", :bid => "1"))
|
160
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "295098062", :uri => "sip:638993408@fetion.com.cn;p=2242", :bid => "1"))
|
161
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "579113578", :uri => "sip:838271744@fetion.com.cn;p=4805", :bid => "1"))
|
162
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "665046562", :uri => "sip:926157269@fetion.com.cn;p=12906", :bid => "1"))
|
163
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "687455743", :uri => "sip:881033150@fetion.com.cn;p=5493", :bid => "1"))
|
164
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "714355089", :uri => "sip:973921799@fetion.com.cn;p=12193", :bid => "1"))
|
165
|
+
@buddy_list1.add_contact(Fetion::Contact.new(:uid => "732743291", :uri => "sip:480867781@fetion.com.cn;p=16105", :bid => "1"))
|
166
|
+
@buddy_list2 = Fetion::BuddyList.new("2", "好友")
|
167
|
+
@buddy_list3 = Fetion::BuddyList.new("3", "同学")
|
168
|
+
@buddy_list3.add_contact(Fetion::Contact.new(:uid => "222516658", :uri => "sip:793401629@fetion.com.cn;p=1919", :bid => "3"))
|
169
|
+
@buddy_list3.add_contact(Fetion::Contact.new(:uid => "227091544", :uri => "sip:669700695@fetion.com.cn;p=3546", :nickname => "郭庆", :bid => "3"))
|
170
|
+
@buddy_list3.add_contact(Fetion::Contact.new(:uid => "228358286", :uri => "sip:660250260@fetion.com.cn;p=3854", :nickname => "蔡智武", :bid => "3"))
|
171
|
+
@buddy_list3.add_contact(Fetion::Contact.new(:uid => "229415466", :uri => "sip:737769829@fetion.com.cn;p=4078", :nickname => "ice", :bid => "3"))
|
172
|
+
@buddy_list3.add_contact(Fetion::Contact.new(:uid => "296436724", :uri => "sip:760087520@fetion.com.cn;p=2467", :bid => "3"))
|
173
|
+
@buddy_lists = [@buddy_list0, @buddy_list1, @buddy_list2, @buddy_list3]
|
174
|
+
@fetion.instance_variable_set(:@buddy_lists, @buddy_lists)
|
140
175
|
end
|
141
176
|
|
142
177
|
it "should get all contacts" do
|
@@ -235,7 +270,7 @@ EOF
|
|
235
270
|
response_body.gsub!("\n", "\r\n")
|
236
271
|
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=10", :body => response_body)
|
237
272
|
@fetion.get_contacts
|
238
|
-
@fetion.contacts.collect {|contact| contact.sid}.should == ["
|
273
|
+
@fetion.contacts.collect {|contact| contact.sid}.should == ["572512981", "638993408", nil, "926157269", nil, nil, "480867781", "793401629", "669700695", "660250260", "737769829", "760087520"]
|
239
274
|
end
|
240
275
|
|
241
276
|
it "should get received msg while get contacts" do
|
@@ -343,7 +378,7 @@ EOF
|
|
343
378
|
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=10", :body => response_body)
|
344
379
|
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => "SIPP")
|
345
380
|
@fetion.get_contacts
|
346
|
-
@fetion.contacts.collect {|c| c.sid}.should == ["
|
381
|
+
@fetion.contacts.collect {|c| c.sid}.should == ["572512981", "638993408", nil, "926157269", nil, nil, "480867781", "793401629", "669700695", "660250260", "737769829", "760087520"]
|
347
382
|
@fetion.receives.collect {|r| r.sip}.should == ["480867781@fetion.com.cn;p=16105"]
|
348
383
|
@fetion.receives.collect {|r| r.sent_at}.should == [Time.parse("Mon, 10 May 2010 14:26:17 GMT")]
|
349
384
|
@fetion.receives.collect {|r| r.text}.should == ["testtesttest"]
|
@@ -499,12 +534,15 @@ EOF
|
|
499
534
|
before :each do
|
500
535
|
@fetion.instance_variable_set(:@seq, 10)
|
501
536
|
@fetion.instance_variable_set(:@sid, "730020377")
|
502
|
-
contact = Fetion::Contact.new
|
503
|
-
contact.id = '295098062'
|
537
|
+
contact = Fetion::Contact.new(:uid => '295098062')
|
504
538
|
@fetion.instance_variable_set(:@contacts, [contact])
|
505
539
|
end
|
506
540
|
|
507
541
|
it "should get presence with online" do
|
542
|
+
buddy_list = Fetion::BuddyList.new(1, 'friends')
|
543
|
+
contact = Fetion::Contact.new(:uid => "295098062")
|
544
|
+
buddy_list.add_contact(contact)
|
545
|
+
@fetion.instance_variable_set(:@buddy_lists, [buddy_list])
|
508
546
|
response_body =<<-EOF
|
509
547
|
BN 730020377 SIP-C/4.0
|
510
548
|
N: PresenceV4
|
@@ -517,7 +555,7 @@ EOF
|
|
517
555
|
response_body.gsub!("\n", "\r\n")
|
518
556
|
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => response_body)
|
519
557
|
@fetion.pulse
|
520
|
-
@fetion.contacts.find {|contact| contact.
|
558
|
+
@fetion.contacts.find {|contact| contact.uid == '295098062'}.status.should == "400"
|
521
559
|
end
|
522
560
|
|
523
561
|
|
@@ -660,5 +698,102 @@ EOF
|
|
660
698
|
@fetion.receives.collect {|r| r.sent_at}.should == [Time.parse("Tue, 11 May 2010 15:18:56 GMT")]
|
661
699
|
@fetion.receives.collect {|r| r.text}.should == ["testtesttest"]
|
662
700
|
end
|
701
|
+
|
702
|
+
it "should get multiple receive msgs" do
|
703
|
+
response_body =<<-EOF
|
704
|
+
M 730020377 SIP-C/4.0
|
705
|
+
I: -11
|
706
|
+
Q: 4 M
|
707
|
+
F: sip:638993408@fetion.com.cn;p=2242
|
708
|
+
C: text/html-fragment
|
709
|
+
K: SaveHistory
|
710
|
+
L: 8
|
711
|
+
D: Sat, 22 May 2010 15:17:26 GMT
|
712
|
+
XI: b1344eca984c418ba4b72a6fed5011e5
|
713
|
+
|
714
|
+
testtestM 730020377 SIP-C/4.0
|
715
|
+
I: -11
|
716
|
+
Q: 5 M
|
717
|
+
F: sip:638993408@fetion.com.cn;p=2242
|
718
|
+
C: text/html-fragment
|
719
|
+
K: SaveHistory
|
720
|
+
L: 4
|
721
|
+
D: Sat, 22 May 2010 15:17:26 GMT
|
722
|
+
XI: 9b9eba984eb4468babf70f5dcceca39d
|
723
|
+
|
724
|
+
testSIPP
|
725
|
+
EOF
|
726
|
+
response_body.gsub!("\n", "\r\n")
|
727
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => response_body)
|
728
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=12", :body => "SIPP")
|
729
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=13", :body => "SIPP")
|
730
|
+
@fetion.pulse
|
731
|
+
@fetion.receives.collect {|r| r.sip}.should == ["638993408@fetion.com.cn;p=2242", "638993408@fetion.com.cn;p=2242"]
|
732
|
+
@fetion.receives.collect {|r| r.sent_at}.should == [Time.parse("Sat, 22 May 2010 15:17:26 GMT"), Time.parse("Sat, 22 May 2010 15:17:26 GMT")]
|
733
|
+
@fetion.receives.collect {|r| r.text}.should == ["testtest", "test"]
|
734
|
+
end
|
735
|
+
|
736
|
+
it "should get add buddy message" do
|
737
|
+
response_body =<<-EOF
|
738
|
+
BN 480867781 SIP-C/4.0
|
739
|
+
N: contact
|
740
|
+
I: 1
|
741
|
+
Q: 5 BN
|
742
|
+
L: 207
|
743
|
+
|
744
|
+
<events><event type="AddBuddyApplication"><application uri="sip:638993408@fetion.com.cn;p=2242" desc="梦研" type="0" time="2010-05-18 13:32:58" addbuddy-phrase-id="1" user-id="295098062"/></event></events>SIPP
|
745
|
+
EOF
|
746
|
+
response_body.gsub!("\n", "\r\n")
|
747
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => response_body)
|
748
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=12", :body => "SIPP")
|
749
|
+
response_body =<<-EOF
|
750
|
+
SIP-C/4.0 200 OK
|
751
|
+
I: 7
|
752
|
+
Q: 1 S
|
753
|
+
L: 368
|
754
|
+
|
755
|
+
<results><contact uri="sip:638993408@fetion.com.cn;p=2242" version="0" user-id="295098062" sid="638993408" mobile-no="13634102006" basic-service-status="1" carrier="CMCC" carrier-status="0" portrait-crc="0" name="" nickname="梦研" gender="0" birth-date="1900-01-01" birthday-valid="0" impresa="" carrier-region="CN.zj.571." user-region="" score-level="0"/></results>EOF
|
756
|
+
EOF
|
757
|
+
response_body.gsub!("\n", "\r\n")
|
758
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=13", :body => response_body)
|
759
|
+
@fetion.pulse
|
760
|
+
end
|
761
|
+
|
762
|
+
it "should handle contact request" do
|
763
|
+
contact = Fetion::Contact.new(:uid => '295098062', :uri => 'sip:638993408@fetion.com.cn;p=2242')
|
764
|
+
@fetion.instance_variable_set(:@add_requests, [contact])
|
765
|
+
buddy_list = Fetion::BuddyList.new("1", "friends")
|
766
|
+
@fetion.instance_variable_set(:@buddy_lists, [buddy_list])
|
767
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => "SIPP")
|
768
|
+
response_body =<<-EOF
|
769
|
+
SIP-C/4.0 200 OK
|
770
|
+
I: 9
|
771
|
+
Q: 1 S
|
772
|
+
L: 349
|
773
|
+
|
774
|
+
<results><contacts version="327533592"><buddies><buddy uri="sip:638993408@fetion.com.cn;p=2242" local-name="" buddy-lists="" online-notify="0" expose-mobile-no="0" expose-name="0" expose-basic-presence="1" accept-instant-message="1" result="1" relation-status="1" user-id="295098062" permission-values="identity=0;" /></buddies></contacts></results>BN 480867781 SIP-C/4.0
|
775
|
+
N: PresenceV4
|
776
|
+
I: 1
|
777
|
+
L: 329
|
778
|
+
Q: 6 BN
|
779
|
+
|
780
|
+
<events><event type="PresenceChanged"><contacts><c id="295098062"><p v="326156919" sid="638993408" su="sip:638993408@fetion.com.cn;p=2242" m="13634102006" c="CMCC" cs="0" s="1" l="1" svc="" n="梦研" i="" p="0" sms="0.0:0:0" sp="0" sh="0"/><pr di="PCCL030308238932" b="400" d="" dt="PC" dc="17"/></c></contacts></event></events>SIPP
|
781
|
+
EOF
|
782
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=12", :body => response_body)
|
783
|
+
@fetion.handle_contact_request('295098062', :result => "1")
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
describe "pic" do
|
788
|
+
it "should get pic when password error max" do
|
789
|
+
response_body =<<-EOF
|
790
|
+
<?xml version="1.0" encoding="UTF-8"?><results><pic-certificate id="2cb24c14-d0d4-4417-a69f-640c91f745c5" pic="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" /></results>
|
791
|
+
EOF
|
792
|
+
FakeWeb.register_uri(:get, "http://nav.fetion.com.cn/nav/GetPicCodeV4.aspx?algorithm=picc-PasswordErrorMax", :body => response_body)
|
793
|
+
actual_pic = @fetion.get_pic_certificate("picc-PasswordErrorMax")
|
794
|
+
expected_pic = PicCertificate.parse(Nokogiri::XML(response_body).root.xpath('/results/pic-certificate').first)
|
795
|
+
actual_pic.id.should == expected_pic.id
|
796
|
+
actual_pic.pic.should == expected_pic.pic
|
797
|
+
end
|
663
798
|
end
|
664
799
|
end
|
@@ -2,13 +2,13 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
3
3
|
describe SipcMessage do
|
4
4
|
class Fetion
|
5
|
-
attr_accessor :mobile_no, :sid, :password, :status_code, :user_status, :
|
5
|
+
attr_accessor :mobile_no, :sid, :password, :status_code, :user_status, :uid, :ssic, :nonce, :key, :signature, :response, :call
|
6
6
|
end
|
7
7
|
|
8
8
|
before :each do
|
9
9
|
@fetion = Fetion.new
|
10
10
|
@fetion.sid = "730020377"
|
11
|
-
@fetion.
|
11
|
+
@fetion.uid = "390937727"
|
12
12
|
@fetion.mobile_no = "15800681509"
|
13
13
|
@fetion.uri = "730020377@fetion.com.cn;p=6907"
|
14
14
|
@fetion.response = "62E57A276EB9B7AAC233B8983A39941870CE74E3B2CD6480B5CA9DCF37C57DECEA250F261543CB4424EE9E72354C9F33C805EB9839BF96501D0261614E69BDF0DBDF484047750B3113DF8850FEF39428ADC17FE86E8800ED5A77AA7F6630F21AE8A24E6ECC2F003BF3B93E35051A7778D238F86D21581BC829679EBEAD36390F"
|
@@ -183,6 +183,22 @@ EOF
|
|
183
183
|
SipcMessage.get_contact_info(@fetion, "tel:15800681507").should == sipc_message
|
184
184
|
end
|
185
185
|
|
186
|
+
it "should get contact info with sip" do
|
187
|
+
@fetion.call = 10
|
188
|
+
sipc_message =<<-EOF
|
189
|
+
S fetion.com.cn SIP-C/4.0
|
190
|
+
F: 730020377
|
191
|
+
I: 11
|
192
|
+
Q: 1 S
|
193
|
+
N: GetContactInfoV4
|
194
|
+
L: 65
|
195
|
+
|
196
|
+
<args><contact uri="sip:638993408@fetion.com.cn;p=2242" /></args>SIPP
|
197
|
+
EOF
|
198
|
+
sipc_message.gsub!("\n", "\r\n").chomp!
|
199
|
+
SipcMessage.get_contact_info(@fetion, "sip:638993408@fetion.com.cn;p=2242").should == sipc_message
|
200
|
+
end
|
201
|
+
|
186
202
|
it "should add buddy" do
|
187
203
|
@fetion.call = 9
|
188
204
|
@fetion.instance_variable_set(:@nickname, 'flyerhzm')
|
@@ -360,4 +376,23 @@ EOF
|
|
360
376
|
sipc_message.gsub!("\n", "\r\n").chomp!
|
361
377
|
SipcMessage.logout(@fetion).should == sipc_message
|
362
378
|
end
|
379
|
+
|
380
|
+
it "should handle contact request" do
|
381
|
+
@fetion.call = 8
|
382
|
+
sipc_message =<<-EOF
|
383
|
+
S fetion.com.cn SIP-C/4.0
|
384
|
+
F: 730020377
|
385
|
+
I: 9
|
386
|
+
Q: 1 S
|
387
|
+
N: HandleContactRequestV4
|
388
|
+
L: 186
|
389
|
+
|
390
|
+
<args><contacts><buddies><buddy user-id="295098062" uri="sip:638993408@fetion.com.cn;p=2242" result="1" buddy-lists="" expose-mobile-no="0" expose-name="0" /></buddies></contacts></args>SIPP
|
391
|
+
EOF
|
392
|
+
sipc_message.gsub!("\n", "\r\n").chomp!
|
393
|
+
contact = Fetion::Contact.new
|
394
|
+
contact.uid = '295098062'
|
395
|
+
contact.uri = 'sip:638993408@fetion.com.cn;p=2242'
|
396
|
+
SipcMessage.handle_contact_request(@fetion, contact, :result => "1").should == sipc_message
|
397
|
+
end
|
363
398
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfetion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
- 5
|
9
|
+
version: 0.5.5
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Richard Huang
|
@@ -9,29 +14,35 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-23 00:00:00 +08:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: guid
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 1
|
30
|
+
- 1
|
23
31
|
version: 0.1.1
|
24
|
-
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: nokogiri
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
38
|
requirements:
|
31
39
|
- - ">="
|
32
40
|
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
33
43
|
version: "0"
|
34
|
-
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
35
46
|
description: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
36
47
|
email: flyerhzm@gmail.com
|
37
48
|
executables:
|
@@ -52,8 +63,10 @@ files:
|
|
52
63
|
- lib/rfetion/contact.rb
|
53
64
|
- lib/rfetion/fetion.rb
|
54
65
|
- lib/rfetion/message.rb
|
66
|
+
- lib/rfetion/pic_certificate.rb
|
55
67
|
- lib/rfetion/sipc_message.rb
|
56
68
|
- rfetion.gemspec
|
69
|
+
- spec/rfetion/buddy_list_spec.rb
|
57
70
|
- spec/rfetion/fetion_spec.rb
|
58
71
|
- spec/rfetion/sipc_message_spec.rb
|
59
72
|
- spec/spec.opts
|
@@ -71,22 +84,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
84
|
requirements:
|
72
85
|
- - ">="
|
73
86
|
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 0
|
74
89
|
version: "0"
|
75
|
-
version:
|
76
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
91
|
requirements:
|
78
92
|
- - ">="
|
79
93
|
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
80
96
|
version: "0"
|
81
|
-
version:
|
82
97
|
requirements: []
|
83
98
|
|
84
99
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.3.
|
100
|
+
rubygems_version: 1.3.6
|
86
101
|
signing_key:
|
87
102
|
specification_version: 3
|
88
103
|
summary: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
89
104
|
test_files:
|
105
|
+
- spec/rfetion/buddy_list_spec.rb
|
90
106
|
- spec/rfetion/fetion_spec.rb
|
91
107
|
- spec/rfetion/sipc_message_spec.rb
|
92
108
|
- spec/spec_helper.rb
|