sugarcrm 0.7.9 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +25 -6
- data/VERSION +1 -1
- data/lib/sugarcrm.rb +1 -0
- data/lib/sugarcrm/association_methods.rb +6 -5
- data/lib/sugarcrm/attribute_methods.rb +104 -1
- data/lib/sugarcrm/base.rb +37 -6
- data/lib/sugarcrm/connection.rb +4 -0
- data/lib/sugarcrm/connection/api/get_entries.rb +2 -1
- data/lib/sugarcrm/connection/api/get_entries_count.rb +3 -1
- data/lib/sugarcrm/connection/api/get_entry.rb +2 -1
- data/lib/sugarcrm/connection/api/get_entry_list.rb +3 -3
- data/lib/sugarcrm/connection/api/search_by_module.rb +6 -5
- data/lib/sugarcrm/connection/helper.rb +6 -1
- data/lib/sugarcrm/exceptions.rb +3 -0
- data/lib/sugarcrm/module.rb +10 -0
- data/lib/sugarcrm/module_methods.rb +6 -0
- data/lib/sugarcrm/response.rb +11 -7
- data/test/connection/test_get_entry.rb +3 -0
- data/test/helper.rb +1 -1
- data/test/test_module.rb +4 -0
- data/test/test_sugarcrm.rb +33 -3
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -12,14 +12,15 @@ RubyGem for interacting with SugarCRM via REST.
|
|
12
12
|
|
13
13
|
A less clunky way to interact with SugarCRM via REST.
|
14
14
|
|
15
|
-
I've built an abstraction layer on top of the SugarCRM REST API, instead of
|
16
|
-
call
|
15
|
+
I've built an abstraction layer on top of the SugarCRM REST API, instead of get_entry("Users", "1") you can
|
16
|
+
call SugarCRM::User.find(1). There is also support for collections à la SugarCRM::User.find(1).email_addresses.
|
17
17
|
ActiveRecord style finders are in place, with limited support for conditions and joins
|
18
|
-
e.g.
|
18
|
+
e.g. SugarCRM::Contacts.find_by_title("VP of Sales") will work, but SugarCRM::Contacts.find_by_title("VP of Sales", {:conditions => {:deleted => 0}}) will not.
|
19
19
|
|
20
20
|
== FEATURES/PROBLEMS:
|
21
21
|
|
22
22
|
* Supports all v2 API calls
|
23
|
+
* Supports saving of Module specific objects.
|
23
24
|
* Auto-generation of Module specific objects. When a connection is established, get_available_modules is called and the resultant modules are turned into SugarCRM::Module classes.
|
24
25
|
* If you just want to use the vanilla API, you can access the methods directly on the SugarCRM.connection object.
|
25
26
|
|
@@ -28,7 +29,10 @@ e.g. +SugarCRM::Contacts.find_by_title("VP of Sales")+ will work, but +SugarCRM:
|
|
28
29
|
require 'sugarcrm'
|
29
30
|
|
30
31
|
# Establish a connection
|
31
|
-
SugarCRM
|
32
|
+
SugarCRM.connect("http://localhost/sugarcrm", 'user', 'password')
|
33
|
+
|
34
|
+
# Enable debugging on the current connection
|
35
|
+
SugarCRM.connection.debug = true
|
32
36
|
|
33
37
|
# Get the logged in user
|
34
38
|
SugarCRM.current_user
|
@@ -38,9 +42,24 @@ e.g. +SugarCRM::Contacts.find_by_title("VP of Sales")+ will work, but +SugarCRM:
|
|
38
42
|
|
39
43
|
# Retrieve a User by user_name
|
40
44
|
SugarCRM::User.find_by_user_name("admin")
|
45
|
+
|
46
|
+
# Update a User's title
|
47
|
+
u = SugarCRM::User.find_by_first_name_and_last_name("Will", "Westin")
|
48
|
+
u.title = "Sales Manager Central"
|
49
|
+
u.save
|
50
|
+
|
51
|
+
# Check if an object is valid (i.e. if it has the required fields to save)
|
52
|
+
u.valid?
|
53
|
+
|
54
|
+
# Access the errors collection
|
55
|
+
u.errors
|
56
|
+
|
57
|
+
# Delete an Account
|
58
|
+
a = SugarCRM::Account.find_by_name("JAB Funds Ltd.")
|
59
|
+
a.delete
|
41
60
|
|
42
|
-
# Retrieve all
|
43
|
-
SugarCRM::User.find_by_user_name('sarah').
|
61
|
+
# Retrieve all Email Addresses assigned to a particular user.
|
62
|
+
SugarCRM::User.find_by_user_name('sarah').email_addresses
|
44
63
|
|
45
64
|
# Retrieve all email addresses on an Account
|
46
65
|
SugarCRM::Account.find_by_name("JAB Funds Ltd.").contacts.each do |contact|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/lib/sugarcrm.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module SugarCRM; module AssociationMethods
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module ClassMethods
|
4
|
+
# Returns an array of the module link fields
|
5
|
+
def associations_from_module_link_fields
|
6
|
+
self._module.link_fields.keys
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
8
10
|
# Generates the association proxy methods for related modules
|
@@ -30,8 +32,7 @@ module SugarCRM; module AssociationMethods
|
|
30
32
|
# "type"=>"link"},
|
31
33
|
#
|
32
34
|
def query_association(association)
|
33
|
-
|
34
|
-
objects = SugarCRM.connection.get_relationships(
|
35
|
+
collection = SugarCRM.connection.get_relationships(
|
35
36
|
self.class._module.name,
|
36
37
|
self.id,
|
37
38
|
association.to_s
|
@@ -3,13 +3,95 @@ module SugarCRM; module AttributeMethods
|
|
3
3
|
module ClassMethods
|
4
4
|
# Returns a hash of the module fields from the module
|
5
5
|
def attributes_from_module_fields
|
6
|
-
fields = {}
|
6
|
+
fields = {}.with_indifferent_access
|
7
7
|
self._module.fields.keys.sort.each do |k|
|
8
8
|
fields[k.to_s] = nil
|
9
9
|
end
|
10
10
|
fields
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
# Determines if attributes have been changed
|
15
|
+
def changed?
|
16
|
+
@modified_attributes.length > 0
|
17
|
+
end
|
18
|
+
|
19
|
+
# Is this a new record?
|
20
|
+
def new?
|
21
|
+
@id.blank?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Converts the attributes hash into format recognizable by Sugar
|
25
|
+
# { :last_name => "Smith"}
|
26
|
+
# becomes
|
27
|
+
# { :last_name => {:name => "last_name", :value => "Smith"}}
|
28
|
+
def serialize_attributes
|
29
|
+
attr_hash = {}
|
30
|
+
@attributes.each_pair do |name,value|
|
31
|
+
attr_hash[name] = serialize_attribute(name,value)
|
32
|
+
end
|
33
|
+
attr_hash[:id] = serialize_id unless new?
|
34
|
+
attr_hash
|
35
|
+
end
|
36
|
+
|
37
|
+
# Converts the modified_attributes hash into format recognizable by Sugar
|
38
|
+
# { :last_name => {:old => "Smit", :new => "Smith"}}
|
39
|
+
# becomes
|
40
|
+
# { :last_name => {:name => "last_name", :value => "Smith"}}
|
41
|
+
def serialize_modified_attributes
|
42
|
+
attr_hash = {}
|
43
|
+
@modified_attributes.each_pair do |name,hash|
|
44
|
+
attr_hash[name] = serialize_attribute(name,hash[:new])
|
45
|
+
end
|
46
|
+
attr_hash[:id] = serialize_id unless new?
|
47
|
+
attr_hash
|
48
|
+
end
|
49
|
+
|
50
|
+
# Checks to see if we have all the neccessary attributes
|
51
|
+
def valid?
|
52
|
+
valid = true
|
53
|
+
self.class._module.required_fields.each do |attribute|
|
54
|
+
case attr_type_for(attribute)
|
55
|
+
when "bool"
|
56
|
+
case @attributes[attribute]
|
57
|
+
when TrueClass:
|
58
|
+
next
|
59
|
+
when FalseClass:
|
60
|
+
next
|
61
|
+
else
|
62
|
+
@errors.add "#{attribute} must be true or false"
|
63
|
+
valid = false
|
64
|
+
end
|
65
|
+
else
|
66
|
+
if @attributes[attribute].blank?
|
67
|
+
@errors.add "#{attribute} cannot be blank"
|
68
|
+
valid = false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
valid
|
73
|
+
end
|
74
|
+
|
75
|
+
# List the required attributes for save
|
76
|
+
def required_attributes
|
77
|
+
self.class._module.required_fields
|
78
|
+
end
|
79
|
+
|
80
|
+
# Serializes the id
|
81
|
+
def serialize_id
|
82
|
+
{:name => "id", :value => @id.to_s}
|
83
|
+
end
|
84
|
+
|
85
|
+
# Un-typecasts the attribute - false becomes 0
|
86
|
+
def serialize_attribute(name,value)
|
87
|
+
attr_value = value
|
88
|
+
case attr_type_for(name)
|
89
|
+
when "bool"
|
90
|
+
attr_value = 0
|
91
|
+
attr_value = 1 if value
|
92
|
+
end
|
93
|
+
{:name => name, :value => attr_value}
|
94
|
+
end
|
13
95
|
|
14
96
|
# Generates get/set methods for keys in the attributes hash
|
15
97
|
def define_attribute_methods
|
@@ -52,6 +134,26 @@ module SugarCRM; module AttributeMethods
|
|
52
134
|
end
|
53
135
|
|
54
136
|
protected
|
137
|
+
|
138
|
+
# Returns the attribute type for a given attribute
|
139
|
+
def attr_type_for(attribute)
|
140
|
+
field = self.class._module.fields[attribute]
|
141
|
+
return false unless field
|
142
|
+
field["type"]
|
143
|
+
end
|
144
|
+
|
145
|
+
# Attempts to typecast each attribute based on the module field type
|
146
|
+
def typecast_attributes
|
147
|
+
@attributes.each_pair do |name,value|
|
148
|
+
attr_type = attr_type_for(name)
|
149
|
+
next unless attr_type
|
150
|
+
case attr_type
|
151
|
+
when "bool"
|
152
|
+
@attributes[name] = (value == "1")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
@attributes
|
156
|
+
end
|
55
157
|
|
56
158
|
# Wrapper around attributes hash
|
57
159
|
def read_attribute(key)
|
@@ -60,6 +162,7 @@ module SugarCRM; module AttributeMethods
|
|
60
162
|
|
61
163
|
# Wrapper around attributes hash
|
62
164
|
def write_attribute(key, value)
|
165
|
+
@modified_attributes[key] = { :old => @attributes[key].to_s, :new => value }
|
63
166
|
@attributes[key] = value
|
64
167
|
end
|
65
168
|
|
data/lib/sugarcrm/base.rb
CHANGED
@@ -4,7 +4,7 @@ require 'sugarcrm/association_methods'
|
|
4
4
|
module SugarCRM; class Base
|
5
5
|
|
6
6
|
# Unset all of the instance methods we don't need.
|
7
|
-
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^define_method$|^class$|^instance_of.$)/ }
|
7
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^define_method$|^class$|^methods$|^instance_of.$|^respond_to.$)/ }
|
8
8
|
|
9
9
|
# This holds our connection
|
10
10
|
cattr_accessor :connection, :instance_writer => false
|
@@ -21,9 +21,11 @@ module SugarCRM; class Base
|
|
21
21
|
|
22
22
|
# Contains a list of attributes
|
23
23
|
attr :attributes, true
|
24
|
+
attr :modified_attributes, true
|
24
25
|
attr :associations, true
|
25
26
|
attr :id, true
|
26
27
|
attr :debug, true
|
28
|
+
attr :errors, true
|
27
29
|
|
28
30
|
class << self # Class methods
|
29
31
|
def establish_connection(url, user, pass, opts={})
|
@@ -74,7 +76,7 @@ module SugarCRM; class Base
|
|
74
76
|
|
75
77
|
case ids.size
|
76
78
|
when 0
|
77
|
-
raise RecordNotFound, "Couldn't find #{name} without an ID"
|
79
|
+
raise RecordNotFound, "Couldn't find #{self._module.name} without an ID"
|
78
80
|
when 1
|
79
81
|
result = find_one(ids.first, options)
|
80
82
|
expects_array ? [ result ] : result
|
@@ -124,6 +126,8 @@ module SugarCRM; class Base
|
|
124
126
|
end
|
125
127
|
|
126
128
|
def query_from_options(options)
|
129
|
+
# If we dont have conditions, just return an empty query
|
130
|
+
return "" unless options[:conditions]
|
127
131
|
conditions = []
|
128
132
|
options[:conditions].each_pair do |column, value|
|
129
133
|
conditions << "#{self._module.table_name}.#{column} = \'#{value}\'"
|
@@ -282,9 +286,13 @@ module SugarCRM; class Base
|
|
282
286
|
def initialize(id=nil, attributes={})
|
283
287
|
@id = id
|
284
288
|
@attributes = self.class.attributes_from_module_fields.merge(attributes)
|
285
|
-
@
|
289
|
+
@modified_attributes = {}
|
290
|
+
@associations = self.class.associations_from_module_link_fields
|
291
|
+
@errors = Set.new
|
286
292
|
define_attribute_methods
|
287
293
|
define_association_methods
|
294
|
+
typecast_attributes
|
295
|
+
self
|
288
296
|
end
|
289
297
|
|
290
298
|
def inspect
|
@@ -293,16 +301,38 @@ module SugarCRM; class Base
|
|
293
301
|
|
294
302
|
def to_s
|
295
303
|
attrs = []
|
296
|
-
@attributes.
|
297
|
-
|
304
|
+
@attributes.keys.sort.each do |k|
|
305
|
+
attrs << "#{k}: #{attribute_for_inspect(k)}"
|
298
306
|
end
|
299
307
|
"#<#{self.class} #{attrs.join(", ")}>"
|
300
308
|
end
|
301
309
|
|
310
|
+
# Saves the current object, checks that required fields are present.
|
311
|
+
# returns true or false
|
302
312
|
def save
|
303
|
-
|
313
|
+
return false unless changed?
|
314
|
+
return false unless valid?
|
315
|
+
# If we get a Hash back, return true. Otherwise return false.
|
316
|
+
(SugarCRM.connection.set_entry(self.class._module.name, serialize_modified_attributes).class == Hash)
|
317
|
+
end
|
318
|
+
|
319
|
+
# Saves the current object, checks that required fields are present.
|
320
|
+
# raises an exception if a save fails
|
321
|
+
def save!
|
322
|
+
raise InvalidRecord, errors.to_a.join(", ") unless valid?
|
323
|
+
# If we get a Hash back, return true. Otherwise return false.
|
324
|
+
(SugarCRM.connection.set_entry(self.class._module.name, serialize_modified_attributes).class == Hash)
|
304
325
|
end
|
305
326
|
|
327
|
+
def delete
|
328
|
+
return false if @id.blank?
|
329
|
+
params = {}
|
330
|
+
params[:id] = serialize_id
|
331
|
+
params[:deleted]= {:name => "deleted", :value => "1"}
|
332
|
+
(SugarCRM.connection.set_entry(self.class._module.name, params).class == Hash)
|
333
|
+
end
|
334
|
+
|
335
|
+
|
306
336
|
# Wrapper around class attribute
|
307
337
|
def attribute_methods_generated?
|
308
338
|
self.class.attribute_methods_generated
|
@@ -316,6 +346,7 @@ module SugarCRM; class Base
|
|
316
346
|
include AttributeMethods
|
317
347
|
extend AttributeMethods::ClassMethods
|
318
348
|
include AssociationMethods
|
349
|
+
extend AssociationMethods::ClassMethods
|
319
350
|
end
|
320
351
|
|
321
352
|
end; end
|
data/lib/sugarcrm/connection.rb
CHANGED
@@ -2,7 +2,9 @@ module SugarCRM; class Connection
|
|
2
2
|
# Retrieves the specified number of records in a module.
|
3
3
|
def get_entries_count(module_name, query, opts={})
|
4
4
|
login! unless logged_in?
|
5
|
-
options = {
|
5
|
+
options = {
|
6
|
+
:deleted => 0
|
7
|
+
}.merge! opts
|
6
8
|
|
7
9
|
json = <<-EOF
|
8
10
|
{
|
@@ -8,8 +8,8 @@ def get_entry_list(module_name, query, opts={})
|
|
8
8
|
:offset => '',
|
9
9
|
:fields => [],
|
10
10
|
:link_fields => [],
|
11
|
-
:
|
12
|
-
:deleted =>
|
11
|
+
:limit => '',
|
12
|
+
:deleted => 0
|
13
13
|
}.merge! opts
|
14
14
|
|
15
15
|
json = <<-EOF
|
@@ -21,7 +21,7 @@ def get_entry_list(module_name, query, opts={})
|
|
21
21
|
\"offset\": \"#{options[:offset]}\"\,
|
22
22
|
\"select_fields\": #{resolve_fields(module_name, options[:fields])}\,
|
23
23
|
\"link_name_to_fields_array\": #{options[:link_fields].to_json}\,
|
24
|
-
\"max_results\": \"#{options[:
|
24
|
+
\"max_results\": \"#{options[:limit]}\"\,
|
25
25
|
\"deleted\": #{options[:deleted]}
|
26
26
|
}
|
27
27
|
EOF
|
@@ -2,12 +2,13 @@ module SugarCRM; class Connection
|
|
2
2
|
# Returns the ID, module name and fields for specified modules.
|
3
3
|
# Supported modules are Accounts, Bugs, Calls, Cases, Contacts,
|
4
4
|
# Leads, Opportunities, Projects, Project Tasks, and Quotes.
|
5
|
-
def search_by_module(search_string, modules,
|
5
|
+
def search_by_module(search_string, modules, ops={})
|
6
6
|
login! unless logged_in?
|
7
7
|
|
8
|
-
|
9
|
-
:
|
10
|
-
|
8
|
+
options = {
|
9
|
+
:offset => nil,
|
10
|
+
:limit => nil,
|
11
|
+
}.merge! opts
|
11
12
|
|
12
13
|
json = <<-EOF
|
13
14
|
{
|
@@ -15,7 +16,7 @@ module SugarCRM; class Connection
|
|
15
16
|
\"search_string\": \"#{search_string}\"\,
|
16
17
|
\"modules\": \"#{modules}\"\,
|
17
18
|
\"offset\": #{options[:offset]}\,
|
18
|
-
\"max_results\": #{options[:
|
19
|
+
\"max_results\": #{options[:limit]}
|
19
20
|
}
|
20
21
|
EOF
|
21
22
|
json.gsub!(/^\s{6}/,'')
|
@@ -3,7 +3,12 @@ module SugarCRM; class Connection
|
|
3
3
|
# FIXME: This is to work around a bug in SugarCRM 6.0
|
4
4
|
# where no fields are returned if no fields are specified
|
5
5
|
if fields.length == 0
|
6
|
-
|
6
|
+
mod = Module.find(module_name)
|
7
|
+
if mod
|
8
|
+
fields = mod.fields.keys
|
9
|
+
else
|
10
|
+
fields = "id"
|
11
|
+
end
|
7
12
|
end
|
8
13
|
return fields.to_json
|
9
14
|
end
|
data/lib/sugarcrm/exceptions.rb
CHANGED
data/lib/sugarcrm/module.rb
CHANGED
@@ -33,6 +33,16 @@ module SugarCRM
|
|
33
33
|
@fields_registered
|
34
34
|
end
|
35
35
|
|
36
|
+
def required_fields
|
37
|
+
required_fields = []
|
38
|
+
ignore_fields = ["id", "date_entered", "date_modified"]
|
39
|
+
self.fields.each_value do |field|
|
40
|
+
next if ignore_fields.include? field["name"]
|
41
|
+
required_fields << field["name"] if field["required"] == 1
|
42
|
+
end
|
43
|
+
required_fields
|
44
|
+
end
|
45
|
+
|
36
46
|
def link_fields
|
37
47
|
self.fields unless link_fields?
|
38
48
|
handle_empty_array
|
@@ -7,6 +7,12 @@ module SugarCRM
|
|
7
7
|
def self.connection=(connection)
|
8
8
|
@@connection = connection
|
9
9
|
end
|
10
|
+
def self.connect(url, user, pass, options={})
|
11
|
+
SugarCRM::Base.establish_connection(url, user, pass, options)
|
12
|
+
end
|
13
|
+
class << self
|
14
|
+
alias :connect! :connect
|
15
|
+
end
|
10
16
|
|
11
17
|
@@modules = []
|
12
18
|
def self.modules
|
data/lib/sugarcrm/response.rb
CHANGED
@@ -8,7 +8,12 @@ module SugarCRM; class Response
|
|
8
8
|
r = new(json)
|
9
9
|
begin
|
10
10
|
return r.to_obj
|
11
|
-
rescue
|
11
|
+
rescue => e
|
12
|
+
if SugarCRM.connection.debug?
|
13
|
+
puts "Failed to process JSON:"
|
14
|
+
pp json
|
15
|
+
puts e
|
16
|
+
end
|
12
17
|
return json
|
13
18
|
end
|
14
19
|
end
|
@@ -23,18 +28,17 @@ module SugarCRM; class Response
|
|
23
28
|
# Tries to instantiate and return an object with the values
|
24
29
|
# populated from the response
|
25
30
|
def to_obj
|
31
|
+
# If this is not a "entry_list" response, just return
|
32
|
+
return @response unless @response["entry_list"]
|
33
|
+
|
26
34
|
objects = []
|
27
35
|
@response["entry_list"].each do |object|
|
28
36
|
attributes = []
|
29
37
|
_module = resolve_module(object)
|
30
38
|
id = object["id"]
|
31
|
-
|
32
|
-
attributes = flatten_name_value_list(object)
|
33
|
-
rescue ArgumentError => e
|
34
|
-
end
|
39
|
+
attributes = flatten_name_value_list(object)
|
35
40
|
if SugarCRM.const_get(_module)
|
36
41
|
if attributes.length == 0
|
37
|
-
pp object
|
38
42
|
raise AttributeParsingError, "response contains objects without attributes!"
|
39
43
|
end
|
40
44
|
objects << SugarCRM.const_get(_module).new(id, attributes)
|
@@ -53,7 +57,7 @@ module SugarCRM; class Response
|
|
53
57
|
def to_json
|
54
58
|
@response.to_json
|
55
59
|
end
|
56
|
-
|
60
|
+
|
57
61
|
def resolve_module(list)
|
58
62
|
list["module_name"].classify
|
59
63
|
end
|
data/test/helper.rb
CHANGED
data/test/test_module.rb
CHANGED
@@ -10,5 +10,9 @@ class TestModule < Test::Unit::TestCase
|
|
10
10
|
should "respond to #fields" do
|
11
11
|
assert_respond_to SugarCRM.modules[0], :fields
|
12
12
|
end
|
13
|
+
|
14
|
+
should "return required fields when #required_fields" do
|
15
|
+
assert SugarCRM::User._module.required_fields.include? "user_name"
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
data/test/test_sugarcrm.rb
CHANGED
@@ -3,6 +3,11 @@ require 'helper'
|
|
3
3
|
class TestSugarCRM < Test::Unit::TestCase
|
4
4
|
context "A SugarCRM::Base instance" do
|
5
5
|
|
6
|
+
should "establish a connection when SugarCRM#connect!" do
|
7
|
+
SugarCRM.connect!(URL, USER, PASS)
|
8
|
+
assert SugarCRM.connection.connected?
|
9
|
+
end
|
10
|
+
|
6
11
|
should "establish a connection when Base#establish_connection" do
|
7
12
|
SugarCRM::Base.establish_connection(URL, USER, PASS)
|
8
13
|
assert SugarCRM.connection.connected?
|
@@ -12,6 +17,10 @@ class TestSugarCRM < Test::Unit::TestCase
|
|
12
17
|
assert_equal "Users", SugarCRM::User._module.name
|
13
18
|
end
|
14
19
|
|
20
|
+
should "responsd to self#methods" do
|
21
|
+
assert_instance_of Array, SugarCRM::User.new.methods
|
22
|
+
end
|
23
|
+
|
15
24
|
should "respond to self.connection" do
|
16
25
|
assert_respond_to SugarCRM::User, :connection
|
17
26
|
assert_instance_of SugarCRM::Connection, SugarCRM::User.connection
|
@@ -26,7 +35,7 @@ class TestSugarCRM < Test::Unit::TestCase
|
|
26
35
|
end
|
27
36
|
|
28
37
|
should "respond to self.attributes_from_modules_fields" do
|
29
|
-
assert_instance_of
|
38
|
+
assert_instance_of ActiveSupport::HashWithIndifferentAccess, SugarCRM::User.attributes_from_module_fields
|
30
39
|
end
|
31
40
|
|
32
41
|
should "return an instance of itself when #new" do
|
@@ -38,10 +47,31 @@ class TestSugarCRM < Test::Unit::TestCase
|
|
38
47
|
assert SugarCRM::User.attribute_methods_generated
|
39
48
|
end
|
40
49
|
|
41
|
-
should "
|
50
|
+
should "not save a record that is missing required attributes" do
|
42
51
|
u = SugarCRM::User.new
|
43
52
|
u.last_name = "Test"
|
44
|
-
|
53
|
+
assert !u.save
|
54
|
+
assert_raise SugarCRM::InvalidRecord do
|
55
|
+
u.save!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
should "create, modify, and delete a record" do
|
60
|
+
#SugarCRM.connection.debug = true
|
61
|
+
u = SugarCRM::User.new
|
62
|
+
u.email1 = "abc@abc.com"
|
63
|
+
u.first_name = "Test"
|
64
|
+
u.last_name = "User"
|
65
|
+
u.system_generated_password = false
|
66
|
+
u.user_name = "test_user"
|
67
|
+
u.status = "Active"
|
68
|
+
assert_equal "Test", u.modified_attributes[:first_name][:new]
|
69
|
+
assert u.save!
|
70
|
+
m = SugarCRM::User.find_by_first_name_and_last_name("Test", "User")
|
71
|
+
m.title = "Test User"
|
72
|
+
assert m.save!
|
73
|
+
assert m.delete
|
74
|
+
#SugarCRM.connection.debug = false
|
45
75
|
end
|
46
76
|
|
47
77
|
should "return an an instance of itself when sent #find(id)" do
|
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:
|
4
|
+
hash: 63
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.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-
|
18
|
+
date: 2010-12-04 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|