sugarcrm 0.5.3 → 0.6.0

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 (43) hide show
  1. data/README.rdoc +15 -10
  2. data/Rakefile +4 -1
  3. data/VERSION +1 -1
  4. data/lib/sugarcrm.rb +107 -119
  5. data/lib/sugarcrm/api/get_available_modules.rb +17 -0
  6. data/lib/sugarcrm/api/get_document_revision.rb +14 -0
  7. data/lib/sugarcrm/{get_entries.rb → api/get_entries.rb} +2 -2
  8. data/lib/sugarcrm/api/get_entries_count.rb +20 -0
  9. data/lib/sugarcrm/{get_entry.rb → api/get_entry.rb} +5 -8
  10. data/lib/sugarcrm/{get_entry_list.rb → api/get_entry_list.rb} +2 -2
  11. data/lib/sugarcrm/{get_module_fields.rb → api/get_module_fields.rb} +6 -3
  12. data/lib/sugarcrm/api/get_note_attachment.rb +15 -0
  13. data/lib/sugarcrm/{get_relationships.rb → api/get_relationship.rb} +9 -4
  14. data/lib/sugarcrm/api/get_report_entries.rb +19 -0
  15. data/lib/sugarcrm/api/get_server_info.rb +7 -0
  16. data/lib/sugarcrm/api/get_user_id.rb +13 -0
  17. data/lib/sugarcrm/api/get_user_team_id.rb +14 -0
  18. data/lib/sugarcrm/api/login.rb +18 -0
  19. data/lib/sugarcrm/api/logout.rb +15 -0
  20. data/lib/sugarcrm/api/seamless_login.rb +13 -0
  21. data/lib/sugarcrm/api/search_by_module.rb +24 -0
  22. data/lib/sugarcrm/api/set_campaign_merge.rb +15 -0
  23. data/lib/sugarcrm/api/set_document_revision.rb +15 -0
  24. data/lib/sugarcrm/api/set_entries.rb +15 -0
  25. data/lib/sugarcrm/api/set_entry.rb +15 -0
  26. data/lib/sugarcrm/api/set_note_attachment.rb +3 -0
  27. data/lib/sugarcrm/api/set_relationship.rb +18 -0
  28. data/lib/sugarcrm/api/set_relationships.rb +22 -0
  29. data/lib/sugarcrm/connection.rb +112 -0
  30. data/lib/sugarcrm/exceptions.rb +16 -0
  31. data/lib/sugarcrm/module.rb +11 -0
  32. data/lib/sugarcrm/request.rb +28 -0
  33. data/lib/sugarcrm/response.rb +29 -0
  34. data/test/helper.rb +5 -0
  35. data/test/test_connection.rb +60 -0
  36. data/test/test_response.rb +36 -0
  37. data/test/test_sugarcrm.rb +31 -45
  38. metadata +56 -17
  39. data/lib/net/http_digest_auth.rb +0 -44
  40. data/lib/stdlib/array.rb +0 -14
  41. data/lib/stdlib/hash.rb +0 -17
  42. data/lib/stdlib/object.rb +0 -5
  43. data/test/test_json_to_obj.rb +0 -48
@@ -0,0 +1,29 @@
1
+ module SugarCRM
2
+ # takes a raw JSON response and turns it into a REAL object
3
+ class Response
4
+
5
+ attr :response, false
6
+ attr :module, false
7
+ attr :attributes, false
8
+ attr :object, false
9
+ attr :id, false
10
+
11
+ def initialize(json)
12
+ @response = json
13
+ @module = @response["entry_list"][0]["module_name"].singularize
14
+ @attributes = flatten(@response["entry_list"][0]["name_value_list"])
15
+ @object = SugarCRM.const_get(@module).new(@attributes) if SugarCRM.const_get(@module)
16
+ end
17
+
18
+ # Takes a hash like { "first_name" => {"name" => "first_name", "value" => "John"}}
19
+ # And flattens it into {"first_name" => "John"}
20
+ def flatten(list)
21
+ raise ArgumentError, 'method parameter must respond to #each_pair' unless list.respond_to? :each_pair
22
+ flat_list = {}
23
+ list.each_pair do |k,v|
24
+ flat_list[k.to_sym] = v["value"]
25
+ end
26
+ flat_list
27
+ end
28
+ end
29
+ end
data/test/helper.rb CHANGED
@@ -7,4 +7,9 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
7
  require 'sugarcrm'
