sugarcrm 0.5.3 → 0.6.0

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