sugarcrm_emp 0.10.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 (94) hide show
  1. data/.document +5 -0
  2. data/.gitignore +29 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +275 -0
  6. data/Rakefile +44 -0
  7. data/VERSION +1 -0
  8. data/WATCHLIST.rdoc +7 -0
  9. data/bin/sugarcrm +26 -0
  10. data/lib/rails/generators/sugarcrm/config/config_generator.rb +22 -0
  11. data/lib/rails/generators/sugarcrm/config/templates/initializer.rb +4 -0
  12. data/lib/rails/generators/sugarcrm/config/templates/sugarcrm.yml +19 -0
  13. data/lib/sugarcrm/associations/association.rb +170 -0
  14. data/lib/sugarcrm/associations/association_cache.rb +36 -0
  15. data/lib/sugarcrm/associations/association_collection.rb +141 -0
  16. data/lib/sugarcrm/associations/association_methods.rb +91 -0
  17. data/lib/sugarcrm/associations/associations.rb +61 -0
  18. data/lib/sugarcrm/associations.rb +5 -0
  19. data/lib/sugarcrm/attributes/attribute_methods.rb +203 -0
  20. data/lib/sugarcrm/attributes/attribute_serializers.rb +55 -0
  21. data/lib/sugarcrm/attributes/attribute_typecast.rb +44 -0
  22. data/lib/sugarcrm/attributes/attribute_validations.rb +62 -0
  23. data/lib/sugarcrm/attributes.rb +4 -0
  24. data/lib/sugarcrm/base.rb +355 -0
  25. data/lib/sugarcrm/config/sugarcrm.yaml +10 -0
  26. data/lib/sugarcrm/connection/api/get_available_modules.rb +22 -0
  27. data/lib/sugarcrm/connection/api/get_document_revision.rb +14 -0
  28. data/lib/sugarcrm/connection/api/get_entries.rb +23 -0
  29. data/lib/sugarcrm/connection/api/get_entries_count.rb +20 -0
  30. data/lib/sugarcrm/connection/api/get_entry.rb +23 -0
  31. data/lib/sugarcrm/connection/api/get_entry_list.rb +31 -0
  32. data/lib/sugarcrm/connection/api/get_module_fields.rb +15 -0
  33. data/lib/sugarcrm/connection/api/get_note_attachment.rb +14 -0
  34. data/lib/sugarcrm/connection/api/get_relationships.rb +30 -0
  35. data/lib/sugarcrm/connection/api/get_report_entries.rb +17 -0
  36. data/lib/sugarcrm/connection/api/get_server_info.rb +7 -0
  37. data/lib/sugarcrm/connection/api/get_user_id.rb +13 -0
  38. data/lib/sugarcrm/connection/api/get_user_team_id.rb +14 -0
  39. data/lib/sugarcrm/connection/api/login.rb +18 -0
  40. data/lib/sugarcrm/connection/api/logout.rb +15 -0
  41. data/lib/sugarcrm/connection/api/seamless_login.rb +13 -0
  42. data/lib/sugarcrm/connection/api/search_by_module.rb +25 -0
  43. data/lib/sugarcrm/connection/api/set_campaign_merge.rb +15 -0
  44. data/lib/sugarcrm/connection/api/set_document_revision.rb +35 -0
  45. data/lib/sugarcrm/connection/api/set_entries.rb +15 -0
  46. data/lib/sugarcrm/connection/api/set_entry.rb +15 -0
  47. data/lib/sugarcrm/connection/api/set_note_attachment.rb +25 -0
  48. data/lib/sugarcrm/connection/api/set_relationship.rb +27 -0
  49. data/lib/sugarcrm/connection/api/set_relationships.rb +22 -0
  50. data/lib/sugarcrm/connection/connection.rb +201 -0
  51. data/lib/sugarcrm/connection/helper.rb +50 -0
  52. data/lib/sugarcrm/connection/request.rb +61 -0
  53. data/lib/sugarcrm/connection/response.rb +91 -0
  54. data/lib/sugarcrm/connection.rb +5 -0
  55. data/lib/sugarcrm/connection_pool.rb +163 -0
  56. data/lib/sugarcrm/exceptions.rb +23 -0
  57. data/lib/sugarcrm/extensions/README.txt +23 -0
  58. data/lib/sugarcrm/finders/dynamic_finder_match.rb +41 -0
  59. data/lib/sugarcrm/finders/finder_methods.rb +243 -0
  60. data/lib/sugarcrm/finders.rb +2 -0
  61. data/lib/sugarcrm/module.rb +174 -0
  62. data/lib/sugarcrm/module_methods.rb +91 -0
  63. data/lib/sugarcrm/session.rb +218 -0
  64. data/lib/sugarcrm.rb +22 -0
  65. data/sugarcrm.gemspec +178 -0
  66. data/test/config_test.yaml +15 -0
  67. data/test/connection/test_get_available_modules.rb +9 -0
  68. data/test/connection/test_get_entries.rb +15 -0
  69. data/test/connection/test_get_entry.rb +22 -0
  70. data/test/connection/test_get_entry_list.rb +23 -0
  71. data/test/connection/test_get_module_fields.rb +11 -0
  72. data/test/connection/test_get_relationships.rb +12 -0
  73. data/test/connection/test_get_server_info.rb +9 -0
  74. data/test/connection/test_get_user_id.rb +9 -0
  75. data/test/connection/test_get_user_team_id.rb +9 -0
  76. data/test/connection/test_login.rb +9 -0
  77. data/test/connection/test_logout.rb +9 -0
  78. data/test/connection/test_set_document_revision.rb +28 -0
  79. data/test/connection/test_set_entry.rb +15 -0
  80. data/test/connection/test_set_note_attachment.rb +16 -0
  81. data/test/connection/test_set_relationship.rb +18 -0
  82. data/test/extensions_test/patch.rb +9 -0
  83. data/test/helper.rb +17 -0
  84. data/test/test_association_collection.rb +11 -0
  85. data/test/test_associations.rb +156 -0
  86. data/test/test_connection.rb +13 -0
  87. data/test/test_connection_pool.rb +40 -0
  88. data/test/test_finders.rb +201 -0
  89. data/test/test_module.rb +51 -0
  90. data/test/test_request.rb +35 -0
  91. data/test/test_response.rb +26 -0
  92. data/test/test_session.rb +136 -0
  93. data/test/test_sugarcrm.rb +213 -0
  94. metadata +266 -0