8
8
 
9
9
  class Test::Unit::TestCase
10
+ # Replace these with your test instance
11
+ URL = "http://valet/sugarcrm6"
12
+ USER = "admin"
13
+ PASS = 'letmein'
14
+ CRM = SugarCRM::Base.establish_connection(URL, USER, PASS, {:debug => true})
10
15
  end
@@ -0,0 +1,60 @@
1
+ require 'helper'
2
+ require "test/unit"
3
+ require "pp"
4
+
5
+ class TestSugarcrm < Test::Unit::TestCase
6
+ context "A SugarCRM::Connection instance" do
7
+
8
+ setup do
9
+ @connection = SugarCRM::Connection.new(URL, USER, PASS, false)
10
+ end
11
+
12
+ should "login and set session id" do
13
+ assert_not_nil @connection.session
14
+ end
15
+
16
+ should "retrieve the list of available modules" do
17
+ assert_instance_of Array, @connection.modules
18
+ end
19
+
20
+ should "create sub-classes by module name" do
21
+ assert SugarCRM.const_defined? "User"
22
+ end
23
+
24
+ should "return a single entry when sent #get_entry." do
25
+ response = @connection.get_entry(
26
+ "Users",
27
+ 1,
28
+ {:fields => ["first_name", "last_name"]}
29
+ )
30
+ assert response.response.key? "entry_list"
31
+ end
32
+
33
+ should "return a list of entries when sent #get_entries." do
34
+ response = @connection.get_entries(
35
+ "Users",
36
+ [1],
37
+ {:fields => ["first_name", "last_name"]}
38
+ )
39
+ assert response.key? "entry_list"
40
+ end
41
+
42
+ should "return a list of entries when sent #get_entry_list." do
43
+ response = @connection.get_entry_list(
44
+ "Users",
45
+ "users.user_name = \'#{USER}\'",
46
+ {
47
+ :fields => ["first_name", "last_name"],
48
+ :link_fields => [
49
+ {
50
+ "name" => "accounts",
51
+ "value" => ["id", "name"]
52
+ }
53
+ ]
54
+ }
55
+ )
56
+ assert response.key? "entry_list"
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+ require "test/unit"
3
+ require "pp"
4
+
5
+ class TestSugarcrm < Test::Unit::TestCase
6
+ context "A SugarCRM::Response instance" do
7
+ setup do
8
+ @json = {"entry_list"=> [{
9
+ "name_value_list"=> {
10
+ "address_city" => {"name"=>"address_city", "value"=>""},
11
+ "receive_notifications" => {"name"=>"receive_notifications", "value"=>"1"},
12
+ "is_group" => {"name"=>"is_group", "value"=>"0"},
13
+ "pwd_last_changed" => {"name"=>"pwd_last_changed", "value"=>"never"}
14
+ },
15
+ "id"=>"1",
16
+ "module_name"=>"Users"
17
+ }],
18
+ "relationship_list"=>[]}
19
+
20
+ @response = SugarCRM::Response.new(@json)
21
+ end
22
+
23
+ should "set the module name" do
24
+ assert_equal "User", @response.module
25
+ end
26
+
27
+ should "flatten the name_value_list into an attributes hash" do
28
+ assert_equal "never", @response.attributes[:pwd_last_changed]
29
+ end
30
+
31
+ should "return an instance of a SugarCRM Module when #object" do
32
+ assert_instance_of SugarCRM::User, @response.object
33
+ end
34
+
35
+ end
36
+ end
@@ -2,61 +2,47 @@ require 'helper'
2
2
  require "test/unit"
3
3
  require "pp"
4
4
 
5
- # Replace these with your test instance
6
- URL = "http://valet/sugarcrm"
7
- USER = "admin"
8
- PASS = 'letmein'
9
-
10
5
  class TestSugarcrm < Test::Unit::TestCase
