qbfc 0.1.0-x86-mswin32-60
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/MIT-LICENSE +20 -0
- data/README +41 -0
- data/Rakefile +82 -0
- data/lib/qbfc.rb +39 -0
- data/lib/qbfc/base.rb +82 -0
- data/lib/qbfc/element.rb +178 -0
- data/lib/qbfc/entities/generated.rb +8 -0
- data/lib/qbfc/entity.rb +11 -0
- data/lib/qbfc/info.rb +42 -0
- data/lib/qbfc/infos/generated.rb +9 -0
- data/lib/qbfc/item.rb +10 -0
- data/lib/qbfc/items/generated.rb +11 -0
- data/lib/qbfc/list.rb +84 -0
- data/lib/qbfc/lists/generated.rb +15 -0
- data/lib/qbfc/lists/qb_class.rb +25 -0
- data/lib/qbfc/modifiable.rb +31 -0
- data/lib/qbfc/ole_wrapper.rb +193 -0
- data/lib/qbfc/qb_collection.rb +26 -0
- data/lib/qbfc/qb_types.rb +34 -0
- data/lib/qbfc/qbfc_const.rb +14 -0
- data/lib/qbfc/request.rb +158 -0
- data/lib/qbfc/session.rb +136 -0
- data/lib/qbfc/terms.rb +10 -0
- data/lib/qbfc/terms/generated.rb +10 -0
- data/lib/qbfc/transaction.rb +83 -0
- data/lib/qbfc/transactions/generated.rb +18 -0
- data/lib/qbfc/voidable.rb +11 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/unit/base_spec.rb +138 -0
- data/spec/unit/element_finder_spec.rb +180 -0
- data/spec/unit/element_spec.rb +118 -0
- data/spec/unit/entities/generated_spec.rb +18 -0
- data/spec/unit/entity_spec.rb +18 -0
- data/spec/unit/info/generated_spec.rb +12 -0
- data/spec/unit/info_spec.rb +48 -0
- data/spec/unit/item_spec.rb +18 -0
- data/spec/unit/items/generated_spec.rb +16 -0
- data/spec/unit/list_finders_spec.rb +128 -0
- data/spec/unit/list_spec.rb +86 -0
- data/spec/unit/lists/generated_spec.rb +15 -0
- data/spec/unit/lists/qb_class_spec.rb +9 -0
- data/spec/unit/modifiable_spec.rb +84 -0
- data/spec/unit/ole_wrapper_spec.rb +293 -0
- data/spec/unit/qb_collection_spec.rb +13 -0
- data/spec/unit/qbfc_const_spec.rb +10 -0
- data/spec/unit/qbfc_spec.rb +10 -0
- data/spec/unit/request_query_survey.txt +48 -0
- data/spec/unit/request_spec.rb +236 -0
- data/spec/unit/session_spec.rb +138 -0
- data/spec/unit/terms/generated_spec.rb +14 -0
- data/spec/unit/terms_spec.rb +18 -0
- data/spec/unit/transaction_finders_spec.rb +124 -0
- data/spec/unit/transaction_spec.rb +94 -0
- data/spec/unit/transactions/generated_spec.rb +20 -0
- data/spec/unit/voidable_spec.rb +32 -0
- metadata +140 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
module QBFC
|
2
|
+
|
3
|
+
# Generated Transaction types
|
4
|
+
TXN_TYPES = %w{ARRefundCreditCard Bill BillPaymentCheck BillPaymentCreditCard BuildAssembly Charge Check CreditCardCharge
|
5
|
+
CreditCardCredit CreditMemo Deposit Estimate InventoryAdjustment Invoice ItemReceipt JournalEntry PurchaseOrder
|
6
|
+
ReceivePayment SalesOrder SalesReceipt SalesTaxPaymentCheck TimeTracking VehicleMileage VendorCredit}
|
7
|
+
|
8
|
+
# Generated Transaction types that support TxnVoid Request
|
9
|
+
TXN_VOIDABLE_TYPES = %w{ARRefundCreditCard Bill BillPaymentCheck BillPaymentCreditCard Charge Check CreditCardCharge CreditCardCredit
|
10
|
+
CreditMemo Deposit InventoryAdjustment Invoice ItemReceipt JournalEntry SalesReceipt VendorCredit}
|
11
|
+
|
12
|
+
# Generated Transaction types that don't support Mod Requests
|
13
|
+
TXN_NO_MOD_TYPES = %w{ARRefundCreditCard BillPaymentCreditCard Deposit InventoryAdjustment VehicleMileage VendorCredit }
|
14
|
+
|
15
|
+
# Generate Transaction subclasses
|
16
|
+
generate(TXN_TYPES, Transaction, {Modifiable => (TXN_TYPES - TXN_NO_MOD_TYPES), Voidable => TXN_VOIDABLE_TYPES})
|
17
|
+
|
18
|
+
end
|
data/spec/rcov.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--exclude "spec/*,gems/*"
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec'
|
3
|
+
require 'spec'
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/qbfc')
|
5
|
+
|
6
|
+
Spec::Runner.configure do |config|
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
module QBFC
|
11
|
+
class Integration
|
12
|
+
FIXTURE_DIRNAME = File.dirname(__FILE__) + "\\fixtures"
|
13
|
+
FIXTURE_FILENAME = FIXTURE_DIRNAME + "\\test.qbw"
|
14
|
+
TMP_DIRNAME = File.dirname(__FILE__) + "\\tmp"
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def reader
|
18
|
+
@@reader ||= new(true)
|
19
|
+
@@reader.open_sess
|
20
|
+
@@reader
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(is_reader = false)
|
25
|
+
FileUtils.mkdir_p(TMP_DIRNAME)
|
26
|
+
|
27
|
+
@is_reader = is_reader
|
28
|
+
@@i ||= 0
|
29
|
+
@@i += 1
|
30
|
+
@dirname = TMP_DIRNAME + "\\fixture_#{@@i}"
|
31
|
+
FileUtils.rm_rf(@dirname)
|
32
|
+
FileUtils.mkdir_p(@dirname)
|
33
|
+
|
34
|
+
['lgb', 'qbw', 'qbw.ND', 'qbw.TLG'].each do |ext|
|
35
|
+
FileUtils.cp FIXTURE_DIRNAME + "\\test.#{ext}", @dirname
|
36
|
+
end
|
37
|
+
|
38
|
+
open_sess
|
39
|
+
end
|
40
|
+
|
41
|
+
def filename
|
42
|
+
File.expand_path(@dirname + "\\test.qbw").gsub(/\//, "\\")
|
43
|
+
end
|
44
|
+
|
45
|
+
def open_sess
|
46
|
+
@sess = QBFC::Session.new(:filename => filename)
|
47
|
+
end
|
48
|
+
|
49
|
+
def session
|
50
|
+
@sess
|
51
|
+
end
|
52
|
+
|
53
|
+
def close
|
54
|
+
@sess.close
|
55
|
+
unless @is_reader
|
56
|
+
sleep(5)
|
57
|
+
FileUtils.rm_rf(@dirname)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe QBFC::Base do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@sess = mock(QBFC::Session)
|
7
|
+
@ole_wrapper = mock(QBFC::OLEWrapper)
|
8
|
+
@ole_methods = ["FullName", "ListID"]
|
9
|
+
@base = QBFC::Base.new(@sess, @ole_wrapper)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "requires a QBFC:Session argument" do
|
13
|
+
lambda {QBFC::Base.new()}.should raise_error
|
14
|
+
lambda {QBFC::Base.new(@sess)}.should_not raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it "initializes with an optional ole_object argument" do
|
18
|
+
lambda {QBFC::Base.new(@sess, @ole_wrapper)}.should_not raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should wrap (only) a WIN32OLE object in an OLEWrapper" do
|
22
|
+
@ole_object = mock(WIN32OLE)
|
23
|
+
@ole_object.should_receive(:kind_of?).with(WIN32OLE).and_return(true)
|
24
|
+
QBFC::OLEWrapper.should_receive(:new).with(@ole_object).and_return(@ole_wrapper)
|
25
|
+
|
26
|
+
QBFC::Base.new(@sess, @ole_object)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not wrap non-WIN32OLE objects" do
|
30
|
+
@ole_wrapper.should_receive(:kind_of?).with(WIN32OLE).and_return(false)
|
31
|
+
QBFC::OLEWrapper.should_not_receive(:new).with(@ole_object)
|
32
|
+
|
33
|
+
QBFC::Base.new(@sess, @ole_wrapper)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "lists OLE methods for OLEWrapper object" do
|
37
|
+
@ole_wrapper.should_receive(:ole_methods).and_return(@ole_methods)
|
38
|
+
@base.ole_methods.should be(@ole_methods)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has a respond_to_ole? method" do
|
42
|
+
@ole_wrapper.should_receive(:respond_to_ole?).with("FullName").and_return(true)
|
43
|
+
@base.respond_to_ole?("FullName").should be_true
|
44
|
+
|
45
|
+
@ole_wrapper.should_receive(:respond_to_ole?).with("NoMethod").and_return(false)
|
46
|
+
@base.respond_to_ole?("NoMethod").should be_false
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should pass unknown method calls to OLEWrapper#qbfc_method_missing" do
|
50
|
+
@ole_wrapper.should_receive(:qbfc_method_missing).with(@sess, :full_name=, "arg")
|
51
|
+
@base.full_name = "arg"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "has a qb_name class method" do
|
55
|
+
QBFC::Base.qb_name.should == "Base"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "aliases qb_name class method as an instance method" do
|
59
|
+
@base.qb_name.should == QBFC::Base.qb_name
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should create_query" do
|
63
|
+
QBFC::Request.should_receive(:new).with(@sess, "BaseQuery")
|
64
|
+
QBFC::Base.__send__(:create_query, @sess)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should should respond to is_base_class? with false" do
|
68
|
+
QBFC::Base.is_base_class?.should be_false
|
69
|
+
end
|
70
|
+
|
71
|
+
describe ".parse_find_args" do
|
72
|
+
before(:each) do
|
73
|
+
@options = {:include_items => true, :owner_id => 0, :conditions => {}}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should return a Request object if given one" do
|
77
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
|
78
|
+
rq.should be(@request)
|
79
|
+
|
80
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
|
81
|
+
rq.should be(@request)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return nil request if no Request given" do
|
85
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
|
86
|
+
rq.should be_nil
|
87
|
+
|
88
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
|
89
|
+
rq.should be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return options if given them" do
|
93
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
|
94
|
+
opt.should be(@options)
|
95
|
+
|
96
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
|
97
|
+
opt.should be(@options)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return an empty hash for options if not given them" do
|
101
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
|
102
|
+
opt.should == {}
|
103
|
+
|
104
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
|
105
|
+
opt.should == {}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return base_options if is_base_class?" do
|
109
|
+
rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, {})
|
110
|
+
base_opt.should == {}
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should make base_options and options separate objects" do
|
114
|
+
rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
|
115
|
+
base_opt.should_not be(opt)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return nil for base_options if isn't a base class" do
|
119
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, {})
|
120
|
+
base_opt.should be_nil
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should delete :conditions from base_options" do
|
124
|
+
rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
|
125
|
+
base_opt.should == {:include_items => true, :owner_id => 0}
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should delete :owner_id from options if a base class" do
|
129
|
+
rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
|
130
|
+
opt.should == {:include_items => true, :conditions => {}}
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should not delete :owner_id if not a base class" do
|
134
|
+
rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
|
135
|
+
opt.should == {:include_items => true, :owner_id => 0, :conditions => {}}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module QBFC::Test
|
4
|
+
class BaseFind < QBFC::Element
|
5
|
+
is_base_class
|
6
|
+
|
7
|
+
ID_NAME = "ListID"
|
8
|
+
|
9
|
+
def self.qb_name
|
10
|
+
"Entity"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ElementFind < QBFC::Element
|
15
|
+
def self.qb_name
|
16
|
+
"Check"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# An Element is a Transaction or a List; that is any QuickBooks objects that can
|
22
|
+
# be created, edited (possibly), deleted and read. Contrast to a Report or Info
|
23
|
+
# which are read-only.
|
24
|
+
describe QBFC::Element do
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@sess = mock(QBFC::Session)
|
28
|
+
@ole_wrapper = mock(QBFC::OLEWrapper)
|
29
|
+
@element = mock(QBFC::Test::ElementFind)
|
30
|
+
|
31
|
+
# Request related mocks
|
32
|
+
@request = mock("QBFC::Request")
|
33
|
+
@request.stub!(:kind_of?).with(QBFC::Request).and_return(true)
|
34
|
+
@request.stub!(:kind_of?).with(Hash).and_return(false)
|
35
|
+
@response = mock("QBFC::Request#response")
|
36
|
+
|
37
|
+
# Filter mock
|
38
|
+
@filter = mock("QBFC::OLEWrapper#Filter")
|
39
|
+
@request.stub!(:filter).and_return(@filter)
|
40
|
+
@filter.stub!(:max_returned=)
|
41
|
+
@request.stub!(:filter_available?).and_return(true)
|
42
|
+
@request.stub!(:apply_options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_request
|
46
|
+
QBFC::Request.stub!(:new).and_return(@request)
|
47
|
+
@request.stub!(:response).and_return(@response)
|
48
|
+
@response.stub!(:GetAt).and_return(@ole_wrapper)
|
49
|
+
@response.stub!(:ole_methods).and_return(["GetAt"])
|
50
|
+
@response.stub!(:Count).and_return(2)
|
51
|
+
|
52
|
+
QBFC::Test::ElementFind.should_receive(:new).with(@sess, @ole_wrapper).at_least(:once).and_return(@element)
|
53
|
+
end
|
54
|
+
|
55
|
+
describe ".find" do
|
56
|
+
|
57
|
+
it "should find_by_unique_id if the 'what' argument is neither :all nor :first" do
|
58
|
+
QBFC::Test::ElementFind::should_receive(:find_by_unique_id).with(@sess, "123-456", {})
|
59
|
+
QBFC::Test::ElementFind::find(@sess, "123-456", {})
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return only first entry if 'what' argument is :first" do
|
63
|
+
setup_request
|
64
|
+
QBFC::Test::ElementFind::find(@sess, :first).should be(@element)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should set request#max_returned to 1 if :first" do
|
68
|
+
setup_request
|
69
|
+
@request.should_receive(:filter).and_return(@filter)
|
70
|
+
@request.stub!(:filter_available?).and_return(true)
|
71
|
+
@filter.should_receive(:max_returned=).with(1)
|
72
|
+
QBFC::Test::ElementFind::find(@sess, :first)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not set request#max_returned if not request.filter_available?" do
|
76
|
+
setup_request
|
77
|
+
@request.stub!(:filter_available?).and_return(false)
|
78
|
+
@request.should_not_receive(:filter)
|
79
|
+
QBFC::Test::ElementFind::find(@sess, :first)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return an array if 'what' argument is :all" do
|
83
|
+
setup_request
|
84
|
+
@filter.should_not_receive(:max_returned=)
|
85
|
+
QBFC::Test::ElementFind::find(@sess, :all).should == [@element, @element]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return nil if no elements are found unless finding :first" do
|
89
|
+
QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
|
90
|
+
@request.should_receive(:response).and_return(nil)
|
91
|
+
QBFC::Test::ElementFind::find(@sess, :first).should be_nil
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return an empty array if no elements are found when finding :all" do
|
95
|
+
QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
|
96
|
+
@request.should_receive(:response).and_return(nil)
|
97
|
+
QBFC::Test::ElementFind::find(@sess, :first).should be_nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "can accept a Request object"
|
101
|
+
it "generates a Request object if not given one"
|
102
|
+
it "accepts conditions"
|
103
|
+
|
104
|
+
it "applies options to request" do
|
105
|
+
setup_request
|
106
|
+
@request.should_receive(:apply_options).with({:owner_id => 0})
|
107
|
+
QBFC::Test::ElementFind::find(@sess, :first, :owner_id => 0)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "passes additional arguments to Request"
|
111
|
+
|
112
|
+
it "should get request#response" do
|
113
|
+
setup_request
|
114
|
+
@request.should_receive(:response).and_return(@response)
|
115
|
+
QBFC::Test::ElementFind::find(@sess, :first)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should call base_class_find for base classes" do
|
119
|
+
QBFC::Request.stub!(:new).and_return(@request)
|
120
|
+
QBFC::Test::BaseFind.should_receive(:base_class_find).with(@sess, :first, @request, {}).and_return(@element)
|
121
|
+
QBFC::Test::BaseFind::find(@sess, :first, {}).should be(@element)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should not call base_class_find for non-base classes" do
|
125
|
+
setup_request
|
126
|
+
QBFC::Test::ElementFind.should_not_receive(:base_class_find)
|
127
|
+
QBFC::Test::ElementFind::find(@sess, :first, {})
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe ".base_class_find" do
|
132
|
+
before(:each) do
|
133
|
+
@request.stub!(:IncludeRetElementList).and_return(@include_list)
|
134
|
+
@include_list.stub!(:Add).with("ListID")
|
135
|
+
@request.stub!(:response).and_return(@response)
|
136
|
+
QBFC::Request.stub!(:new).and_return(@request)
|
137
|
+
|
138
|
+
@element = mock(QBFC::Test::ElementFind)
|
139
|
+
@base_element = mock(QBFC::Test::BaseFind)
|
140
|
+
@customer_ret = mock("CustomerRet")
|
141
|
+
@base_element.stub!(:ole_methods).and_return(["CustomerRet"])
|
142
|
+
@base_element.stub!(:CustomerRet).and_return(@customer_ret)
|
143
|
+
@customer_ret.stub!(:ListID).and_return("123-456")
|
144
|
+
QBFC::Customer.stub!(:find_by_id).and_return(@element)
|
145
|
+
|
146
|
+
@response.stub!(:GetAt).and_return(@base_element)
|
147
|
+
@response.stub!(:Count).and_return(2)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should request only ListID" do
|
151
|
+
@include_list.should_receive(:Add).with("ListID")
|
152
|
+
QBFC::Test::BaseFind.find(@sess, :first, @request, {})
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should send class ChildList::find_by_id with ListID and find options for each" do
|
156
|
+
@base_element.should_receive(:CustomerRet).at_least(:once).and_return(@customer_ret)
|
157
|
+
@customer_ret.should_receive(:ListID).at_least(:once).and_return("789-012")
|
158
|
+
QBFC::Customer.should_receive(:find_by_id).at_least(:once).with(@sess, "789-012", {}).and_return(@element)
|
159
|
+
QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should return nil if no records and not :all" do
|
163
|
+
@request.should_receive(:response).and_return(nil)
|
164
|
+
QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be_nil
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should return nil if no records and not :all" do
|
168
|
+
@request.should_receive(:response).and_return(nil)
|
169
|
+
QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == []
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should return single record unless :all" do
|
173
|
+
QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should return Array if :all" do
|
177
|
+
QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == [@element, @element]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module QBFC::Test
|
4
|
+
class BaseKlass < QBFC::Element
|
5
|
+
is_base_class
|
6
|
+
end
|
7
|
+
|
8
|
+
class NormalKlass < QBFC::Element
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# An Element is a Transaction or a List; that is any QuickBooks objects that can
|
13
|
+
# be created, edited (possibly), deleted and read. Contrast to a Report or Info
|
14
|
+
# which are read-only.
|
15
|
+
describe QBFC::Element do
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
@sess = mock(QBFC::Session)
|
19
|
+
@ole_wrapper = mock(QBFC::OLEWrapper)
|
20
|
+
@ole_object = mock(WIN32OLE)
|
21
|
+
@ole_methods = ["FullName", "DataExtRetList"]
|
22
|
+
@element = QBFC::Test::NormalKlass.new(@sess, @ole_wrapper)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#initialize" do
|
26
|
+
it "should set up add request if ole_object is nil" do
|
27
|
+
@request = mock(QBFC::Request)
|
28
|
+
@request.should_receive(:ole_object).and_return(@ole_object)
|
29
|
+
QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
|
30
|
+
QBFC::Test::NormalKlass.new(@sess)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should assign the Add request as the @setter" do
|
34
|
+
@request = mock(QBFC::Request)
|
35
|
+
@request.stub!(:ole_object).and_return(@ole_object)
|
36
|
+
QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
|
37
|
+
QBFC::Test::NormalKlass.new(@sess).
|
38
|
+
instance_variable_get(:@setter).should == @request
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should error if class is_base_class?" do
|
42
|
+
lambda {
|
43
|
+
QBFC::Test::BaseKlass.new(@sess)
|
44
|
+
}.should raise_error(QBFC::BaseClassNewError)
|
45
|
+
|
46
|
+
lambda {
|
47
|
+
QBFC::Test::BaseKlass.new(@sess, @ole_wrapper)
|
48
|
+
}.should raise_error(QBFC::BaseClassNewError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#new_record?" do
|
53
|
+
before(:each) do
|
54
|
+
@request = mock(QBFC::Request)
|
55
|
+
@request.stub!(:ole_object).and_return(@ole_object)
|
56
|
+
QBFC::Request.stub!(:new).with(@sess, "NormalKlassAdd").and_return(@request)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return true if ole_object is an AddRq" do
|
60
|
+
QBFC::Test::NormalKlass.new(@sess).new_record?.should be_true
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return false if ole_object is from a QueryRq" do
|
64
|
+
@element.new_record?.should be_false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe ".is_base_class? (and is_base_class macro)" do
|
69
|
+
it "should return true if Class is_base_class has been called" do
|
70
|
+
QBFC::Test::BaseKlass.is_base_class?.should be_true
|
71
|
+
QBFC::Test::NormalKlass.is_base_class?.should be_false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#custom" do
|
76
|
+
before(:each) do
|
77
|
+
@data_ext = mock("QBFC::OLEWrapper#DataExtRet")
|
78
|
+
@data_ext_list = [@data_ext, @data_ext]
|
79
|
+
@ole_wrapper.stub!(:DataExtRetList).and_return(@data_ext_list)
|
80
|
+
@ole_wrapper.stub!(:data_ext).and_return(@data_ext_list)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should get custom fields" do
|
84
|
+
@data_ext.should_receive(:data_ext_name).and_return("Custom Field")
|
85
|
+
@data_ext.should_receive(:owner_id).and_return(0)
|
86
|
+
@data_ext.should_receive(:data_ext_value).and_return("Hello")
|
87
|
+
|
88
|
+
@element.custom("Custom Field").should == "Hello"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return nil if there are no custom fields" do
|
92
|
+
@ole_wrapper.should_receive(:DataExtRetList).and_return(nil)
|
93
|
+
|
94
|
+
@element.custom("Custom Field").should be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return nil if the custom field is not found" do
|
98
|
+
@data_ext.should_receive(:data_ext_name).twice.and_return("Custom Field")
|
99
|
+
|
100
|
+
@element.custom("No Field").should be_nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#save" do
|
105
|
+
it "should submit the setter object" do
|
106
|
+
@request = mock(QBFC::Request)
|
107
|
+
@request.stub!(:ole_object).and_return(@ole_object)
|
108
|
+
QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
|
109
|
+
@request.should_receive(:submit)
|
110
|
+
|
111
|
+
QBFC::Test::NormalKlass.new(@sess).save
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should raise an error if there is no setter object" do
|
115
|
+
lambda { @element.save}.should raise_error(QBFC::NotSavableError)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|