rfetion 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|