11
- context "A SugarCRM::Base instance" do
12
- setup do
13
- @sugarcrm = SugarCRM::Base.new(URL, USER, PASS, {:debug => true})
6
+ context "A SugarCRM::Module instance" do
7
+
8
+ should "return the module name" do
9
+ assert_equal "Users", SugarCRM::User.module_name
14
10
  end
15
11
 
16
- should "return a single entry in JSON format when option :to_obj => false" do
17
- @test = SugarCRM::Base.new(URL, USER, PASS, {:debug => true, :to_obj => false})
18
- response = @test.get_entry(
19
- "Users",
20
- 1,
21
- {:fields => ["first_name", "last_name"]}
22
- )
23
- assert_kind_of Hash, response
12
+ should "respond to self.connection" do
13
+ assert_respond_to SugarCRM::User, :connection
14
+ assert_instance_of SugarCRM::Connection, SugarCRM::User.connection
24
15
  end
25
16
 
26
- should "return a single entry when sent #get_entry." do
27
- response = @sugarcrm.get_entry(
28
- "Users",
29
- 1,
30
- {:fields => ["first_name", "last_name"]}
31
- )
32
- assert_respond_to 'response', :entry_list
17
+ should "respond to self.register_module_fields" do
18
+ assert_respond_to SugarCRM::User, :register_module_fields
19
+ SugarCRM::User.register_module_fields
20
+ assert SugarCRM::User.module_fields.length > 0
33
21
  end
34
22
 
35
- should "return a list of entries when sent #get_entries." do
36
- response = @sugarcrm.get_entries(
37
- "Users",
38
- [1],
39
- {:fields => ["first_name", "last_name"]}
40
- )
41
- assert_respond_to 'response', :entry_list
23
+ should "respond to self.connection.logged_in?" do
24
+ assert SugarCRM::User.connection.logged_in?
25
+ end
26
+
27
+ should "return an instance of itself when #new" do
28
+ assert_instance_of SugarCRM::User, SugarCRM::User.new
42
29
  end
43
30
 
44
- should "return a list of entries when sent #get_entry_list." do
45
- response = @sugarcrm.get_entry_list(
46
- "Users",
47
- "users.user_name = \'#{USER}\'",
48
- {
49
- :fields => ["first_name", "last_name"],
50
- :link_fields => [
51
- {
52
- "name" => "accounts",
53
- "value" => ["id", "name"]
54
- }
55
- ]
56
- }
57
- )
58
- assert_respond_to 'response', :entry_list
31
+ should "define instance level attributes when #new" do
32
+ u = SugarCRM::User.new
33
+ assert SugarCRM::User.attribute_methods_generated
34
+ end
35
+
36
+ should "respond to attributes derived from module_fields" do
37
+ u = SugarCRM::User.new
38
+ u.last_name = "Test"
39
+ assert_equal "Test", u.last_name
59
40
  end
60
41
 
42
+ should "return an an instance of itself when sent #find(id)" do
43
+ u = SugarCRM::User.find(1)
44
+ assert_instance_of SugarCRM::User, u
45
+ end
61
46
  end
47
+
62
48
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sugarcrm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 3
10
- version: 0.5.3
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Carl Hicks
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-16 00:00:00 -07:00
18
+ date: 2010-08-08 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -46,7 +46,24 @@ dependencies:
46
46
  version: "0"
47
47
  type: :runtime
48
48
  version_requirements: *id002
49
- description: A Ruby based REST client for SugarCRM.
49
+ - !ruby/object:Gem::Dependency
50
+ name: activesupport
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: |-
64
+ I've implemented all of the basic API calls that SugarCRM supports, and am actively building an abstraction layer
65
+ on top of the basic API methods. The end result will be to provide ActiveRecord style finders and first class
66
+ objects. Some of this functionality is included today.
50
67
  email: carl.hicks@gmail.com
51
68
  executables: []
52
69
 
@@ -62,18 +79,39 @@ files:
62
79
  - README.rdoc
63
80
  - Rakefile
64
81
  - VERSION
