jubjub 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/README.mdown +27 -1
  2. data/lib/jubjub.rb +1 -1
  3. data/lib/jubjub/connection/xmpp_gateway.rb +9 -9
  4. data/lib/jubjub/connection/xmpp_gateway/helper.rb +5 -5
  5. data/lib/jubjub/connection/xmpp_gateway/muc.rb +127 -32
  6. data/lib/jubjub/connection/xmpp_gateway/pubsub.rb +64 -64
  7. data/lib/jubjub/data_form.rb +16 -13
  8. data/lib/jubjub/errors.rb +2 -2
  9. data/lib/jubjub/helpers.rb +32 -0
  10. data/lib/jubjub/jid.rb +8 -8
  11. data/lib/jubjub/muc.rb +3 -1
  12. data/lib/jubjub/muc/affiliation.rb +77 -0
  13. data/lib/jubjub/muc/affiliations_collection.rb +31 -0
  14. data/lib/jubjub/muc/collection.rb +12 -19
  15. data/lib/jubjub/muc/configuration.rb +2 -2
  16. data/lib/jubjub/muc/muc.rb +24 -11
  17. data/lib/jubjub/pubsub.rb +1 -1
  18. data/lib/jubjub/pubsub/affiliation.rb +20 -20
  19. data/lib/jubjub/pubsub/affiliation_collection.rb +11 -18
  20. data/lib/jubjub/pubsub/collection.rb +14 -21
  21. data/lib/jubjub/pubsub/configuration.rb +2 -2
  22. data/lib/jubjub/pubsub/item.rb +8 -8
  23. data/lib/jubjub/pubsub/item_collection.rb +10 -17
  24. data/lib/jubjub/pubsub/pubsub.rb +17 -17
  25. data/lib/jubjub/pubsub/subscription.rb +6 -6
  26. data/lib/jubjub/response.rb +1 -1
  27. data/lib/jubjub/response/error.rb +6 -6
  28. data/lib/jubjub/response/proxy.rb +8 -8
  29. data/lib/jubjub/response/response.rb +10 -10
  30. data/lib/jubjub/user.rb +16 -15
  31. data/spec/connection/xmpp_gateway_muc_spec.rb +174 -40
  32. data/spec/connection/xmpp_gateway_pubsub_spec.rb +100 -104
  33. data/spec/fixtures/vcr_cassettes/muc_configuration.yml +73 -6
  34. data/spec/fixtures/vcr_cassettes/muc_create_with_configuration.yml +8 -8
  35. data/spec/fixtures/vcr_cassettes/muc_message.yml +89 -0
  36. data/spec/fixtures/vcr_cassettes/muc_modify_affiliations.yml +367 -0
  37. data/spec/fixtures/vcr_cassettes/muc_retrieve_affiliations.yml +93 -0
  38. data/spec/fixtures/vcr_cassettes/pubsub_publish_with_dataform_payload.yml +3 -3
  39. data/spec/fixtures/vcr_cassettes/pubsub_retrieve_items.yml +24 -18
  40. data/spec/mixins/user_spec.rb +37 -37
  41. data/spec/models/data_form_spec.rb +3 -3
  42. data/spec/models/jid_spec.rb +41 -41
  43. data/spec/models/muc_affiliation_collection_spec.rb +146 -0
  44. data/spec/models/muc_affiliation_spec.rb +215 -0
  45. data/spec/models/muc_collection_spec.rb +64 -32
  46. data/spec/models/muc_configuration_spec.rb +3 -3
  47. data/spec/models/muc_spec.rb +44 -23
  48. data/spec/models/pubsub_affiliation_collection_spec.rb +65 -30
  49. data/spec/models/pubsub_affiliation_spec.rb +50 -50
  50. data/spec/models/pubsub_collection_spec.rb +65 -49
  51. data/spec/models/pubsub_item_collection_spec.rb +17 -17
  52. data/spec/models/pubsub_item_spec.rb +18 -18
  53. data/spec/models/pubsub_spec.rb +41 -41
  54. data/spec/models/pubsub_subscription_spec.rb +23 -23
  55. data/spec/models/response_error_spec.rb +19 -19
  56. data/spec/models/response_proxy_spec.rb +51 -49
  57. data/spec/models/response_spec.rb +33 -33
  58. data/spec/support/helpers.rb +21 -1
  59. data/spec/support/matchers.rb +4 -4
  60. data/spec/support/shared_examples.rb +132 -94
  61. data/spec/support/webmock_stanza_matching.rb +43 -0
  62. metadata +45 -16
