business-central 1.0.1 → 1.0.6
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.
- checksums.yaml +4 -4
- data/README.md +58 -15
- data/lib/business_central.rb +47 -2
- data/lib/business_central/client.rb +82 -39
- data/lib/business_central/exceptions.rb +30 -10
- data/lib/business_central/object/account.rb +4 -12
- data/lib/business_central/object/aged_account_payable.rb +4 -12
- data/lib/business_central/object/aged_account_receivable.rb +4 -12
- data/lib/business_central/object/argument_helper.rb +22 -0
- data/lib/business_central/object/attachment.rb +30 -0
- data/lib/business_central/object/balance_sheet.rb +4 -12
- data/lib/business_central/object/base.rb +100 -49
- data/lib/business_central/object/cash_flow_statement.rb +4 -12
- data/lib/business_central/object/company.rb +9 -2
- data/lib/business_central/object/company_information.rb +7 -15
- data/lib/business_central/object/country_region.rb +26 -0
- data/lib/business_central/object/currency.rb +29 -0
- data/lib/business_central/object/customer.rb +34 -0
- data/lib/business_central/object/customer_financial_detail.rb +13 -0
- data/lib/business_central/object/customer_payment.rb +43 -0
- data/lib/business_central/object/customer_payment_journal.rb +25 -0
- data/lib/business_central/object/customer_sale.rb +13 -0
- data/lib/business_central/object/default_dimension.rb +51 -0
- data/lib/business_central/object/dimension.rb +20 -0
- data/lib/business_central/object/dimension_line.rb +37 -0
- data/lib/business_central/object/dimension_value.rb +28 -0
- data/lib/business_central/object/employee.rb +21 -0
- data/lib/business_central/object/filter_query.rb +18 -0
- data/lib/business_central/object/general_ledger_entry.rb +13 -0
- data/lib/business_central/object/income_statement.rb +13 -0
- data/lib/business_central/object/irs1099_code.rb +16 -0
- data/lib/business_central/object/item.rb +16 -19
- data/lib/business_central/object/item_category.rb +16 -0
- data/lib/business_central/object/journal.rb +29 -0
- data/lib/business_central/object/journal_line.rb +48 -0
- data/lib/business_central/object/object_helper.rb +49 -0
- data/lib/business_central/object/payment_method.rb +16 -0
- data/lib/business_central/object/payment_term.rb +16 -0
- data/lib/business_central/object/picture.rb +53 -0
- data/lib/business_central/object/purchase_invoice.rb +8 -16
- data/lib/business_central/object/purchase_invoice_line.rb +14 -18
- data/lib/business_central/object/request.rb +61 -50
- data/lib/business_central/object/response.rb +31 -23
- data/lib/business_central/object/retained_earning_statement.rb +13 -0
- data/lib/business_central/object/sales_credit_memo.rb +20 -0
- data/lib/business_central/object/sales_credit_memo_line.rb +30 -0
- data/lib/business_central/object/sales_invoice.rb +62 -0
- data/lib/business_central/object/sales_invoice_line.rb +30 -0
- data/lib/business_central/object/sales_order.rb +20 -0
- data/lib/business_central/object/sales_order_line.rb +30 -0
- data/lib/business_central/object/sales_quote.rb +20 -0
- data/lib/business_central/object/sales_quote_line.rb +30 -0
- data/lib/business_central/object/shipment_method.rb +16 -0
- data/lib/business_central/object/subscription.rb +16 -0
- data/lib/business_central/object/tax_area.rb +16 -0
- data/lib/business_central/object/tax_group.rb +16 -0
- data/lib/business_central/object/time_registration_entry.rb +16 -0
- data/lib/business_central/object/trial_balance.rb +13 -0
- data/lib/business_central/object/units_of_measure.rb +16 -0
- data/lib/business_central/object/url_builder.rb +59 -0
- data/lib/business_central/object/url_helper.rb +44 -0
- data/lib/business_central/object/validation.rb +10 -7
- data/lib/business_central/object/vendor.rb +12 -15
- data/lib/business_central/object/vendor_purchase.rb +13 -0
- data/lib/business_central/version.rb +4 -2
- data/lib/business_central/web_service.rb +78 -0
- data/lib/core_ext/string.rb +18 -12
- data/test/business_central/client_test.rb +49 -7
- data/test/business_central/object/account_test.rb +6 -5
- data/test/business_central/object/aged_account_payable_test.rb +6 -5
- data/test/business_central/object/aged_account_receivable_test.rb +6 -5
- data/test/business_central/object/attachment_test.rb +117 -0
- data/test/business_central/object/balance_sheet_test.rb +6 -5
- data/test/business_central/object/base_test.rb +41 -0
- data/test/business_central/object/cash_flow_statement_test.rb +6 -5
- data/test/business_central/object/company_information_test.rb +9 -10
- data/test/business_central/object/company_test.rb +6 -5
- data/test/business_central/object/country_region_test.rb +129 -0
- data/test/business_central/object/currency_test.rb +150 -0
- data/test/business_central/object/customer_financial_detail_test.rb +68 -0
- data/test/business_central/object/customer_payment_journal_test.rb +134 -0
- data/test/business_central/object/customer_payment_test.rb +141 -0
- data/test/business_central/object/customer_sale_test.rb +72 -0
- data/test/business_central/object/customer_test.rb +168 -0
- data/test/business_central/object/default_dimension_test.rb +170 -0
- data/test/business_central/object/dimension_line_test.rb +165 -0
- data/test/business_central/object/dimension_test.rb +65 -0
- data/test/business_central/object/dimension_value_test.rb +68 -0
- data/test/business_central/object/employee_test.rb +141 -0
- data/test/business_central/object/filter_query_test.rb +36 -0
- data/test/business_central/object/general_ledger_entry_test.rb +82 -0
- data/test/business_central/object/income_statement_test.rb +82 -0
- data/test/business_central/object/irs1099_code_test.rb +124 -0
- data/test/business_central/object/item_category_test.rb +122 -0
- data/test/business_central/object/item_test.rb +16 -17
- data/test/business_central/object/journal_line_test.rb +152 -0
- data/test/business_central/object/journal_test.rb +144 -0
- data/test/business_central/object/payment_method_test.rb +134 -0
- data/test/business_central/object/payment_term_test.rb +134 -0
- data/test/business_central/object/picture_test.rb +74 -0
- data/test/business_central/object/purchase_invoice_line_test.rb +15 -15
- data/test/business_central/object/purchase_invoice_test.rb +15 -15
- data/test/business_central/object/request_test.rb +75 -12
- data/test/business_central/object/response_test.rb +34 -9
- data/test/business_central/object/retained_earning_statement_test.rb +52 -0
- data/test/business_central/object/sales_credit_memo_line_test.rb +134 -0
- data/test/business_central/object/sales_credit_memo_test.rb +146 -0
- data/test/business_central/object/sales_invoice_line_test.rb +164 -0
- data/test/business_central/object/sales_invoice_test.rb +156 -0
- data/test/business_central/object/sales_order_line_test.rb +134 -0
- data/test/business_central/object/sales_order_test.rb +146 -0
- data/test/business_central/object/sales_quote_line_test.rb +134 -0
- data/test/business_central/object/sales_quote_test.rb +146 -0
- data/test/business_central/object/shipment_method_test.rb +133 -0
- data/test/business_central/object/subscription_test.rb +126 -0
- data/test/business_central/object/tax_area_test.rb +126 -0
- data/test/business_central/object/tax_group_test.rb +126 -0
- data/test/business_central/object/time_registration_entry_test.rb +126 -0
- data/test/business_central/object/trial_balance_test.rb +82 -0
- data/test/business_central/object/units_of_measure_test.rb +126 -0
- data/test/business_central/object/validation_test.rb +5 -4
- data/test/business_central/object/vendor_purchase_test.rb +82 -0
- data/test/business_central/object/vendor_test.rb +16 -16
- data/test/business_central/web_service_test.rb +100 -0
- data/test/business_central_test.rb +3 -1
- data/test/test_helper.rb +16 -6
- metadata +188 -37
- data/lib/business_central/object/helper.rb +0 -15
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BusinessCentral
|
4
|
+
module Object
|
5
|
+
class URLBuilder
|
6
|
+
extend URLHelper
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def sanitize(query = '', values = [])
|
10
|
+
return encode_url_params(query) if values.length.zero?
|
11
|
+
|
12
|
+
query = replace_template_with_value(query, values)
|
13
|
+
encode_url_object(query)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(base_url:, parent_path: [], child_path: '', child_id: '', child_code: '', filter: '')
|
18
|
+
@base_url = base_url.to_s
|
19
|
+
@parent_path = parent_path || []
|
20
|
+
@child_path = child_path.to_s
|
21
|
+
@child_id = child_id.to_s
|
22
|
+
@child_code = child_code.to_s
|
23
|
+
@filter = filter.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def build
|
27
|
+
url = @base_url
|
28
|
+
url += build_parent_path
|
29
|
+
url += build_child_path
|
30
|
+
url += build_filter
|
31
|
+
url
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_parent_path
|
37
|
+
return '' if @parent_path.empty?
|
38
|
+
|
39
|
+
@parent_path.map do |parent|
|
40
|
+
"/#{parent[:path]}(#{parent[:id]})" if !parent[:id].nil?
|
41
|
+
end.join('')
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_child_path
|
45
|
+
url = ''
|
46
|
+
url += "/#{@child_path}" if @child_path.present?
|
47
|
+
url += "(#{@child_id})" if @child_id.present?
|
48
|
+
url += "('#{odata_encode(@child_code)}')" if @child_code.present?
|
49
|
+
url
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_filter
|
53
|
+
url = ''
|
54
|
+
url += "?$filter=#{@filter}" if @filter.present?
|
55
|
+
url
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BusinessCentral
|
4
|
+
module Object
|
5
|
+
module URLHelper
|
6
|
+
def encode_url_object(object)
|
7
|
+
URI::RFC2396_Parser.new.escape(object)
|
8
|
+
end
|
9
|
+
|
10
|
+
def encode_url_params(query)
|
11
|
+
CGI.escape(query)
|
12
|
+
end
|
13
|
+
|
14
|
+
def odata_encode(value)
|
15
|
+
value = value.dup
|
16
|
+
value.gsub!(/'/, "''") if value =~ /'/
|
17
|
+
value.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def replace_template_with_value(query, values)
|
23
|
+
query = query.dup
|
24
|
+
return replace_template_with_hash_values(query, values) if values.first.is_a?(Hash)
|
25
|
+
replace_template_with_array_values(query, values)
|
26
|
+
end
|
27
|
+
|
28
|
+
def replace_template_with_hash_values(query, values)
|
29
|
+
values.first.each do |key, value|
|
30
|
+
query.gsub!(/:#{key}/, odata_encode(value))
|
31
|
+
end
|
32
|
+
query
|
33
|
+
end
|
34
|
+
|
35
|
+
def replace_template_with_array_values(query, values)
|
36
|
+
query.scan(/\?/).each_with_index do |_character, index|
|
37
|
+
character_position = query =~ /\?/
|
38
|
+
query[character_position] = odata_encode(values[index])
|
39
|
+
end
|
40
|
+
query
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BusinessCentral
|
2
4
|
module Object
|
3
5
|
class Validation
|
@@ -11,25 +13,26 @@ module BusinessCentral
|
|
11
13
|
@validation_rules.each do |rules_key, rules_value|
|
12
14
|
rules_value.each do |validation_key, validation_value|
|
13
15
|
if required?(validation_key, validation_value, @object_params[rules_key].to_s)
|
14
|
-
@errors << { field: rules_key, message: 'is a required field'}
|
16
|
+
@errors << { field: rules_key, message: 'is a required field' }
|
15
17
|
end
|
16
18
|
|
17
19
|
if exceeds_maximum_length?(validation_key, validation_value, @object_params[rules_key].to_s)
|
18
|
-
@errors << { field: rules_key, message: "has exceeded the maximum length #{validation_value}"}
|
20
|
+
@errors << { field: rules_key, message: "has exceeded the maximum length #{validation_value}" }
|
19
21
|
end
|
20
22
|
|
21
23
|
if not_inclusive_of?(validation_key, validation_value, @object_params[rules_key].to_s)
|
22
|
-
@errors << { field: rules_key, message: "is not one of #{validation_value.join(', ')}"}
|
24
|
+
@errors << { field: rules_key, message: "is not one of #{validation_value.join(', ')}" }
|
23
25
|
end
|
24
26
|
|
25
27
|
if date_type?(validation_key, validation_value, @object_params[rules_key])
|
26
|
-
@errors << { field: rules_key, message: 'is not a date'}
|
28
|
+
@errors << { field: rules_key, message: 'is not a date' }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
raise InvalidObjectException
|
32
|
-
|
33
|
+
raise InvalidObjectException, @errors if @errors.any?
|
34
|
+
|
35
|
+
true
|
33
36
|
end
|
34
37
|
|
35
38
|
private
|
@@ -51,4 +54,4 @@ module BusinessCentral
|
|
51
54
|
end
|
52
55
|
end
|
53
56
|
end
|
54
|
-
end
|
57
|
+
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BusinessCentral
|
2
4
|
module Object
|
3
5
|
class Vendor < Base
|
4
|
-
|
6
|
+
extend BusinessCentral::Object::ObjectHelper
|
7
|
+
|
8
|
+
OBJECT = 'vendors'
|
5
9
|
|
6
10
|
OBJECT_VALIDATION = {
|
7
11
|
number: {
|
@@ -24,22 +28,15 @@ module BusinessCentral
|
|
24
28
|
}
|
25
29
|
}.freeze
|
26
30
|
|
27
|
-
OBJECT_METHODS = [
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
OBJECT_METHODS = %i[
|
32
|
+
get
|
33
|
+
post
|
34
|
+
patch
|
35
|
+
delete
|
32
36
|
].freeze
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
@parent_path = [
|
37
|
-
{
|
38
|
-
path: 'companies',
|
39
|
-
id: company_id
|
40
|
-
}
|
41
|
-
]
|
42
|
-
end
|
38
|
+
navigation :default_dimension
|
39
|
+
navigation :picture
|
43
40
|
end
|
44
41
|
end
|
45
42
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BusinessCentral
|
4
|
+
class WebService
|
5
|
+
DEFAULT_URL = 'https://api.businesscentral.dynamics.com/v2.0/production/ODataV4'
|
6
|
+
|
7
|
+
attr_reader :url, :object_url
|
8
|
+
|
9
|
+
def initialize(client:, **options)
|
10
|
+
@client = client
|
11
|
+
opts = options.dup
|
12
|
+
@url = opts.delete(:url) || DEFAULT_URL
|
13
|
+
end
|
14
|
+
|
15
|
+
def object(object_url = '', *values)
|
16
|
+
if values.length.zero?
|
17
|
+
@object_url = object_url
|
18
|
+
return self
|
19
|
+
end
|
20
|
+
|
21
|
+
@object_url = Object::URLBuilder.sanitize(object_url, values)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(query = '', *values)
|
26
|
+
raise InvalidObjectURLException if @object_url.to_s.blank?
|
27
|
+
|
28
|
+
Object::Request.get(
|
29
|
+
@client,
|
30
|
+
build_url(
|
31
|
+
filter: Object::FilterQuery.sanitize(query, values)
|
32
|
+
)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def post(params = {})
|
37
|
+
raise InvalidObjectURLException if @object_url.to_s.blank?
|
38
|
+
|
39
|
+
Object::Request.post(
|
40
|
+
@client,
|
41
|
+
build_url,
|
42
|
+
params
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def patch(params = {})
|
47
|
+
raise InvalidObjectURLException if @object_url.to_s.blank?
|
48
|
+
|
49
|
+
object = get
|
50
|
+
Object::Request.patch(
|
51
|
+
@client,
|
52
|
+
build_url,
|
53
|
+
object[:etag],
|
54
|
+
params
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete
|
59
|
+
raise InvalidObjectURLException if @object_url.to_s.blank?
|
60
|
+
|
61
|
+
object = get
|
62
|
+
Object::Request.delete(
|
63
|
+
@client,
|
64
|
+
build_url,
|
65
|
+
object[:etag]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def build_url(filter: '')
|
72
|
+
Object::URLBuilder.new(
|
73
|
+
base_url: "#{@url}/#{@object_url}",
|
74
|
+
filter: filter
|
75
|
+
).build
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/core_ext/string.rb
CHANGED
@@ -1,25 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class String
|
2
4
|
def blank?
|
3
5
|
empty? || /\A[[:space:]]*\z/.match?(self)
|
4
6
|
end
|
5
7
|
|
8
|
+
def present?
|
9
|
+
!blank?
|
10
|
+
end
|
11
|
+
|
6
12
|
# Convert string to CamelCase
|
7
13
|
def to_camel_case(uppercase_first_letter = false)
|
8
14
|
string = self
|
9
|
-
if uppercase_first_letter
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
string.gsub(
|
15
|
+
string = if uppercase_first_letter
|
16
|
+
string.sub(/^[a-z\d]*/, &:capitalize)
|
17
|
+
else
|
18
|
+
string.sub(/^(?:(?=\b|[A-Z_])|\w)/, &:downcase)
|
19
|
+
end
|
20
|
+
string.gsub(%r{(?:_|(/))([a-z\d]*)}) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }.gsub('/', '::')
|
15
21
|
end
|
16
22
|
|
17
23
|
# Convert string to snake_case
|
18
24
|
def to_snake_case
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
gsub(/::/, '/')
|
26
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
27
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
28
|
+
.tr('-', '_')
|
29
|
+
.downcase
|
24
30
|
end
|
25
|
-
end
|
31
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
2
4
|
# rake test TEST=test/business_central/client_test.rb
|
3
5
|
|
4
6
|
class BusinessCentral::ClientTest < Minitest::Test
|
@@ -9,15 +11,15 @@ class BusinessCentral::ClientTest < Minitest::Test
|
|
9
11
|
def test_authorize_client
|
10
12
|
test_redirect_url = 'www.example.com'
|
11
13
|
response = @client.authorize(oauth_authorize_callback: test_redirect_url)
|
12
|
-
assert_match
|
13
|
-
assert_match
|
14
|
+
assert_match(%r{oauth2/authorize?}, response)
|
15
|
+
assert_match(/redirect_uri=#{test_redirect_url}/, response)
|
14
16
|
end
|
15
17
|
|
16
18
|
def test_request_client_token
|
17
19
|
test_redirect_url = 'www.example.com'
|
18
20
|
test_access_token = '123'
|
19
21
|
|
20
|
-
stub_request(:post, /
|
22
|
+
stub_request(:post, /#{BusinessCentral::Client::DEFAULT_LOGIN_URL}/)
|
21
23
|
.to_return(
|
22
24
|
status: 200,
|
23
25
|
headers: {
|
@@ -32,7 +34,7 @@ class BusinessCentral::ClientTest < Minitest::Test
|
|
32
34
|
)
|
33
35
|
|
34
36
|
response = @client.request_token('code123', oauth_token_callback: test_redirect_url)
|
35
|
-
assert_equal test_access_token,response.token
|
37
|
+
assert_equal test_access_token, response.token
|
36
38
|
end
|
37
39
|
|
38
40
|
def test_authorize_client_from_token
|
@@ -56,7 +58,7 @@ class BusinessCentral::ClientTest < Minitest::Test
|
|
56
58
|
expires_in: 3600
|
57
59
|
)
|
58
60
|
|
59
|
-
stub_request(:post, /
|
61
|
+
stub_request(:post, /#{BusinessCentral::Client::DEFAULT_LOGIN_URL}/)
|
60
62
|
.to_return(
|
61
63
|
status: 200,
|
62
64
|
headers: {
|
@@ -74,4 +76,44 @@ class BusinessCentral::ClientTest < Minitest::Test
|
|
74
76
|
assert_equal test_access_token, response.token
|
75
77
|
end
|
76
78
|
|
77
|
-
|
79
|
+
def test_authorize_throws_exception
|
80
|
+
stub_request(:get, BusinessCentral::Client::DEFAULT_LOGIN_URL)
|
81
|
+
.to_return(status: 200, body: '', headers: {})
|
82
|
+
|
83
|
+
mock = MiniTest::Mock.new
|
84
|
+
def mock.authorize_url(_arguments)
|
85
|
+
response = Faraday.get(BusinessCentral::Client::DEFAULT_LOGIN_URL)
|
86
|
+
response = OAuth2::Response.new(response)
|
87
|
+
raise OAuth2::Error, response
|
88
|
+
end
|
89
|
+
|
90
|
+
OAuth2::Strategy::AuthCode.stub(:new, mock) do
|
91
|
+
assert_raises(BusinessCentral::ApiException) do
|
92
|
+
@client.authorize
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_request_token_throws_exception
|
98
|
+
stub_request(:get, BusinessCentral::Client::DEFAULT_URL)
|
99
|
+
.to_return(status: 200, body: '', headers: {})
|
100
|
+
|
101
|
+
mock = MiniTest::Mock.new
|
102
|
+
def mock.get_token(*_params)
|
103
|
+
response = Faraday.get(BusinessCentral::Client::DEFAULT_URL)
|
104
|
+
response = OAuth2::Response.new(response)
|
105
|
+
raise OAuth2::Error, response
|
106
|
+
end
|
107
|
+
|
108
|
+
OAuth2::Strategy::AuthCode.stub(:new, mock) do
|
109
|
+
assert_raises(BusinessCentral::ApiException) do
|
110
|
+
@client.request_token
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_build_web_service_object
|
116
|
+
@client.web_service.object('Company/Vendors')
|
117
|
+
assert_equal @client.web_service.object_url, 'Company/Vendors'
|
118
|
+
end
|
119
|
+
end
|