65
- - lib/net/http_digest_auth.rb
66
- - lib/stdlib/array.rb
67
- - lib/stdlib/hash.rb
68
- - lib/stdlib/object.rb
69
82
  - lib/sugarcrm.rb
70
- - lib/sugarcrm/get_entries.rb
71
- - lib/sugarcrm/get_entry.rb
72
- - lib/sugarcrm/get_entry_list.rb
73
- - lib/sugarcrm/get_module_fields.rb
74
- - lib/sugarcrm/get_relationships.rb
83
+ - lib/sugarcrm/api/get_available_modules.rb
84
+ - lib/sugarcrm/api/get_document_revision.rb
85
+ - lib/sugarcrm/api/get_entries.rb
86
+ - lib/sugarcrm/api/get_entries_count.rb
87
+ - lib/sugarcrm/api/get_entry.rb
88
+ - lib/sugarcrm/api/get_entry_list.rb
89
+ - lib/sugarcrm/api/get_module_fields.rb
90
+ - lib/sugarcrm/api/get_note_attachment.rb
91
+ - lib/sugarcrm/api/get_relationship.rb
92
+ - lib/sugarcrm/api/get_report_entries.rb
93
+ - lib/sugarcrm/api/get_server_info.rb
94
+ - lib/sugarcrm/api/get_user_id.rb
95
+ - lib/sugarcrm/api/get_user_team_id.rb
96
+ - lib/sugarcrm/api/login.rb
97
+ - lib/sugarcrm/api/logout.rb
98
+ - lib/sugarcrm/api/seamless_login.rb
99
+ - lib/sugarcrm/api/search_by_module.rb
100
+ - lib/sugarcrm/api/set_campaign_merge.rb
101
+ - lib/sugarcrm/api/set_document_revision.rb
102
+ - lib/sugarcrm/api/set_entries.rb
103
+ - lib/sugarcrm/api/set_entry.rb
104
+ - lib/sugarcrm/api/set_note_attachment.rb
105
+ - lib/sugarcrm/api/set_relationship.rb
106
+ - lib/sugarcrm/api/set_relationships.rb
107
+ - lib/sugarcrm/connection.rb
108
+ - lib/sugarcrm/exceptions.rb
109
+ - lib/sugarcrm/module.rb
110
+ - lib/sugarcrm/request.rb
111
+ - lib/sugarcrm/response.rb
75
112
  - test/helper.rb
76
- - test/test_json_to_obj.rb
113
+ - test/test_connection.rb
114
+ - test/test_response.rb
77
115
  - test/test_sugarcrm.rb
78
116
  has_rdoc: true
79
117
  homepage: http://github.com/chicks/sugarcrm
@@ -111,5 +149,6 @@ specification_version: 3
111
149
  summary: Ruby based REST client for SugarCRM
112
150
  test_files:
113
151
  - test/helper.rb
114
- - test/test_json_to_obj.rb
152
+ - test/test_connection.rb
153
+ - test/test_response.rb
115
154
  - test/test_sugarcrm.rb
