ecircle_soap_client 0.0.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.
@@ -0,0 +1,14 @@
1
+ require 'ostruct'
2
+ module Ecircle
3
+ class Configuration
4
+ attr_accessor :realm, :user, :password, :wsdl
5
+
6
+ def initialize
7
+ @session_token = nil
8
+ @wsdl = OpenStruct.new
9
+ wsdl.document = "http://webservices.ecircle-ag.com/soap/ecm.wsdl"
10
+ wsdl.endpoint = "http://webservices.ecircle-ag.com/rpc"
11
+ wsdl.namespace = "http://webservices.ecircleag.com/rpcns"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,73 @@
1
+ module Ecircle
2
+ class Group < Ecircle::Base
3
+ class << self
4
+ def find_all_by_name(group_name)
5
+ ary = Ecircle.client.lookup_groups :lookupParams => { :groupName => group_name }
6
+ ary.is_a?(Array) ? ary.collect { |a| Ecircle::Group.new(a) } : []
7
+ end
8
+
9
+ def find_by_name(group_name)
10
+ hsh = Ecircle.client.lookup_groups :lookupParams => { :groupName => group_name }
11
+ hsh.is_a?(Hash) ? Group.new(hsh) : raise("Group name #{group_name} not unique")
12
+ end
13
+
14
+ def all
15
+ find_all_by_name("")
16
+ end
17
+
18
+ def find_by_id(idstr)
19
+ ## TODO there must be a better way of doing this?!
20
+ ## TODO but there isn't a lookupGroupById in the wsdl specification.
21
+ all.reject { |a| a.id != idstr }.first
22
+ end
23
+ end
24
+
25
+ def initialize(hsh = nil)
26
+ super()
27
+ @all_fields = hsh || {}
28
+ @id = self[:id]
29
+ end
30
+
31
+ # Make a user a member of a group. Can be called multiple times for the same
32
+ # user, eCircle checks for duplicates based on the email or whatever.
33
+ # Returns a member object.
34
+ def add_member(user, send_invite = false, send_message = false)
35
+ member_id = Ecircle.client.
36
+ create_member(:userId => user.id, :groupId => @id,
37
+ :invite => send_invite, :sendMessage => send_message)
38
+ Ecircle::Member.find_by_id(member_id)
39
+ end
40
+
41
+ def remove_user(user, send_message = false)
42
+ user.leave_group(self, send_message)
43
+ end
44
+
45
+ def remove_member(member, send_message = false)
46
+ member.user.leave_group(self, send_message)
47
+ end
48
+
49
+ # clone this group at eCircle. For example,
50
+ # Ecircle::Group.
51
+ # find_by_name("fubar").
52
+ # clone( "snafu", "snafu@cmXX.ecircle-ag.com", false )
53
+ def clone(with_name, with_email, keep_owner = true)
54
+ Ecircle.client.
55
+ clone_group(:templateGroupId => @id, :newGroupEmail => with_email,
56
+ :newGroupName => with_name, :keepOwner => keep_owner)
57
+ end
58
+
59
+ def delete
60
+ Ecircle.client.delete_group :groupId => @id
61
+ end
62
+
63
+ def to_xml
64
+ # prefer to use u.send(...) but that creates a new xml element called 'send'!
65
+ # hence this is using instance_eval with a string.
66
+ Savon::SOAP::XML.new.xml do |x|
67
+ x.group(:id => @id) do |u|
68
+ u.name(@id)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,31 @@
1
+ module Ecircle
2
+ class Member < Ecircle::Base
3
+ class << self
4
+ def find_by_id(member_id)
5
+ Ecircle.client.lookup_member_by_id :memberid => member_id
6
+ end
7
+ end
8
+
9
+ def initialize(xml_string)
10
+ super()
11
+ init_with_xml("member", xml_string)
12
+ end
13
+
14
+ def delete
15
+ Ecircle.client.delete_member :memberId => @id
16
+ end
17
+
18
+ ## TODO with assume that the member id is the form of "<userid>g<groupid>", hence
19
+ ## TODO split on 'g' should work!
20
+ def user_id ; @id.split(/g/).first ; end
21
+ def group_id ; @id.split(/g/).last ; end
22
+
23
+ def group
24
+ Ecircle::Group.find_by_id(group_id)
25
+ end
26
+ def user
27
+ Ecircle::User.find_by_id(user_id)
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,93 @@
1
+ module Ecircle
2
+ class Message < Ecircle::Base
3
+
4
+ MessageTypeUnknown = Class.new(RuntimeError)
5
+ MessageGroupNotDefined = Class.new(RuntimeError)
6
+
7
+ class << self
8
+ def find_all_by_group_name(group_name)
9
+ ary = Ecircle.client.lookup_messages :lookupParams => { :groupName => group_name }
10
+ ary.is_a?(Array) ? ary.collect { |a| Ecircle::Message.new(a) } : []
11
+ end
12
+
13
+ def find_by_id(idstr)
14
+ ## TODO no lookupMessageById, hence this workaround.
15
+ all.reject { |msg| msg.id != idstr }.first
16
+ end
17
+
18
+ def all
19
+ find_all_by_group_name("")
20
+ end
21
+ end
22
+
23
+ def initialize(hsh)
24
+ super()
25
+ @all_fields = hsh
26
+ @id = self[:id]
27
+ end
28
+
29
+ def subject
30
+ self[:subject]
31
+ end
32
+
33
+ def group
34
+ # a single message could potentially have no group_id? Either case this
35
+ # should just return nil instead of raising an exception.
36
+ Ecircle::Group.find_by_id(self[:group_id]) if self[:group_id]
37
+ end
38
+
39
+ def delete
40
+ Ecircle.client.delete_message :messageId => self.id
41
+ true
42
+ rescue Ecircle::Client::PermissionDenied => e
43
+ false
44
+ end
45
+
46
+ # This does one of two things, if the message is of type 'single', then
47
+ # it uses send_single_message_to_user, else if the type is 'normal' then
48
+ # it uses the send_group_message_to_user.
49
+ #
50
+ # If parameters are given and this is a single message, then a parameterized
51
+ # version of the message is sent.
52
+ #
53
+ # Return value is an array with the first value being boolean to indicate
54
+ # success status. The second value is the original result returned by the
55
+ # ecircle API. The thing is, that ecircle will return nil on success, so
56
+ # in that case, we return [true, nil].
57
+ def send_to_user(user, parameters = nil)
58
+ result = case self[:type]
59
+
60
+ when /single/
61
+ if parameters.nil?
62
+ Ecircle.client.
63
+ send_single_message_to_user(:singleMessageId => @id,
64
+ :userId => user.id)
65
+ else
66
+ paras = { :singleMessageId => @id,
67
+ :userId => user.id,
68
+ :names => parameters.keys,
69
+ :values => parameters.values,
70
+ }
71
+ Ecircle.client.send_parametrized_single_message_to_user(paras)
72
+ end
73
+
74
+ when /normal/
75
+ # raise an exception because this is inconsistent: a group message without
76
+ # group_id is not possible.
77
+ raise MessageGroupNotDefined, "MsgId: #{self.id}" unless self[:group_id]
78
+
79
+ Ecircle.client.
80
+ send_group_message_to_user(:userId => user.id,
81
+ :messageId => @id,
82
+ :groupid => self[:group_id])
83
+ else
84
+ raise(MessageTypeUnknown, "Type: #{self[:type]} unknown for "+
85
+ "MsgId: #{self.id}")
86
+ end
87
+
88
+ # strangely, if the message sending worked out, then ecircle sends nil, i.e.
89
+ # nothing back. Else we get some sort of strange error or exception.
90
+ result.nil? ? [true, nil] : [false, result]
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,120 @@
1
+ module Ecircle
2
+ class User < Ecircle::Base
3
+
4
+ class << self
5
+ def create_by_email(email)
6
+ u = User.new
7
+ u.email = email
8
+ ## TODO why must the title be defined
9
+ u.title = "-1"
10
+ u.id = Ecircle.client.create_user :userXmlSpec => u.to_xml
11
+ u
12
+ end
13
+
14
+ def find_by_email(email)
15
+ Ecircle.client.lookup_user_by_email :email => email
16
+ end
17
+
18
+ def find_by_identifier(idstr)
19
+ Ecircle.client.lookup_user_by_identifier :identifier => idstr
20
+ end
21
+
22
+ def find_by_id(idstr)
23
+ Ecircle.client.lookup_user_by_id :userId => idstr
24
+ end
25
+ end
26
+
27
+ def initialize(xml_string = nil)
28
+ super()
29
+ initialize_with_xml(xml_string) if xml_string
30
+ end
31
+
32
+ def email
33
+ self[:email]
34
+ end
35
+
36
+ def delete
37
+ Ecircle.client.delete_user :user_id => @id
38
+ end
39
+
40
+ def create_or_update(send_message = false)
41
+ Ecircle.client.
42
+ create_or_update_user_by_email :userXml => to_xml, :sendMessage => send_message
43
+ end
44
+
45
+ def save
46
+ Ecircle.client.update_user :userXmlSpec => to_xml
47
+ end
48
+
49
+ # Returns the group ids this user is signed up to as an Array of strings.
50
+ def group_ids
51
+ [Ecircle.client.find_memberships_by_email(:email => email)].flatten.compact
52
+ end
53
+
54
+ def groups
55
+ group_ids.collect { |grpid| Ecircle::Group.find_by_id(grpid) }
56
+ end
57
+ alias_method :memberships, :groups
58
+
59
+ # +group_or_id+ may be a Ecircle::Group
60
+ # object, containing the group's id, or the id directly.
61
+ def in_group?(group_or_id)
62
+ group_ids.include?(Ecircle::User.group_id(group_or_id))
63
+ end
64
+
65
+ def join_group(group, send_invite = false, send_message = false)
66
+ group.add_member self, send_invite, send_message
67
+ end
68
+
69
+ # Unsubscribe this user from the given group. group may be a Ecircle::Group
70
+ # object, containing the group's id, or the id directly.
71
+ # Always returns true.
72
+ def leave_group(group_or_id, send_message = false)
73
+ Ecircle.client.
74
+ unsubscribe_member_by_email(:groupId => Ecircle::User.group_id(group_or_id),
75
+ :email => email,
76
+ :sendMessage => send_message)
77
+ end
78
+
79
+ def to_xml
80
+ obj = self # in instance_eval 'self' will be something else, so create new
81
+ # reference to te self containing all the data.
82
+
83
+ # prefer to use u.send(...) but that creates a new xml element called 'send'!
84
+ # hence this is using instance_eval with a string.
85
+ Savon::SOAP::XML.new.xml do |x|
86
+ x.user(:id => @id) do |u|
87
+ # email is special, so so so special.
88
+ u.email(self.email)
89
+
90
+ # base attributes of a user
91
+ [:title, :firstname, :lastname, :nickname, :dob_dd,
92
+ :dob_mm, :dob_yyyy,:countrycode,:languagecode].each do |field_name|
93
+ u.instance_eval "%s(obj[:%s])" % ([field_name]*2)
94
+ end
95
+
96
+ # cust_attr_X
97
+ 9.times.collect { |idx| "cust_attr_#{idx+1}" }.
98
+ each do |field_name|
99
+ u.instance_eval "%s(obj[:%s])" % ([field_name]*2)
100
+ end
101
+
102
+ # named attributes, these are generic and defined by some guy in a suit.
103
+ named_attrs.each do |key,value|
104
+ u.namedattr({:name => key}, value)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def self.group_id(group_obj_or_id)
113
+ (group_obj_or_id.is_a?(Ecircle::Group) ? group_obj_or_id.id : group_obj_or_id).to_s
114
+ end
115
+
116
+ def initialize_with_xml(xml_string)
117
+ init_with_xml("user", xml_string)
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,48 @@
1
+ require 'savon'
2
+ require 'nokogiri'
3
+ require 'net/http/post/multipart'
4
+ require 'uuidtools'
5
+ require 'base64'
6
+ require 'ostruct'
7
+
8
+ require 'ecircle/configuration'
9
+ require 'ecircle/client'
10
+ require 'ecircle/base'
11
+ require 'ecircle/member'
12
+ require 'ecircle/group'
13
+ require 'ecircle/user'
14
+ require 'ecircle/message'
15
+
16
+ # Helper for converting times to ecircle expected format.
17
+ module EcircleTimeHelper
18
+ def ecircle_format(prefix)
19
+ # ecircle uses JS month indices
20
+ strftime("yyyy:%Y,dd:%d,hh:%H,min:%M,ss:%S,mm:#{'%02d' % (month - 1)}").split(',').
21
+ inject({}) do |hsh, postfix_and_value|
22
+ postfix, value = postfix_and_value.split(':')
23
+ hsh.merge( "#{prefix}_#{postfix}".to_sym => value )
24
+ end
25
+ end
26
+ end
27
+
28
+ [Date, Time].each do |clazz|
29
+ clazz.send(:include, EcircleTimeHelper)
30
+ end
31
+
32
+ module Ecircle
33
+ extend self
34
+
35
+ def configuration
36
+ @configuration ||= Configuration.new
37
+ end
38
+
39
+ def client
40
+ @client ||= Client.new
41
+ end
42
+
43
+ def configure
44
+ config = configuration
45
+ block_given? ? yield(config) : config
46
+ config
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ original_load_path = $LOAD_PATH
14
+ dirs = ['ext', 'lib'].select { |dir| File.directory?(dir) }
15
+ $LOAD_PATH.unshift(*dirs)
16
+
17
+ require 'pry'
18
+ require 'ecircle_soap_client'
19
+
20
+ settings = YAML::load_file(File.join(File.dirname(__FILE__), 'test', '.login.yml'))
21
+ Ecircle.configure do |config|
22
+ config.user = settings["user"]
23
+ config.realm = settings["realm"]
24
+ config.password = settings["password"]
25
+ end
26
+ puts "*** Setup Ecircle"
27
+
28
+ Pry.editor = "emacs"
29
+ Pry.start
30
+
31
+ $LOAD_PATH.reject! { |path| !(original_load_path.include?(path)) }
@@ -0,0 +1,4 @@
1
+ ---
2
+ user: username
3
+ realm: http://example.com
4
+ password: password
data/test/helper.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ require 'test/unit'
13
+ require 'shoulda'
14
+ require 'yaml'
15
+ require 'rr'
16
+
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+
20
+ require 'ecircle_soap_client'
21
+
22
+ class Test::Unit::TestCase
23
+ include RR::Adapters::TestUnit
24
+
25
+ def _soap_fault(msg)
26
+ os = OpenStruct.new
27
+ os.body = Savon::SOAP::XML.new.xml do |x|
28
+ x.envelope do |e|
29
+ e.body do |b|
30
+ b.Fault do |f|
31
+ f.faultcode("client")
32
+ f.faultstring(msg)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ Savon::SOAP::Fault.new(os)
38
+ end
39
+
40
+ def mock_ecircle_client(create_client_object = false)
41
+ if create_client_object
42
+ client, req_obj = Ecircle::Client.new, Object.new
43
+ mock(client).client { req_obj }
44
+ # don't mock client since this will be used directly.
45
+ yield(client, mock(req_obj))
46
+ else
47
+ req_object = Object.new
48
+ mock(Ecircle).client { req_object }
49
+ yield(mock(req_object))
50
+ end
51
+ end
52
+
53
+ def in_soap_body
54
+ <<-SOAP
55
+ <?xml version="1.0" encoding="UTF-8"?>
56
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
57
+ <soapenv:Body>
58
+ #{yield}
59
+ </soapenv:Body>
60
+ </soapenv:Envelope>
61
+ SOAP
62
+ end
63
+
64
+ def mock_response(resp)
65
+ mock_ecircle_client(true) do |client, savon_client|
66
+ mock(Ecircle).client { client }
67
+ mock(client).logon { nil }
68
+ savon_client.request.with_any_args do
69
+ Savon::SOAP::Response.new(HTTPI::Response.new(200, {}, resp))
70
+ end
71
+ end
72
+ end
73
+
74
+ def config_soap_client
75
+ # keep login details separate from gem.
76
+ settings = begin
77
+ YAML::load_file(File.join(File.dirname(__FILE__), '.login.yml'))
78
+ rescue
79
+ puts "NO test/.login.yml --> copy the sample across to test"
80
+ exit 1
81
+ end
82
+
83
+ Ecircle.configure do |config|
84
+ config.user = settings["user"]
85
+ config.realm = settings["realm"]
86
+ config.password = settings["password"]
87
+ end
88
+ end
89
+
90
+ def assert_difference(expression, difference = 1, message = nil, &block)
91
+ b = block.send(:binding)
92
+ exps = Array.wrap(expression)
93
+ before = exps.map { |e| eval(e, b) }
94
+
95
+ yield
96
+
97
+ exps.each_with_index do |e, i|
98
+ error = "#{e.inspect} didn't change by #{difference}"
99
+ error = "#{message}.\n#{error}" if message
100
+ assert_equal(before[i] + difference, eval(e, b), error)
101
+ end
102
+ end
103
+ end
104
+
105
+ # Rails extension required for assert_difference (another rails extension)
106
+ class Array
107
+ def self.wrap(object)
108
+ if object.nil?
109
+ []
110
+ elsif object.respond_to?(:to_ary)
111
+ object.to_ary
112
+ else
113
+ [object]
114
+ end
115
+ end
116
+ end