@@ -2,7 +2,7 @@ require "nokogiri"
2
2
 
3
3
  module Jubjub
4
4
  class DataForm
5
-
5
+
6
6
  attr_reader :fields
7
7
 
8
8
  def initialize(config={})
@@ -47,12 +47,15 @@ module Jubjub
47
47
  def ==(thing)
48
48
  thing.is_a?( self.class ) && thing.fields == self.fields
49
49
  end
50
-
50
+
51
51
  def to_builder(root_doc=Nokogiri::XML.parse(""))
52
52
  Nokogiri::XML::Builder.with(root_doc) do |xml|
53
53
  xml.x_('xmlns' => 'jabber:x:data', :type => 'submit') {
54
- settings.each{|name,values|
55
- xml.field_('var' => name){
54
+ fields.each{|name,settings|
55
+ options = {'var' => name}
56
+ options[:type] = settings[:type] if settings[:type]
57
+ values = Array[self[name]].flatten
58
+ xml.field_(options){
56
59
  values.each {|v|
57
60
  xml.value_ v
58
61
  }
@@ -73,8 +76,8 @@ module Jubjub
73
76
  end
74
77
 
75
78
  def check_config(config)
76
- required = [:type]
77
- understood = required + [:label, :options, :value]
79
+ required = []
80
+ understood = required + [:type, :label, :options, :value]
78
81
 
79
82
  raise Jubjub::ArgumentError.new("please initialize with a hash of the format { 'foo' => {:type => 'boolean', :value => false, :label => 'Fooey'} }") unless config.is_a? Hash
80
83
 
@@ -87,7 +90,7 @@ module Jubjub
87
90
  ) if mystery_arguments.any?
88
91
  end
89
92
  end
90
-
93
+
91
94
  def convert_xml(config)
92
95
  config.xpath(
93
96
  # Get fields
@@ -98,24 +101,24 @@ module Jubjub
98
101
  hash = {}
99
102
  hash[:type] = field.attr 'type'
100
103
  hash[:label] = field.attr 'label'
101
-
104
+
102
105
  value = field.xpath('x_data:value', namespaces)
103
106
  hash[:value] = hash[:type].match(/\-multi$/) ? value.map{|e| e.content } : value.text
104
-
107
+
105
108
  options = field.xpath('x_data:option', namespaces).map{|o|
106
109
  { :label => o.attr('label'), :value => o.xpath('x_data:value', namespaces).text }
107
110
  }
108
111
  hash[:options] = options if options.any?
109
-
112
+
110
113
  result[field.attr 'var'] = hash unless hash[:type] == 'fixed'
111
114
  result
112
115
  }
113
116
  end
114
-
117
+
115
118
  def namespaces
116
119
  { 'x_data' => 'jabber:x:data' }
117
120
  end
118
121
 
119
122
  end
120
-
121
- end
123
+
124
+ end
@@ -1,7 +1,7 @@
1
1
  module Jubjub
2
2
  class Error < StandardError
3
3
  end
4
-
4
+
5
5
  class ArgumentError < Error
6
6
  end
7
- end
7
+ end
@@ -0,0 +1,32 @@
1
+ module Jubjub
2
+ module Helpers
3
+ module Collection
4
+
5
+ # Hint that methods are actually applied to list using method_missing
6
+ def inspect
7
+ list.inspect
8
+ end
9
+
10
+ def search_list(default=nil, &block)
11
+ list unless default # We HAVE to search unless there is a default
12
+ if list?
13
+ list.find( &block ) || default
14
+ else
15
+ default
16
+ end
17
+ end
18
+ private :search_list
19
+
20
+ def method_missing(name, *args, &block)
21
+ list.send(name, *args, &block)
22
+ end
23
+ private :method_missing
24
+
25
+ def list?
26
+ instance_variable_defined?("@list")
27
+ end
28
+ private :list?
29
+
30
+ end
31
+ end
32
+ end
@@ -1,10 +1,10 @@
1
1
  module Jubjub
2
2
  class Jid
3
-
3
+
4
4
  PATTERN = /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/
5
-
5
+
6
6
  attr_reader :node, :domain, :resource
7
-
7
+
8
8
  def initialize(node, domain = nil, resource = nil)
9
9
  if node.is_a? Jid
10
10
  @node = node.node
@@ -15,19 +15,19 @@ module Jubjub
15
15
  @domain = domain
16
16
  @resource = resource
17
17
  end
18
-
18
+
19
19
  if @domain.nil? && @resource.nil?
20
20
  @node, @domain, @resource = node.to_s.scan(PATTERN).first
21
21
  end
22
22
  end
23
-
23
+
24
24
  def to_s
25
25
  (node ? "#{node}@" : '') + domain + (resource ? "/#{resource}" : '')
26
26
  end
27
-
27
+
28
28
  def ==(obj)
29
29
  obj.is_a?( self.class ) && obj.to_s == self.to_s
30
30
  end
31
-
31
+
32
32
  end
33
- end
33
+ end
@@ -1,4 +1,6 @@
1
1
  require "jubjub/connection/xmpp_gateway/muc"
2
2
  require 'jubjub/muc/muc'
3
3
  require 'jubjub/muc/collection'
4
- require 'jubjub/muc/configuration'
4
+ require 'jubjub/muc/configuration'
5
+ require 'jubjub/muc/affiliations_collection'
6
+ require 'jubjub/muc/affiliation'
@@ -0,0 +1,77 @@
1
+ class Jubjub::Muc::Affiliation
2
+
3
+ attr_reader :muc_jid, :jid, :nick, :role, :affiliation
4
+
5
+ def initialize(muc_jid, jid, nick, role, affiliation, connection)
6
+ @muc_jid = Jubjub::Jid.new muc_jid
7
+ @jid = Jubjub::Jid.new jid
8
+ @nick = nick
9
+ @role = role
10
+ @affiliation = affiliation
11
+ @connection = connection
12
+ end
13
+
14
+ # Hide the connection details and show jid as string for compactness
15
+ def inspect
16
+ obj_id = "%x" % (object_id << 1)
17
+ "#<#{self.class}:0x#{obj_id} @muc_jid=\"#{muc_jid}\" @jid=\"#{jid}\" @nick=#{@nick.inspect} @affiliation=#{affiliation.inspect} @role=#{@role.inspect}>"
18
+ end
19
+
20
+ def outcast?
21
+ affiliation == "outcast"
22
+ end
23
+
24
+ def none?
25
+ affiliation == "none"
26
+ end
27
+
28
+ def member?
29
+ affiliation == "member"
30
+ end
31
+
32
+ def admin?
33
+ affiliation == "admin"
34
+ end
35
+
36
+ def owner?
37
+ affiliation == "owner"
38
+ end
39
+
40
+ def set(new_affiliation)
41
+ old_affiliation = @affiliation
42
+ @affiliation = new_affiliation
43
+ r = @connection.muc.modify_affiliations muc_jid, self
44
+ @affiliation = old_affiliation unless r
45
+ r
46
+ end
47
+
48
+ def set_outcast
49
+ set 'outcast'
50
+ end
51
+
52
+ def set_none
53
+ set 'none'
54
+ end
55
+
56
+ def set_member
57
+ set 'member'
58
+ end
59
+
60
+ def set_admin
61
+ set 'admin'
62
+ end
63
+
64
+ def set_owner
65
+ set 'owner'
66
+ end
67
+
68
+ def ==(other)
69
+ other.is_a?( self.class ) &&
70
+ other.muc_jid == self.muc_jid &&
71
+ other.jid == self.jid &&
72
+ other.nick == self.nick &&
73
+ other.role == self.role &&
74
+ other.affiliation == self.affiliation
75
+ end
76
+
77
+ end
@@ -0,0 +1,31 @@
1
+ class Jubjub::Muc::AffiliationCollection
2
+
3
+ attr_reader :jid
4
+
5
+ include Jubjub::Helpers::Collection
6
+
7
+ def initialize(jid,connection)
8
+ @jid = Jubjub::Jid.new jid
9
+ @connection = connection
10
+ end
11
+
12
+ def [](jid_num)
13
+ case jid_num
14
+ when Fixnum
15
+ list[jid_num]
16
+ when Jubjub::Jid
17
+ search_list( Jubjub::Muc::Affiliation.new( jid, jid_num, nil, nil, 'none', @connection ) ){|i| i.jid == jid_num }
18
+ else
19
+ j = Jubjub::Jid.new( jid_num )
20
+ search_list( Jubjub::Muc::Affiliation.new( jid, j, nil, nil, 'none', @connection ) ){|i| i.jid == j }
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def list
27
+ # OPTIMIZE: These requests should be made in parallel, not sequentially
28
+ @list ||= %w(owner outcast member admin).map{|a| @connection.muc.retrieve_affiliations( jid, a ) }.flatten
29
+ end
30
+
31
+ end
@@ -2,14 +2,16 @@
2
2
  # and delaying expensive operations until
3
3
  # required
4
4
  class Jubjub::Muc::Collection
5
-
5
+
6
6
  attr_reader :jid
7
-
7
+
8
+ include Jubjub::Helpers::Collection
9
+
8
10
  def initialize(jid, connection)
9
11
  @jid = Jubjub::Jid.new(jid)
10
12
  @connection = connection
11
13
  end
12
-
14
+
13
15
  def create(node, nick = nil, &block)
14
16
  full_jid = Jubjub::Jid.new node, @jid.domain, nick || @connection.jid.node
15
17
 
@@ -22,34 +24,25 @@ class Jubjub::Muc::Collection
22
24
  # Instant room
23
25
  result = @connection.muc.create full_jid
24
26
  end
25
-
27
+
26
28
  end
27
-
29
+
28
30
  def [](jid_node_num)
29
31
  case jid_node_num
30
32
  when Fixnum
31
33
  list[jid_node_num]
32
34
  when Jubjub::Jid
33
- list.find{|m| m.jid == jid_node_num } || Jubjub::Muc.new( jid_node_num, nil, @connection )
35
+ search_list( Jubjub::Muc.new( jid_node_num, nil, @connection ) ){|m| m.jid == jid_node_num }
34
36
  else
35
37
  j = Jubjub::Jid.new jid_node_num, jid.domain
36
- list.find{|m| m.jid == j } || Jubjub::Muc.new( j, nil, @connection )
38
+ search_list( Jubjub::Muc.new( j, nil, @connection ) ){|m| m.jid == j }
37
39
  end
38
40
  end
39
-
40
- # Hint that methods are actually applied to list using method_missing
41
- def inspect
42
- list.inspect
43
- end
44
-
41
+
45
42
  private
46
43
 
47
- def method_missing(name, *args, &block)
48
- list.send(name, *args, &block)
49
- end
50
-
51
44
  def list
52
45
  @list ||= @connection.muc.list @jid
53
46
  end
54
-
55
- end
47
+
48
+ end
@@ -1,5 +1,5 @@
1
1
  require 'jubjub/data_form'
2
2
 
3
3
  class Jubjub::Muc::Configuration < Jubjub::DataForm
4
-
5
- end
4
+
5
+ end
@@ -1,37 +1,50 @@
1
1
  module Jubjub
2
2
  class Muc
3
-
3
+
4
4
  attr_reader :jid, :name
5
-
5
+
6
6
  def initialize(jid, name = nil, connection = nil)
7
7
  @jid = Jubjub::Jid.new(jid)
8
8
  @name = name
9
9
  @connection = connection
10
- end
11
-
10
+ end
11
+
12
+ def message(body)
13
+ @connection.muc.message(jid, body)
14
+ self
15
+ end
16
+
12
17
  def exit(nick = nil)
13
18
  full_jid = Jubjub::Jid.new @jid.node, @jid.domain, nick || @connection.jid.node
14
-
19
+
15
20
  @connection.muc.exit(full_jid)
16
21
  self
17
22
  end
18
-
23
+
19
24
  def destroy
20
25
  @connection.muc.destroy(@jid)
21
26
  end
22
-
27
+
28
+ def affiliations
29
+ AffiliationCollection.new jid, @connection
30
+ end
31
+
32
+ def roles
33
+ RoleCollection.new jid, @connection
34
+ end
35
+
23
36
  # Hide the connection details and show jid as string for compactness
24
37
  def inspect
25
38
  obj_id = "%x" % (object_id << 1)
26
39
  "#<#{self.class}:0x#{obj_id} @jid=\"#{@jid}\" @name=#{@name.inspect}>"
27
40
  end
28
-
41
+
29
42
  def ==(other)
30
43
  other.is_a?( self.class ) &&
31
44
  other.jid == self.jid &&
32
45
  other.name == self.name
33
46
  end
34
-
35
- end
36
47
 
37
- end
48
+ end
49
+
50
+ end
@@ -6,4 +6,4 @@ require "jubjub/pubsub/affiliation"
6
6
  require "jubjub/pubsub/affiliation_collection"
7
7
  require "jubjub/pubsub/item"
8
8
  require "jubjub/pubsub/item_collection"
9
- require "jubjub/pubsub/subscription"
9
+ require "jubjub/pubsub/subscription"
@@ -1,7 +1,7 @@
1
1
  class Jubjub::Pubsub::Affiliation
2
-
2
+
3
3
  attr_reader :pubsub_jid, :pubsub_node, :jid, :affiliation
4
-
4
+
5
5
  def initialize(pubsub_jid, pubsub_node, jid, affiliation, connection)
6
6
  @pubsub_jid = Jubjub::Jid.new pubsub_jid
7
7
  @pubsub_node = pubsub_node
@@ -15,31 +15,31 @@ class Jubjub::Pubsub::Affiliation
15
15
  obj_id = "%x" % (object_id << 1)
16
16
  "#<#{self.class}:0x#{obj_id} @pubsub_jid=\"#{pubsub_jid}\" @pubsub_node=#{@pubsub_node} @jid=\"#{jid}\" @affiliation=#{affiliation.inspect}>"
17
17
  end
18
-
18
+
19
19
  def owner?
20
20
  affiliation == "owner"
21
21
  end
22
-
22
+
23
23
  def publisher?
24
24
  affiliation == "publisher"
25
25
  end
26
-
26
+
27
27
  def publish_only?
28
28
  affiliation == "publish-only"
29
29
  end
30
-
30
+
31
31
  def member?
32
32
  affiliation == "member"
33
33
  end
34
-
34
+
35
35
  def none?
36
36
  affiliation == "none"
37
37
  end
38
-
38
+
39
39
  def outcast?
40
40
  affiliation == "outcast"
41
41
  end
42
-
42
+
43
43
  def set(new_affiliation)
44
44
  old_affiliation = @affiliation
45
45
  @affiliation = new_affiliation
@@ -47,31 +47,31 @@ class Jubjub::Pubsub::Affiliation
47
47
  @affiliation = old_affiliation unless r
48
48
  r
49
49
  end
50
-
50
+
51
51
  def set_owner
52
52
  set 'owner'
53
53
  end
54
-
54
+
55
55
  def set_publisher
56
- set 'publisher'
56
+ set 'publisher'
57
57
  end
58
-
58
+
59
59
  def set_publish_only
60
- set 'publish-only'
60
+ set 'publish-only'
61
61
  end
62
-
62
+
63
63
  def set_member
64
64
  set 'member'
65
65
  end
66
-
66
+
67
67
  def set_none
68
68
  set 'none'
69
69
  end
70
-
70
+
71
71
  def set_outcast
72
72
  set 'outcast'
73
73
  end
74
-
74
+
75
75
  def ==(other)
76
76
  other.is_a?( self.class ) &&
77
77
  other.pubsub_jid == self.pubsub_jid &&
@@ -79,5 +79,5 @@ class Jubjub::Pubsub::Affiliation
79
79
  other.jid == self.jid &&
80
80
  other.affiliation == self.affiliation
81
81
  end
82
-
83
- end
82
+
83
+ end