sugarcrm 0.9.16 → 0.9.17
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.
- data/Gemfile.lock +5 -3
- data/VERSION +1 -1
- data/lib/sugarcrm/attributes/attribute_methods.rb +6 -3
- data/lib/sugarcrm/base.rb +20 -7
- data/lib/sugarcrm/connection/helper.rb +1 -1
- data/lib/sugarcrm/connection/request.rb +26 -1
- data/lib/sugarcrm/extensions/README.txt +1 -1
- data/lib/sugarcrm/module.rb +1 -1
- data/sugarcrm.gemspec +9 -8
- data/test/connection/test_set_entry.rb +15 -0
- data/test/test_module.rb +1 -1
- data/test/test_request.rb +35 -0
- data/test/test_sugarcrm.rb +14 -1
- metadata +26 -56
data/Gemfile.lock
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (3.
|
4
|
+
activesupport (3.1.3)
|
5
|
+
multi_json (~> 1.0)
|
5
6
|
git (1.2.5)
|
6
7
|
i18n (0.6.0)
|
7
8
|
jeweler (1.5.2)
|
8
9
|
bundler (~> 1.0.0)
|
9
10
|
git (>= 1.2.5)
|
10
11
|
rake
|
11
|
-
json (1.
|
12
|
-
|
12
|
+
json (1.6.1)
|
13
|
+
multi_json (1.0.3)
|
14
|
+
rake (0.9.2.2)
|
13
15
|
shoulda (2.11.3)
|
14
16
|
|
15
17
|
PLATFORMS
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.17
|
@@ -164,9 +164,12 @@ module SugarCRM; module AttributeMethods
|
|
164
164
|
|
165
165
|
# Wrapper for invoking save on modified_attributes
|
166
166
|
# sets the id if it's a new record
|
167
|
-
def save_modified_attributes!
|
168
|
-
|
169
|
-
|
167
|
+
def save_modified_attributes!(opts={})
|
168
|
+
options = { :validate => true }.merge(opts)
|
169
|
+
if options[:validate]
|
170
|
+
# Complain if we aren't valid
|
171
|
+
raise InvalidRecord, @errors.full_messages.join(", ") unless valid?
|
172
|
+
end
|
170
173
|
# Send the save request
|
171
174
|
response = self.class.session.connection.set_entry(self.class._module.name, serialize_modified_attributes)
|
172
175
|
# Complain if we don't get a parseable response back
|
data/lib/sugarcrm/base.rb
CHANGED
@@ -36,8 +36,13 @@ module SugarCRM; class Base
|
|
36
36
|
sort_criteria = 'date_entered'
|
37
37
|
elsif self.method_defined? :date_created
|
38
38
|
sort_criteria = 'date_created'
|
39
|
+
# Added date_modified because TeamSets doesn't have a date_created or date_entered field.
|
40
|
+
# There's no test for this because it's Pro and above only.
|
41
|
+
# Hope this doesn't break anything!
|
42
|
+
elsif self.method_defined? :date_modified
|
43
|
+
sort_criteria = 'date_modified'
|
39
44
|
else
|
40
|
-
raise InvalidAttribute, "Unable to determine record creation date for sorting criteria: expected date_entered or
|
45
|
+
raise InvalidAttribute, "Unable to determine record creation date for sorting criteria: expected date_entered, date_created, or date_modified attribute to be present"
|
41
46
|
end
|
42
47
|
options = {:order_by => sort_criteria}.merge(options)
|
43
48
|
validate_find_options(options)
|
@@ -152,11 +157,14 @@ module SugarCRM; class Base
|
|
152
157
|
|
153
158
|
# Saves the current object, checks that required fields are present.
|
154
159
|
# returns true or false
|
155
|
-
def save
|
160
|
+
def save(opts={})
|
161
|
+
options = { :validate => true }.merge(opts)
|
156
162
|
return false if !(new_record? || changed?)
|
157
|
-
|
163
|
+
if options[:validate]
|
164
|
+
return false if !valid?
|
165
|
+
end
|
158
166
|
begin
|
159
|
-
save!
|
167
|
+
save!(options)
|
160
168
|
rescue
|
161
169
|
return false
|
162
170
|
end
|
@@ -165,8 +173,8 @@ module SugarCRM; class Base
|
|
165
173
|
|
166
174
|
# Saves the current object, and any modified associations.
|
167
175
|
# Raises an exceptions if save fails for any reason.
|
168
|
-
def save!
|
169
|
-
save_modified_attributes!
|
176
|
+
def save!(opts={})
|
177
|
+
save_modified_attributes!(opts)
|
170
178
|
save_modified_associations!
|
171
179
|
true
|
172
180
|
end
|
@@ -190,6 +198,11 @@ module SugarCRM; class Base
|
|
190
198
|
self.attributes = self.class.find(self.id).attributes
|
191
199
|
end
|
192
200
|
|
201
|
+
def blank?
|
202
|
+
@attributes.empty?
|
203
|
+
end
|
204
|
+
alias :empty? :blank?
|
205
|
+
|
193
206
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
194
207
|
# is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
|
195
208
|
#
|
@@ -238,7 +251,7 @@ module SugarCRM; class Base
|
|
238
251
|
|
239
252
|
# Returns the URL (in string format) where the module instance is available in CRM
|
240
253
|
def url
|
241
|
-
"#{SugarCRM.session.config[:base_url]}/index.php?module=#{self.class._module}&action=DetailView&record=#{self.id}"
|
254
|
+
"#{SugarCRM.session.config[:base_url]}/index.php?module=#{self.class._module.name}&action=DetailView&record=#{self.id}"
|
242
255
|
end
|
243
256
|
|
244
257
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
@@ -8,7 +8,7 @@ module SugarCRM; class Request
|
|
8
8
|
def initialize(url, method, json, debug=false)
|
9
9
|
@url = url
|
10
10
|
@method = method
|
11
|
-
@json =
|
11
|
+
@json = escape(json)
|
12
12
|
@request = 'method=' << @method.to_s
|
13
13
|
@request << '&input_type=JSON'
|
14
14
|
@request << '&response_type=JSON'
|
@@ -21,6 +21,20 @@ module SugarCRM; class Request
|
|
21
21
|
self
|
22
22
|
end
|
23
23
|
|
24
|
+
def escape(json)
|
25
|
+
# BUG: SugarCRM doesn't properly handle '"' inside of JSON for some reason. Let's unescape any html elements.
|
26
|
+
j = convert_reserved_characters(json)
|
27
|
+
# Now we escape the resulting string.
|
28
|
+
j = CGI.escape(j)
|
29
|
+
j
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO: Fix this so that it JSON.parse will consume it.
|
33
|
+
def unescape
|
34
|
+
j = CGI.unescape(@json)
|
35
|
+
j.gsub!(/\n/, '')
|
36
|
+
end
|
37
|
+
|
24
38
|
def bytesize
|
25
39
|
self.to_s.bytesize
|
26
40
|
end
|
@@ -32,4 +46,15 @@ module SugarCRM; class Request
|
|
32
46
|
def to_s
|
33
47
|
@request
|
34
48
|
end
|
49
|
+
|
50
|
+
# A tiny helper for converting reserved characters for html encoding
|
51
|
+
def convert_reserved_characters(string)
|
52
|
+
string.gsub!(/"/, '\"')
|
53
|
+
string.gsub!(/'/, '\'')
|
54
|
+
string.gsub!(/&/, '\&')
|
55
|
+
string.gsub!(/</, '\<')
|
56
|
+
string.gsub!(/</, '\>')
|
57
|
+
string
|
58
|
+
end
|
59
|
+
|
35
60
|
end; end
|
data/lib/sugarcrm/module.rb
CHANGED
data/sugarcrm.gemspec
CHANGED
@@ -4,14 +4,13 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.9.
|
7
|
+
s.name = "sugarcrm"
|
8
|
+
s.version = "0.9.17"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Carl Hicks", "David Sulc"]
|
12
|
-
s.date =
|
13
|
-
s.
|
14
|
-
s.email = %q{carl.hicks@gmail.com}
|
12
|
+
s.date = "2011-11-26"
|
13
|
+
s.email = "carl.hicks@gmail.com"
|
15
14
|
s.executables = ["sugarcrm"]
|
16
15
|
s.extra_rdoc_files = [
|
17
16
|
"LICENSE",
|
@@ -83,10 +82,10 @@ Gem::Specification.new do |s|
|
|
83
82
|
"./sugarcrm.gemspec",
|
84
83
|
"./sugarcrm.tmproj"
|
85
84
|
]
|
86
|
-
s.homepage =
|
85
|
+
s.homepage = "http://github.com/chicks/sugarcrm"
|
87
86
|
s.require_paths = ["lib"]
|
88
|
-
s.rubygems_version =
|
89
|
-
s.summary =
|
87
|
+
s.rubygems_version = "1.8.11"
|
88
|
+
s.summary = "A less clunky way to interact with SugarCRM via REST."
|
90
89
|
s.test_files = [
|
91
90
|
"test/connection/test_get_available_modules.rb",
|
92
91
|
"test/connection/test_get_entries.rb",
|
@@ -100,6 +99,7 @@ Gem::Specification.new do |s|
|
|
100
99
|
"test/connection/test_login.rb",
|
101
100
|
"test/connection/test_logout.rb",
|
102
101
|
"test/connection/test_set_document_revision.rb",
|
102
|
+
"test/connection/test_set_entry.rb",
|
103
103
|
"test/connection/test_set_note_attachment.rb",
|
104
104
|
"test/connection/test_set_relationship.rb",
|
105
105
|
"test/extensions_test/patch.rb",
|
@@ -110,6 +110,7 @@ Gem::Specification.new do |s|
|
|
110
110
|
"test/test_connection_pool.rb",
|
111
111
|
"test/test_finders.rb",
|
112
112
|
"test/test_module.rb",
|
113
|
+
"test/test_request.rb",
|
113
114
|
"test/test_response.rb",
|
114
115
|
"test/test_session.rb",
|
115
116
|
"test/test_sugarcrm.rb"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSetEntry < ActiveSupport::TestCase
|
4
|
+
context "A SugarCRM.connection" do
|
5
|
+
should "set values on an Bean with #set_entry" do
|
6
|
+
|
7
|
+
name_value_list = {
|
8
|
+
"name" => { "name" => "name", "value" => "A Test Meeting" },
|
9
|
+
"date_start" => { "name" => "date_start", "value" => "2011-11-23 12:03:16" },
|
10
|
+
"description" => { "name" => "description", "value" => "RT @bumblebeenie "It's Childish Gambino, home girl drop it like the Nasdaq" Are you serious bro?" }
|
11
|
+
}
|
12
|
+
meeting = SugarCRM.connection.set_entry("Meetings", name_value_list)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/test/test_module.rb
CHANGED
@@ -7,7 +7,7 @@ class TestModule < ActiveSupport::TestCase
|
|
7
7
|
end
|
8
8
|
|
9
9
|
should "return required fields when #required_fields" do
|
10
|
-
assert SugarCRM::
|
10
|
+
assert SugarCRM::Account._module.required_fields.include? :name
|
11
11
|
end
|
12
12
|
|
13
13
|
# TODO: Figure out a way to test this.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRequest < ActiveSupport::TestCase
|
4
|
+
context "A SugarCRM::Request instance" do
|
5
|
+
setup do
|
6
|
+
@url = "http://localhost/sugarcrm"
|
7
|
+
@method = "get_entry"
|
8
|
+
@json = <<-EOF
|
9
|
+
{
|
10
|
+
"session": "an invalid session",
|
11
|
+
"module_name": "Accounts",
|
12
|
+
"name_value_list": {
|
13
|
+
"name": {
|
14
|
+
"name": "name",
|
15
|
+
"value": "A Test Meeting" },
|
16
|
+
"date_start": {
|
17
|
+
"name": "date_start",
|
18
|
+
"value": "2011-11-23 12:03:16" },
|
19
|
+
"description": {
|
20
|
+
"name": "description",
|
21
|
+
"value": ""OMG HAI!"" }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
EOF
|
25
|
+
@json.gsub!(/^\s{6}/, '')
|
26
|
+
@request = SugarCRM::Request.new(@url, @method, @json, false)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "properly escape JSON" do
|
30
|
+
assert_equal "%7B%22hello%22%3A+%22%5C%22OMG+HAI%21%5C%22%22%7D", @request.escape('{"hello": ""OMG HAI!""}')
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
data/test/test_sugarcrm.rb
CHANGED
@@ -187,8 +187,20 @@ class TestSugarCRM < ActiveSupport::TestCase
|
|
187
187
|
user = SugarCRM::User.first
|
188
188
|
assert_equal "#{SugarCRM.session.config[:base_url]}/index.php?module=Users&action=DetailView&record=#{user.id}", user.url
|
189
189
|
end
|
190
|
+
|
191
|
+
should "respond to #blank?" do
|
192
|
+
assert !SugarCRM::User.first.blank?
|
193
|
+
end
|
194
|
+
|
195
|
+
should "bypass validation when #save(:validate => false)" do
|
196
|
+
u = SugarCRM::User.new
|
197
|
+
u.last_name = "doe"
|
198
|
+
assert u.save({:validate => false})
|
199
|
+
assert u.delete
|
200
|
+
end
|
190
201
|
end
|
191
|
-
|
202
|
+
|
203
|
+
# TODO: Fix this test so it creates the Note properly before asserting.
|
192
204
|
context "A SugarCRM::Note instance" do
|
193
205
|
should "return the correct parent record with the `parent` method" do
|
194
206
|
note = SugarCRM::Note.first
|
@@ -197,4 +209,5 @@ class TestSugarCRM < ActiveSupport::TestCase
|
|
197
209
|
assert_equal note.parent_type.singularize, parent.class.to_s.split('::').last
|
198
210
|
end
|
199
211
|
end
|
212
|
+
|
200
213
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sugarcrm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
- 16
|
10
|
-
version: 0.9.16
|
5
|
+
version: 0.9.17
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Carl Hicks
|
@@ -16,98 +11,73 @@ autorequire:
|
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
13
|
|
19
|
-
date: 2011-
|
20
|
-
default_executable: sugarcrm
|
14
|
+
date: 2011-11-26 00:00:00 Z
|
21
15
|
dependencies:
|
22
16
|
- !ruby/object:Gem::Dependency
|
23
|
-
|
24
|
-
type: :runtime
|
17
|
+
name: activesupport
|
25
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
19
|
none: false
|
27
20
|
requirements:
|
28
21
|
- - ">="
|
29
22
|
- !ruby/object:Gem::Version
|
30
|
-
hash: 23
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 3
|
34
|
-
- 10
|
35
23
|
version: 2.3.10
|
36
|
-
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
37
26
|
version_requirements: *id001
|
38
27
|
- !ruby/object:Gem::Dependency
|
39
|
-
|
40
|
-
type: :runtime
|
28
|
+
name: i18n
|
41
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
30
|
none: false
|
43
31
|
requirements:
|
44
32
|
- - ">="
|
45
33
|
- !ruby/object:Gem::Version
|
46
|
-
hash: 3
|
47
|
-
segments:
|
48
|
-
- 0
|
49
34
|
version: "0"
|
50
|
-
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
51
37
|
version_requirements: *id002
|
52
38
|
- !ruby/object:Gem::Dependency
|
53
|
-
|
54
|
-
type: :runtime
|
39
|
+
name: json
|
55
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
56
41
|
none: false
|
57
42
|
requirements:
|
58
43
|
- - ">="
|
59
44
|
- !ruby/object:Gem::Version
|
60
|
-
hash: 3
|
61
|
-
segments:
|
62
|
-
- 0
|
63
45
|
version: "0"
|
64
|
-
|
46
|
+
type: :runtime
|
47
|
+
prerelease: false
|
65
48
|
version_requirements: *id003
|
66
49
|
- !ruby/object:Gem::Dependency
|
67
|
-
|
68
|
-
type: :development
|
50
|
+
name: shoulda
|
69
51
|
requirement: &id004 !ruby/object:Gem::Requirement
|
70
52
|
none: false
|
71
53
|
requirements:
|
72
54
|
- - ">="
|
73
55
|
- !ruby/object:Gem::Version
|
74
|
-
hash: 3
|
75
|
-
segments:
|
76
|
-
- 0
|
77
56
|
version: "0"
|
78
|
-
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
79
59
|
version_requirements: *id004
|
80
60
|
- !ruby/object:Gem::Dependency
|
81
|
-
|
82
|
-
type: :development
|
61
|
+
name: bundler
|
83
62
|
requirement: &id005 !ruby/object:Gem::Requirement
|
84
63
|
none: false
|
85
64
|
requirements:
|
86
65
|
- - ~>
|
87
66
|
- !ruby/object:Gem::Version
|
88
|
-
hash: 23
|
89
|
-
segments:
|
90
|
-
- 1
|
91
|
-
- 0
|
92
|
-
- 0
|
93
67
|
version: 1.0.0
|
94
|
-
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
95
70
|
version_requirements: *id005
|
96
71
|
- !ruby/object:Gem::Dependency
|
97
|
-
|
98
|
-
type: :development
|
72
|
+
name: jeweler
|
99
73
|
requirement: &id006 !ruby/object:Gem::Requirement
|
100
74
|
none: false
|
101
75
|
requirements:
|
102
76
|
- - ~>
|
103
77
|
- !ruby/object:Gem::Version
|
104
|
-
hash: 7
|
105
|
-
segments:
|
106
|
-
- 1
|
107
|
-
- 5
|
108
|
-
- 2
|
109
78
|
version: 1.5.2
|
110
|
-
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
111
81
|
version_requirements: *id006
|
112
82
|
description:
|
113
83
|
email: carl.hicks@gmail.com
|
@@ -197,6 +167,7 @@ files:
|
|
197
167
|
- test/connection/test_login.rb
|
198
168
|
- test/connection/test_logout.rb
|
199
169
|
- test/connection/test_set_document_revision.rb
|
170
|
+
- test/connection/test_set_entry.rb
|
200
171
|
- test/connection/test_set_note_attachment.rb
|
201
172
|
- test/connection/test_set_relationship.rb
|
202
173
|
- test/extensions_test/patch.rb
|
@@ -207,11 +178,11 @@ files:
|
|
207
178
|
- test/test_connection_pool.rb
|
208
179
|
- test/test_finders.rb
|
209
180
|
- test/test_module.rb
|
181
|
+
- test/test_request.rb
|
210
182
|
- test/test_response.rb
|
211
183
|
- test/test_session.rb
|
212
184
|
- test/test_sugarcrm.rb
|
213
185
|
- bin/sugarcrm
|
214
|
-
has_rdoc: true
|
215
186
|
homepage: http://github.com/chicks/sugarcrm
|
216
187
|
licenses: []
|
217
188
|
|
@@ -225,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
225
196
|
requirements:
|
226
197
|
- - ">="
|
227
198
|
- !ruby/object:Gem::Version
|
228
|
-
hash:
|
199
|
+
hash: 3914223844168854610
|
229
200
|
segments:
|
230
201
|
- 0
|
231
202
|
version: "0"
|
@@ -234,14 +205,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
205
|
requirements:
|
235
206
|
- - ">="
|
236
207
|
- !ruby/object:Gem::Version
|
237
|
-
hash: 3
|
238
|
-
segments:
|
239
|
-
- 0
|
240
208
|
version: "0"
|
241
209
|
requirements: []
|
242
210
|
|
243
211
|
rubyforge_project:
|
244
|
-
rubygems_version: 1.
|
212
|
+
rubygems_version: 1.8.11
|
245
213
|
signing_key:
|
246
214
|
specification_version: 3
|
247
215
|
summary: A less clunky way to interact with SugarCRM via REST.
|
@@ -258,6 +226,7 @@ test_files:
|
|
258
226
|
- test/connection/test_login.rb
|
259
227
|
- test/connection/test_logout.rb
|
260
228
|
- test/connection/test_set_document_revision.rb
|
229
|
+
- test/connection/test_set_entry.rb
|
261
230
|
- test/connection/test_set_note_attachment.rb
|
262
231
|
- test/connection/test_set_relationship.rb
|
263
232
|
- test/extensions_test/patch.rb
|
@@ -268,6 +237,7 @@ test_files:
|
|
268
237
|
- test/test_connection_pool.rb
|
269
238
|
- test/test_finders.rb
|
270
239
|
- test/test_module.rb
|
240
|
+
- test/test_request.rb
|
271
241
|
- test/test_response.rb
|
272
242
|
- test/test_session.rb
|
273
243
|
- test/test_sugarcrm.rb
|