@@ -1,44 +0,0 @@
1
- # net_http_digest_auth.rb
2
- require 'digest/md5'
3
- require 'net/http'
4
-
5
- module Net
6
- module HTTPHeader
7
- @@nonce_count = -1
8
- CNONCE = Digest::MD5.new.update("%x" % (Time.now.to_i + rand(65535))).hexdigest
9
- def digest_auth(user, password, response)
10
- # based on http://segment7.net/projects/ruby/snippets/digest_auth.rb
11
- @@nonce_count += 1
12
-
13
- response['www-authenticate'] =~ /^(\w+) (.*)/
14
-
15
- params = {}
16
- $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
17
-
18
- a_1 = "#{user}:#{params['realm']}:#{password}"
19
- a_2 = "#{@method}:#{@path}"
20
- request_digest = ''
21
- request_digest << Digest::MD5.new.update(a_1).hexdigest
22
- request_digest << ':' << params['nonce']
23
- request_digest << ':' << ('%08x' % @@nonce_count)
24
- request_digest << ':' << CNONCE
25
- request_digest << ':' << params['qop']
26
- request_digest << ':' << Digest::MD5.new.update(a_2).hexdigest
27
-
28
- header = []
29
- header << "Digest username=\"#{user}\""
30
- header << "realm=\"#{params['realm']}\""
31
-
32
- header << "qop=#{params['qop']}"
33
-
34
- header << "algorithm=MD5"
35
- header << "uri=\"#{@path}\""
36
- header << "nonce=\"#{params['nonce']}\""
37
- header << "nc=#{'%08x' % @@nonce_count}"
38
- header << "cnonce=\"#{CNONCE}\""
39
- header << "response=\"#{Digest::MD5.new.update(request_digest).hexdigest}\""
40
-
41
- @header['Authorization'] = header
42
- end
43
- end
44
- end
data/lib/stdlib/array.rb DELETED
@@ -1,14 +0,0 @@
1
- # A fancy way of iterating over an array and converting hashes to objects
2
- class Array
3
- def to_obj
4
- # Make a deep copy of the array
5
- a = Marshal.load(Marshal.dump(self))
6
- a.each do |i|
7
- case i.class.to_s
8
- when "Hash" then i = i.to_obj
9
- when "Array" then i = i.to_obj
10
- end
11
- end
12
- a
13
- end
14
- end
data/lib/stdlib/hash.rb DELETED
@@ -1,17 +0,0 @@
1
- # A fancy way of iterating over a hash and converting hashes to objects
2
- class Hash
3
- def to_obj
4
- o = Object.new
5
- self.each do |k,v|
6
- # If we're looking at a hash or array, we need to look through them and convert any hashes to objects as well
7
- case v.class.to_s
8
- when "Hash" then v = v.to_obj
9
- when "Array" then v = v.to_obj
10
- end
11
- o.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
12
- o.class.send(:define_method, k, proc{o.instance_variable_get("@#{k}")}) ## create the getter that returns the instance variable
13
- o.class.send(:define_method, "#{k}=", proc{|v| o.instance_variable_set("@#{k}", v)}) ## create the setter that sets the instance variable
14
- end
15
- o
16
- end
17
- end
data/lib/stdlib/object.rb DELETED
@@ -1,5 +0,0 @@
1
- class Object
2
- def to_obj
3
- self
4
- end
5
- end
@@ -1,48 +0,0 @@
1
- require 'helper'
2
-
3
- class TestJson2Object < Test::Unit::TestCase
4
- def test_object
5
- json = {"string" => "value"}.to_json
6
- obj = JSON.parse(json).to_obj
7
- assert_equal("value", obj.string)
8
- end
9
-
10
- def test_nested_object
11
- json = {"dogs" => {"retriever" => "sparky", "basset" => "jennie", "pinscher" => "carver"}}.to_json
12
- obj = JSON.parse(json).to_obj
13
- assert_equal("sparky", obj.dogs.retriever)
14
- end
15
-
16
- def test_array_of_objects
17
- json = [{"retriever" => "sparky"}, {"basset" => "jennie"}, {"pinscher" => "carver"}].to_json
18
- obj = JSON.parse(json).to_obj
19
- assert_equal("sparky", obj[0].retriever)
20
- end
21
-
22
- def test_deep_nest_mixed
23
- json = {"kennels" => [
24
- {"dallas" => [
25
- {"name" => "north"},
26
- {"name" => "east"},
27
- ]},
28
- {"frisco" => [
29
- {"name" => "south"},
30
- {"name" => "west"}
31
- ],
32
- "company" => "Doggie Daze"
33
- }
34
- ]}.to_json
35
- obj = JSON.parse(json).to_obj
36
- assert_equal("west", obj.kennels[1].frisco[0].name)
37
- end
38
-
39
- def test_deep_nest_hash
40
- json = {"kennels" => {
41
- "kennel" => {
42
- "dallas" => ["north", "south"],
43
- "frisco" => ["east", "west"]}}
44
- }.to_json
45
- obj = JSON.parse(json).to_obj
46
- assert_equal("north", obj.kennels.kennel.dallas[0])
47
- end
48
- end