@@ -0,0 +1,28 @@
1
+ require 'helper'
2
+
3
+ class TestSetDocumentRevision < ActiveSupport::TestCase
4
+ context "A SugarCRM.connection" do
5
+ should "Update a document revision" do
6
+ file = File.read("test/config_test.yaml")
7
+ # Create a new document, no file is attached or uploaded at this stage.
8
+ d = SugarCRM::Document.create(
9
+ :revision => 1,
10
+ :active_date => Date.today,
11
+ :filename => "config_test.yaml",
12
+ :document_name=> "config_test.yaml",
13
+ :uploadfile => "config_test.yaml"
14
+ )
15
+ # Did we succeed?
16
+ assert !d.new?
17
+ # Create a new document revision, attaching the file to the document_revision, and associating the document
18
+ # revision with parent document
19
+ assert SugarCRM.connection.set_document_revision(d.id, d.revision + 1, {:file => file, :file_name => "config_test.yaml"})
20
+ # Delete the document
21
+ assert d.delete
22
+ # Remove any document revisions associated with that document
23
+ SugarCRM::DocumentRevision.find_all_by_document_id(d.id).each do |dr|
24
+ assert dr.delete
25
+ end
26
+ end
27
+ end
28
+ end
@@ -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 &quot;It's Childish Gambino, home girl drop it like the Nasdaq&quot; Are you serious bro?" }
11
+ }
12
+ meeting = SugarCRM.connection.set_entry("Meetings", name_value_list)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ class TestSetNoteAttachment < ActiveSupport::TestCase
4
+ context "A SugarCRM.connection" do
5
+ should "Add an attachment to a Note" do
6
+ n = SugarCRM::Note.new
7
+ n.name = "A Test Note"
8
+ assert n.save
9
+ file = File.read("test/config_test.yaml")
10
+ assert SugarCRM.connection.set_note_attachment(n.id, "config_test.yaml", file)
11
+ attachment = SugarCRM.connection.get_note_attachment(n.id)
12
+ assert_equal file, Base64.decode64(attachment["file"])
13
+ assert n.delete
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+
3
+ class TestSetRelationship < ActiveSupport::TestCase
4
+ context "A SugarCRM.connection" do
5
+ should "add and remove a relationship when #set_relationship" do
6
+ meeting = SugarCRM::Meeting.new
7
+ meeting.date_start = DateTime.now
8
+ meeting.duration_hours = 0.5
9
+ meeting.name = "Stupid Meeting"
10
+ assert meeting.save!
11
+ response = SugarCRM.connection.set_relationship("Users","1","meetings", [meeting.id])
12
+ assert response["created"] == 1
13
+ response = SugarCRM.connection.set_relationship("Users","1","meetings", [meeting.id], {:delete => 1})
14
+ assert response["deleted"] == 1
15
+ assert meeting.delete
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ SugarCRM::Contact.class_eval do
2
+ def self.is_extended?
3
+ true
4
+ end
5
+
6
+ def is_extended?
7
+ true
8
+ end
9
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'active_support/test_case'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'sugarcrm'
9
+
10
+ CONFIG_PATH = File.join(File.dirname(__FILE__),'config.yaml')
11
+
12
+ class ActiveSupport::TestCase
13
+ # put your credentials into a YAML file in the test directory
14
+ # the format should be identical to the config_test.yaml found in the same directory
15
+ raise "test/config.yaml file not found. See README for instructions on setting up a testing environment" unless File.exists? CONFIG_PATH
16
+ SugarCRM::Session.from_file(CONFIG_PATH)
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'helper'
2
+
3
+ class TestAssociationCollection < ActiveSupport::TestCase
4
+ context "A SugarCRM::AssociationCollection instance" do
5
+ should "create a new instance when #new" do
6
+ u = SugarCRM::User.find("seed_sarah_id")
7
+ ac = SugarCRM::AssociationCollection.new(u,:email_addresses)
8
+ assert_instance_of SugarCRM::AssociationCollection, ac
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,156 @@
1
+ require 'helper'
2
+
3
+ class TestAssociations < ActiveSupport::TestCase
4
+ context "A SugarCRM::Associations class" do
5
+ should "Return an array of Association objects when self#register(SugarCRM::User.new)" do
6
+ associations = SugarCRM::Associations.register(SugarCRM::User.new)
7
+ assert associations.include? "email_addresses"
8
+ assert associations.proxy_methods.include? "email_addresses"
9
+ end
10
+ end
11
+
12
+ context "A SugarCRM::Association class" do
13
+ should "compute relationship cardinality correctly" do
14
+ c = SugarCRM::Case.first
15
+ link_fields_hash = c.associations.classify{|i| i.link_field}
16
+ # TODO: test one_to_one cardinality by creating custom module with custom relationship
17
+ # (no "official" one-to-one relationship exists in Sugar out of the box)
18
+ assert_equal :one_to_many, link_fields_hash['calls'].first.cardinality
19
+ assert_equal :many_to_one, link_fields_hash['accounts'].first.cardinality
20
+ assert_equal :many_to_many, link_fields_hash['contacts'].first.cardinality
21
+ end
22
+ should "respond to #pretty_print" do
23
+ a = SugarCRM::Case.first.associations.first
24
+ assert_respond_to a, :pretty_print
25
+ end
26
+ end
27
+
28
+ context "A SugarCRM::Base instance" do
29
+ should "return an email address when sent #email_addresses" do
30
+ u = SugarCRM::User.find("seed_sarah_id")
31
+ assert_instance_of SugarCRM::AssociationCollection, u.email_addresses
32
+ assert_instance_of SugarCRM::EmailAddress, u.email_addresses.first
33
+ assert_equal "sarah@example.com", u.email_addresses.first.email_address
34
+ end
35
+
36
+ should "utilize the association cache" do
37
+ u = SugarCRM::User.find(1)
38
+ u.email_addresses
39
+ assert u.association_cached? :email_addresses
40
+ end
41
+
42
+ should "permit adding a record to an association collection (such as #meetings << Meeting.new)" do
43
+ u = SugarCRM::User.find(1)
44
+ m = SugarCRM::Meeting.new
45
+ m.date_start = DateTime.now
46
+ m.duration_hours = 0.5
47
+ m.name = "Yet Another Stupid Meeting"
48
+ u.meetings << m
49
+ assert u.meetings.include?(m)
50
+ assert_equal [m], u.meetings.added
51
+ assert u.save!
52
+ u = SugarCRM::User.find(1)
53
+ assert u.meetings.include?(m)
54
+ assert u.meetings.delete(m)
55
+ assert u.meetings.save!
56
+ assert !u.meetings.include?(m)
57
+ end
58
+
59
+ # TODO: Fix created_by_link to only return a single result
60
+ should "return a user when sent #created_by_link" do
61
+ a = SugarCRM::Account.first
62
+ assert_instance_of SugarCRM::User, a.created_by_link.first
63
+ end
64
+
65
+ should "create relationships with associate!" do
66
+ a = SugarCRM::Account.first
67
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
68
+
69
+ nb_contacts = a.contacts.size
70
+ a.associate!(c)
71
+ assert_equal nb_contacts + 1, a.contacts.size # test association_cache is updated
72
+
73
+ assert_equal nb_contacts + 1, SugarCRM::Account.first.contacts.size # test relationship is created in Sugar
74
+
75
+ assert c.delete
76
+ end
77
+
78
+ should "destroy relationships with disassociate!" do
79
+ a = SugarCRM::Account.first
80
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
81
+
82
+ a.associate!(c)
83
+ nb_contacts = a.contacts.size
84
+ a.disassociate!(c)
85
+ assert_equal nb_contacts - 1, a.contacts.size # test association_cache is updated
86
+
87
+ assert_equal nb_contacts - 1, SugarCRM::Account.first.contacts.size # test relationship is destroyed in Sugar
88
+
89
+ assert c.delete
90
+ end
91
+
92
+ should "not destroy a relationship if associate! is called with {:delete => 0}" do
93
+ a = SugarCRM::Account.first
94
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
95
+
96
+ a.associate!(c)
97
+ nb_contacts = a.contacts.size
98
+ a.associate!(c, {:delete => 0})
99
+ assert_equal nb_contacts, a.contacts.size
100
+
101
+ assert c.delete
102
+ end
103
+
104
+ should "update association cache on associate! only if association changes" do
105
+ a = SugarCRM::Account.first
106
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
107
+
108
+ nb_contacts = a.contacts.size
109
+ a.associate!(c)
110
+ assert_equal nb_contacts + 1, a.contacts.size
111
+ a.associate!(c)
112
+ assert_equal nb_contacts + 1, a.contacts.size # should not change: already associated
113
+
114
+ assert c.delete
115
+ end
116
+
117
+ should "update association cache on << only if association changes" do
118
+ a = SugarCRM::Account.first
119
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
120
+
121
+ nb_contacts = a.contacts.size
122
+ a.contacts << c
123
+ assert_equal nb_contacts + 1, a.contacts.size
124
+ a.contacts << c
125
+ assert_equal nb_contacts + 1, a.contacts.size # should not change: already associated
126
+
127
+ assert c.delete
128
+ end
129
+
130
+ should "update association cache for both sides of the relationship when calling associate!" do
131
+ a = SugarCRM::Account.first
132
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
133
+
134
+ nb_contacts = a.contacts.size
135
+ nb_accounts = c.accounts.size
136
+ a.associate!(c)
137
+ assert_equal nb_contacts + 1, a.contacts.size
138
+ assert_equal nb_accounts + 1, c.accounts.size
139
+
140
+ assert c.delete
141
+ end
142
+
143
+ should "update association cache for both sides of the relationship when calling <<" do
144
+ a = SugarCRM::Account.first
145
+ c = SugarCRM::Contact.create(:last_name => 'Doe')
146
+
147
+ nb_contacts = a.contacts.size
148
+ nb_accounts = c.accounts.size
149
+ a.contacts << c
150
+ assert_equal nb_contacts + 1, a.contacts.size
151
+ assert_equal nb_accounts + 1, c.accounts.size
152
+
153
+ assert c.delete
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+
3
+ class TestConnection < ActiveSupport::TestCase
4
+ context "A SugarCRM::Connection instance" do
5
+ should "retrieve the list of available modules" do
6
+ assert_instance_of Array, SugarCRM.modules
7
+ assert_instance_of SugarCRM::Module, SugarCRM.modules[0]
8
+ end
9
+ should "create sub-classes by module name" do
10
+ assert SugarCRM.session.namespace_const.const_defined? "User"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ require 'helper'
2
+
3
+ class TestConnectionPool < ActiveSupport::TestCase
4
+ context "A SugarCRM::ConnectionPool instance" do
5
+ should "have a default pool size of 1 if Rails isn't defined" do
6
+ assert_equal 1, SugarCRM.session.connection_pool.size
7
+ end
8
+
9
+ should "be able to specify its pool size" do
10
+ config = SugarCRM.session.config
11
+ sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:size => 3}})
12
+
13
+ begin
14
+ assert_equal 3, sess.connection_pool.size
15
+ ensure
16
+ sess.disconnect!
17
+ end
18
+ end
19
+
20
+ should "be able to specify its timeout on creation" do
21
+ default_timeout = SugarCRM.session.connection_pool.timeout
22
+
23
+ config = SugarCRM.session.config
24
+ sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:wait_timeout => default_timeout+1}})
25
+
26
+ begin
27
+ assert_equal default_timeout+1, sess.connection_pool.timeout
28
+ ensure
29
+ sess.disconnect!
30
+ end
31
+ end
32
+
33
+ should "be able to specify its timeout after creation" do
34
+ timeout = SugarCRM.session.connection_pool.timeout
35
+ SugarCRM.session.connection_pool.timeout += 1
36
+
37
+ assert_equal timeout + 1, SugarCRM.session.connection_pool.timeout
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,201 @@
1
+ require 'helper'
2
+
3
+ class TestFinders < ActiveSupport::TestCase
4
+ context "A SugarCRM::Base instance" do
5
+ should "always return an Array when :all" do
6
+ users = SugarCRM::User.all(:limit => 10)
7
+ assert_instance_of Array, users
8
+ users = SugarCRM::User.find(:all, :conditions => {:user_name => "= #{users.first.user_name}"})
9
+ assert_instance_of Array, users
10
+ assert_equal 1, users.length
11
+ users = SugarCRM::User.find(:all, :conditions => {:user_name => '= invalid_user_123'})
12
+ assert_instance_of Array, users
13
+ assert users.length == 0
14
+ end
15
+
16
+ should "support finding first instance with default sort order (for module using date_entered as creation date)" do
17
+ expected_account = SugarCRM::Account.first({:order_by => 'date_entered'})
18
+ account = nil
19
+ assert_nothing_raised do
20
+ account = SugarCRM::Account.first
21
+ end
22
+ assert_equal expected_account.id, account.id
23
+ end
24
+
25
+ should "support finding first instance with default sort order (for module using date_created as creation date)" do
26
+ expected_email = SugarCRM::EmailAddress.first({:order_by => 'date_created'})
27
+ email = nil
28
+ assert_nothing_raised do
29
+ email = SugarCRM::EmailAddress.first
30
+ end
31
+ assert_equal expected_email.id, email.id
32
+ end
33
+
34
+ should "support finding first instance (sorted by attribute)" do
35
+ account = SugarCRM::Account.first({
36
+ :order_by => 'name'
37
+ })
38
+ assert_instance_of SugarCRM::Account, account
39
+ end
40
+
41
+ should "support finding last instance (sorted by attribute)" do
42
+ expected_account = SugarCRM::Account.first({:order_by => 'name DESC'})
43
+ account = SugarCRM::Account.last({:order_by => 'name'})
44
+ assert_equal expected_account.id, account.id
45
+
46
+ expected_account = SugarCRM::Account.first({:order_by => 'name DESC'})
47
+ account = SugarCRM::Account.last({:order_by => 'name ASC'})
48
+ assert_equal expected_account.id, account.id
49
+
50
+ expected_account = SugarCRM::Account.first({:order_by => 'name ASC'})
51
+ account = SugarCRM::Account.last({:order_by => 'name DESC'})
52
+ assert_equal expected_account.id, account.id
53
+ end
54
+
55
+ should "support finding last instance with symbol as :order_by option" do
56
+ expected_account = SugarCRM::Account.first({:order_by => 'id DESC'})
57
+ account = SugarCRM::Account.last({:order_by => :id})
58
+ assert_equal expected_account.id, account.id
59
+ end
60
+
61
+ should "support finding last instance (last created)" do
62
+ expected_account = SugarCRM::Account.first({:order_by => 'date_entered DESC'})
63
+ account = SugarCRM::Account.last
64
+ assert_equal expected_account.id, account.id
65
+ end
66
+
67
+ should "support returning only certain fields" do
68
+ user = SugarCRM::User.first(:fields => [:first_name, :department])
69
+ assert_instance_of SugarCRM::User, user
70
+ end
71
+
72
+ should "raise a RuntimeError when searching for last instance with multiple order clauses" do
73
+ assert_raise(RuntimeError){ SugarCRM::Account.last({:order_by => 'name, id DESC'}) }
74
+ end
75
+
76
+ should "raise a RuntimeError when searching for last instance if order clause has weird format" do
77
+ assert_raise(RuntimeError){ SugarCRM::Account.last({:order_by => 'name id DESC'}) }
78
+ assert_raise(RuntimeError){ SugarCRM::Account.last({:order_by => 'name DESC id'}) }
79
+ end
80
+
81
+ should "support searching based on conditions" do
82
+ accounts = SugarCRM::Account.all({
83
+ :conditions => { :billing_address_postalcode => ["> '70000'", "< '79999'" ] },
84
+ :limit => 2,
85
+ :order_by => 'billing_address_postalcode'
86
+ })
87
+ assert_instance_of SugarCRM::Account, accounts.first
88
+ end
89
+
90
+ should "support searching based on SQL operators" do
91
+ accounts = SugarCRM::Account.all({
92
+ :conditions => { :name => "LIKE '%Inc%'" }
93
+ })
94
+ assert accounts
95
+ assert_instance_of SugarCRM::Account, accounts.first
96
+ end
97
+
98
+ should "return an an instance of itself when sent #find(id)" do
99
+ assert_instance_of SugarCRM::User, SugarCRM::User.find(1)
100
+ end
101
+
102
+ should "receive a response containing all fields when sent #get_entry" do
103
+ u = SugarCRM::User.find(1)
104
+ assert_not_nil u.user_name
105
+ end
106
+
107
+ should "return an array of records when sent #find([id1, id2, id3])" do
108
+ users = SugarCRM::User.find(["seed_sarah_id", 1])
109
+ assert_not_nil users.last.user_name
110
+ end
111
+
112
+ # test Base#find_by_sql edge case
113
+ should "return an array of records with small limit and an offset of 0" do
114
+ accounts = SugarCRM::Account.all(:limit => 3, :offset => 0)
115
+ assert_equal 3, accounts.size
116
+ end
117
+
118
+ # test Base#find_by_sql edge case: force slize size to vary up and down
119
+ should "return an array of records with small offset and a limit greater than 5 but not divisible by 5" do
120
+ accounts = SugarCRM::Account.all(:limit => 13, :offset => 2)
121
+ assert_equal 13, accounts.size
122
+ end
123
+
124
+ # test Base#find_by_sql standard case
125
+ should "return an array of records with high limit" do
126
+ accounts = SugarCRM::Account.all(:limit => 12)
127
+ assert_equal 12, accounts.size
128
+ end
129
+
130
+ should "accept a block" do
131
+ # try small limit which will return result on the first result slice (and call yield block only once)
132
+ count = 0
133
+ assert_nothing_raised do
134
+ SugarCRM::Account.all(:limit => 2){|a|
135
+ count += 1
136
+ }
137
+ end
138
+ assert_equal 2, count
139
+
140
+ # try larger limit which will require multiple result slices to be fetched and yielded individually (yield block called for each result slice)
141
+ count = 0
142
+ assert_nothing_raised do
143
+ SugarCRM::Account.all(:limit => 12){|a|
144
+ count += 1
145
+ }
146
+ end
147
+ assert_equal 12, count
148
+ end
149
+
150
+ should "retrieve all records (with no limit option) correctly" do
151
+ count = 0
152
+ SugarCRM::Account.all{|a|
153
+ count += 1
154
+ }
155
+ assert_equal SugarCRM::Account.count, count
156
+ end
157
+
158
+ should "return an array of records when using :order_by, :limit, and :offset options" do
159
+ accounts = SugarCRM::Account.all(:order_by => 'name', :limit => 3, :offset => 10)
160
+ accounts_api = SugarCRM.connection.get_entry_list('Accounts', '1=1', :order_by => 'name', :limit => 3, :offset => 10)
161
+ assert_equal accounts_api, accounts
162
+ end
163
+
164
+ should "return an array of records working around a SugarCRM bug when :limit > :offset" do
165
+ accounts = SugarCRM::Account.all(:order_by => 'name', :limit => 10, :offset => 2)
166
+ assert_equal 10, accounts.size
167
+ end
168
+
169
+ should "return an array of 1 record with :limit => 1, :offset => 1" do
170
+ accounts = SugarCRM::Account.all(:order_by => 'name', :limit => 1, :offset => 1)
171
+ assert_equal 1, accounts.size
172
+ end
173
+
174
+ should "ignore :offset => 0" do
175
+ accounts = SugarCRM::Account.all(:order_by => 'name', :limit => 3)
176
+ accounts_offset = SugarCRM::Account.all(:order_by => 'name', :limit => 3, :offset => 0)
177
+ assert_equal accounts, accounts_offset
178
+ end
179
+
180
+ should "compute offsets correctly" do
181
+ accounts = SugarCRM::Account.all(:order_by => 'name', :limit => 10, :offset => 3)
182
+ accounts_first_slice = SugarCRM::Account.all(:order_by => 'name', :limit => 5, :offset => 3)
183
+ accounts_second_slice = SugarCRM::Account.all(:order_by => 'name', :limit => 5, :offset => 8)
184
+ assert_equal accounts, accounts_first_slice.concat(accounts_second_slice)
185
+ end
186
+
187
+ should "return an instance of User when sent User#find_by_username" do
188
+ u = SugarCRM::User.find_by_user_name("sarah")
189
+ assert_equal "sarah@example.com", u.email_addresses.first.email_address
190
+ end
191
+
192
+ should "create or retrieve a record when #find_or_create_by_name" do
193
+ a = SugarCRM::Account.find_or_create_by_name("Really Important Co. Name")
194
+ assert_instance_of SugarCRM::Account, a
195
+ assert !a.new?
196
+ b = SugarCRM::Account.find_or_create_by_name("Really Important Co. Name")
197
+ assert a == b
198
+ assert a.delete
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,51 @@
1
+ require 'helper'
2
+
3
+ class TestModule < ActiveSupport::TestCase
4
+ context "A SugarCRM::Module instance" do
5
+ should "respond to #fields" do
6
+ assert_respond_to SugarCRM.modules[0], :fields
7
+ end
8
+
9
+ should "return required fields when #required_fields" do
10
+ assert SugarCRM::Account._module.required_fields.include? :name
11
+ end
12
+
13
+ # TODO: Figure out a way to test this.
14
+ #should "return the custom table name when #custom_table_name" do
15
+ # assert_equal "accounts_cstm", SugarCRM::Account._module.custom_table_name
16
+ #end
17
+ end
18
+
19
+ context "SugarCRM::Module" do
20
+ should "find modules" do
21
+ assert_instance_of SugarCRM::Module, SugarCRM::Module.find("Accounts")
22
+ end
23
+
24
+ should "(de)register all modules" do
25
+ assert SugarCRM.modules.size > 0
26
+ assert SugarCRM.session.namespace_const.const_defined? 'User'
27
+
28
+ SugarCRM::Module.deregister_all(SugarCRM.session)
29
+ assert SugarCRM.modules.size == 0
30
+ assert ! (SugarCRM.session.namespace_const.const_defined? 'User')
31
+
32
+ SugarCRM::Module.register_all(SugarCRM.session)
33
+ assert SugarCRM.modules.size > 0
34
+ assert SugarCRM.session.namespace_const.const_defined? 'User'
35
+ end
36
+ end
37
+
38
+ context "The SugarCRM class" do
39
+ should "return current user" do
40
+ current_user = SugarCRM.current_user
41
+ assert_instance_of SugarCRM::User, current_user
42
+ assert_equal SugarCRM.config[:username], current_user.user_name
43
+ end
44
+
45
+ should "implement reload!" do
46
+ assert_nothing_raised do
47
+ SugarCRM.reload!
48
+ end
49
+ end
50
+ end
51
+ end
@@ -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": "&quot;OMG HAI!&quot;" }
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": "&quot;OMG HAI!&quot;"}')
31
+ end
32
+
33
+ end
34
+ end
35
+
@@ -0,0 +1,26 @@
1
+ require 'helper'
2
+
3
+ class TestResponse < ActiveSupport::TestCase
4
+ context "A SugarCRM::Response instance" do
5
+ setup do
6
+ @json = {"entry_list"=> [{
7
+ "name_value_list"=> {
8
+ "address_city" => {"name"=>"address_city", "value"=>""},
9
+ "receive_notifications" => {"name"=>"receive_notifications", "value"=>"1"},
10
+ "is_group" => {"name"=>"is_group", "value"=>"0"},
11
+ "pwd_last_changed" => {"name"=>"pwd_last_changed", "value"=>"never"}
12
+ },
13
+ "id"=>"1",
14
+ "module_name"=>"Users"
15
+ }],
16
+ "relationship_list"=>[]}
17
+
18
+ @response = SugarCRM::Response.handle(@json, SugarCRM.session)
19
+ end
20
+
21
+ should "return an instance of a SugarCRM Module" do
22
+ assert_instance_of SugarCRM::User, @response
23
+ end
24
+
25
+ end
26
+ end