cubits 0.1.0 → 0.2.1
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/CHANGES.md +21 -0
- data/README.md +105 -12
- data/cubits.gemspec +1 -1
- data/lib/cubits/account.rb +6 -0
- data/lib/cubits/helpers.rb +61 -0
- data/lib/cubits/invoice.rb +1 -1
- data/lib/cubits/quote.rb +7 -0
- data/lib/cubits/resource.rb +36 -2
- data/lib/cubits/version.rb +1 -1
- data/lib/cubits.rb +4 -1
- data/spec/lib/cubits/account_spec.rb +9 -0
- data/spec/lib/cubits/helpers_spec.rb +12 -0
- data/spec/lib/cubits/invoice_spec.rb +12 -0
- data/spec/lib/cubits/quote_spec.rb +9 -0
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f20d1982b3ef43be0e3b9b8cbc9fea14c1cd44f
|
4
|
+
data.tar.gz: 193e702ea136342137d5c73f204e0135399051cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21fc0a0189fa63b53c738a41252700a3a0075e2097706099ff6056614be1be2564f038281cd8a4e164897544b21b64dc6e7d17c614e54d0c1d8f9a53c53aa0f2
|
7
|
+
data.tar.gz: fce9506b0b8c7d36b367f44505031981679727b0a533f8cfd633d7eafcc6bc10b58392efcce75a9f786fd09684ca11e9188b14fb9a8d4b84d8e702aee26c8613
|
data/CHANGES.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# 0.2.1
|
2
|
+
|
3
|
+
Minor fixes to README.
|
4
|
+
|
5
|
+
# 0.2.0
|
6
|
+
|
7
|
+
Implemented new API calls:
|
8
|
+
|
9
|
+
* Retrieving a list of accounts: `Cubits::Account.all`
|
10
|
+
* Get a quote for an operation: `Cubits::Quote.create(...)`
|
11
|
+
* Buy bitcoins using funds in a Cubits account: `Cubits.buy(...)`
|
12
|
+
* Sell bitcoins and credit funds to a Cubits account: `Cubits.sell(...)`
|
13
|
+
|
14
|
+
# 0.1.0
|
15
|
+
|
16
|
+
Initial release.
|
17
|
+
|
18
|
+
* Configuring connection
|
19
|
+
* Testing connection: `Cubits.available?`
|
20
|
+
* Creating, retrieving invoices: `Cubits::Invoice`
|
21
|
+
* Send bitcoins to a bitcoin address: `Cubits.send_money(...)`
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
A Ruby 1.9+ client for [Cubits](https://cubits.com) Merchant API v1.
|
4
4
|
|
5
|
-
|
5
|
+
# Installation
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
@@ -18,11 +18,11 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install cubits
|
20
20
|
|
21
|
-
|
21
|
+
# Usage
|
22
22
|
|
23
|
-
|
23
|
+
## Configuration
|
24
24
|
|
25
|
-
First thing you have to do is to
|
25
|
+
First thing you have to do is to generate your API token (key+secret) from your [Cubits Pay](https://cubits.com/merchant) account in the API integration section.
|
26
26
|
|
27
27
|
Then, configure your Cubits client:
|
28
28
|
```ruby
|
@@ -40,26 +40,25 @@ Cubits.configure(key: '***', secret: '***')
|
|
40
40
|
Cubits.available? # => true
|
41
41
|
```
|
42
42
|
|
43
|
-
|
43
|
+
## Invoices
|
44
44
|
|
45
45
|
Using the `cubits` Ruby client you can create and retrieve invoices.
|
46
46
|
|
47
|
-
Invoices are represented by `Cubits::Invoice` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash),
|
48
|
-
so it's a Hash with a method-like access to its elements:
|
47
|
+
Invoices are represented by the `Cubits::Invoice` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash), so it's a Hash with a method-like access to its elements:
|
49
48
|
|
50
49
|
```ruby
|
51
50
|
invoice.id # => "686e4238970a92f04f1f5a30035bf024"
|
52
51
|
invoice.status # => "pending"
|
53
52
|
invoice.invoice_amount # => "0.00446216"
|
54
53
|
invoice.invoice_currency # => "BTC"
|
55
|
-
invoice.address # => "
|
54
|
+
invoice.address # => "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
|
56
55
|
```
|
57
56
|
|
58
57
|
#### .create
|
59
58
|
|
60
59
|
Creates a new invoice.
|
61
60
|
|
62
|
-
For a list of accepted and returned parameters, see `POST /api/v1/invoices` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
|
61
|
+
For a list of accepted and returned parameters, see the `POST /api/v1/invoices` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
|
63
62
|
|
64
63
|
|
65
64
|
```ruby
|
@@ -77,7 +76,7 @@ Retrieves an existing invoice.
|
|
77
76
|
invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
|
78
77
|
```
|
79
78
|
|
80
|
-
Returns `Cubits::Invoice` object or `nil` if invoice was not found.
|
79
|
+
Returns `Cubits::Invoice` object or `nil` if the specified invoice was not found.
|
81
80
|
|
82
81
|
|
83
82
|
#### #reload
|
@@ -86,10 +85,104 @@ Reloads `Cubits::Invoice` object.
|
|
86
85
|
```ruby
|
87
86
|
invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
|
88
87
|
# do some stuff...
|
89
|
-
invoice.reload # gets the up-to-date invoice data from Cubits API
|
88
|
+
invoice.reload # gets the up-to-date invoice data from the Cubits API
|
90
89
|
```
|
91
90
|
|
92
|
-
|
91
|
+
## Accounts
|
92
|
+
|
93
|
+
Your Cubits accounts are represented by the `Cubits::Account` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash), so it's a Hash with a method-like access to its elements:
|
94
|
+
```ruby
|
95
|
+
account = Cubits::Account.all.first
|
96
|
+
|
97
|
+
account.currency # => "EUR"
|
98
|
+
account.balance # => "125.00"
|
99
|
+
```
|
100
|
+
|
101
|
+
#### .all
|
102
|
+
|
103
|
+
Retrieves a list of accounts.
|
104
|
+
|
105
|
+
Returns `Array` of `Cubits::Account` objects.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
Cubits::Account.all # => [{ currency: 'EUR', balance: '125.00' }, ...]
|
109
|
+
```
|
110
|
+
|
111
|
+
## Quotes
|
112
|
+
|
113
|
+
Requests a quote for a *"buy"* or *"sell"* operation.
|
114
|
+
|
115
|
+
Quotes contain information about the current Cubits exchange rate for a certain operation type of a certain amount and can serve as an estimation for subsequent buy or sell requests.
|
116
|
+
|
117
|
+
#### .create
|
118
|
+
Creates a new quote.
|
119
|
+
|
120
|
+
For a list of accepted and returned parameters, see the `POST /api/v1/quotes` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
|
121
|
+
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
quote = Cubits::Quote.create(
|
125
|
+
operation: 'buy',
|
126
|
+
sender: {
|
127
|
+
currency: 'EUR'
|
128
|
+
},
|
129
|
+
receiver: {
|
130
|
+
currency: 'BTC',
|
131
|
+
amount: '1.0'
|
132
|
+
}
|
133
|
+
)
|
134
|
+
|
135
|
+
quote.sender # => {"currency"=>"EUR", "amount"=>"172.81"}
|
136
|
+
```
|
137
|
+
|
138
|
+
Here a call to `POST /api/v1/quotes` is executed and the response is wrapped in a `Cubits::Quote` object.
|
139
|
+
|
140
|
+
|
141
|
+
## Buy bitcoins
|
142
|
+
|
143
|
+
`Cubits.buy` helper method creates a transaction to buy bitcoins using funds from your Cubits account. Bought bitcoins will be credited to your Cubits wallet.
|
144
|
+
|
145
|
+
The exact exchange rate will be calculated at the transaction execution time.
|
146
|
+
|
147
|
+
#### Parameters
|
148
|
+
Attribute | Data type | Description
|
149
|
+
------------|-------------|--------------
|
150
|
+
sender | Hash | Sender attributes define the spending part of the transaction
|
151
|
+
sender[:currency] | String | [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) code of the currency that you want to spend (e.g. "EUR")
|
152
|
+
sender[:amount] | String | Amount in specified currency to be spent, decimal number as a string (e.g. "12.50")
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
Cubits.buy sender: { currency: 'EUR', amount: '150.00' }
|
156
|
+
# => {"tx_ref_code"=>"RNXH3"}
|
157
|
+
```
|
158
|
+
|
159
|
+
On success, `.buy` creates a transaction and returns its reference code.
|
160
|
+
|
161
|
+
|
162
|
+
## Sell bitcoins
|
163
|
+
|
164
|
+
`Cubits.sell` helper method creates a transaction to sell bitcoins from your Cubits wallet and receive the according amount in the specified fiat currency. Fiat funds will be credited to your Cubits cash account.
|
165
|
+
|
166
|
+
The exact exchange rate will be calculated at the transaction execution time.
|
167
|
+
|
168
|
+
#### Parameters
|
169
|
+
Attribute | Data type | Description
|
170
|
+
------------|-------------|--------------
|
171
|
+
sender | Hash | Sender attributes define the spending part of the transaction
|
172
|
+
sender[:amount] | String | Amount in BTC to be spent, decimal number as a string (e.g. "0.01250000")
|
173
|
+
receiver | Hash | Receiver attributes define the receiving part of the transaction
|
174
|
+
receiver[:currency] | String | ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) code of the currency that you want to receive (e.g. "EUR")
|
175
|
+
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
Cubits.sell sender: { amount: '0.45000000' }, receiver: { currency: 'EUR' }
|
179
|
+
# => {"tx_ref_code"=>"4XRX3"}
|
180
|
+
```
|
181
|
+
|
182
|
+
On success, `.sell` creates a transaction and returns its reference code.
|
183
|
+
|
184
|
+
|
185
|
+
## Send money
|
93
186
|
|
94
187
|
`Cubits.send_money` helper method allows you to send Bitcoin from your Cubits Wallet to an external Bitcoin address.
|
95
188
|
|
data/cubits.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ['alex.kukushkin@cubits.com']
|
11
11
|
spec.summary = 'Ruby client for Cubits Merchant API'
|
12
12
|
spec.description = 'Ruby client for Cubits Merchant API'
|
13
|
-
spec.homepage = ''
|
13
|
+
spec.homepage = 'https://github.com/cubits/cubits-ruby'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/cubits/helpers.rb
CHANGED
@@ -31,5 +31,66 @@ module Cubits
|
|
31
31
|
amount: params[:amount], address: params[:address]
|
32
32
|
)
|
33
33
|
end
|
34
|
+
|
35
|
+
# Executes "Buy bitcoins" API call.
|
36
|
+
# Buy Bitcoins using funds in a Cubits account. Bought Bitcoins will be credited
|
37
|
+
# to your Cubits Wallet.
|
38
|
+
#
|
39
|
+
# @param params [Hash]
|
40
|
+
# @param params[:sender] [Hash] Sender attributes define spending part of transaction
|
41
|
+
# @param params[:sender][:currency] [String] ISO 4217 code of the currency, that you want
|
42
|
+
# to spend (e.g. "EUR")
|
43
|
+
# @param params[:sender][:amount] [String] Amount in specified currency to be spent,
|
44
|
+
# decimal number as a String (e.g. "12.50")
|
45
|
+
#
|
46
|
+
def buy(params)
|
47
|
+
fail ArgumentError, 'Hash is expected as params' unless params.is_a?(Hash)
|
48
|
+
fail ArgumentError, 'Hash is expected as :sender' unless params[:sender].is_a?(Hash)
|
49
|
+
sender = params[:sender]
|
50
|
+
fail ArgumentError, 'String is expected as sender[:currency]' unless sender[:currency].is_a?(String)
|
51
|
+
fail ArgumentError, 'String is expected as sender[:amount]' unless sender[:amount].is_a?(String)
|
52
|
+
fail ArgumentError, 'Invalid amount format' unless sender[:amount] =~ /^\d+\.\d+$/
|
53
|
+
Cubits.connection.post(
|
54
|
+
'/api/v1/buy',
|
55
|
+
sender: {
|
56
|
+
currency: sender[:currency],
|
57
|
+
amount: sender[:amount]
|
58
|
+
}
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Executes "Sell bitcoins" API call.
|
64
|
+
#
|
65
|
+
# Creates a transaction to sell bitcoins from your Cubits wallet and receive amount
|
66
|
+
# in specified fiat currency. Fiat funds will be credited to your Cubits account.
|
67
|
+
#
|
68
|
+
# @param params [Hash]
|
69
|
+
# @param params[:sender] [Hash] Sender attributes define spending part of transaction
|
70
|
+
# @param params[:sender][:amount] [String] Amount in bitcoins to be spent,
|
71
|
+
# decimal number as a String (e.g. "0.01250000")
|
72
|
+
# @param params[:receiver] [Hash] Receiver attributes define receiving part of transaction
|
73
|
+
# @param params[:receiver][:currency] [String] ISO 4217 code of the currency, that you want
|
74
|
+
# to receive (e.g. "EUR")
|
75
|
+
#
|
76
|
+
def sell(params)
|
77
|
+
fail ArgumentError, 'Hash is expected as params' unless params.is_a?(Hash)
|
78
|
+
fail ArgumentError, 'Hash is expected as :sender' unless params[:sender].is_a?(Hash)
|
79
|
+
sender = params[:sender]
|
80
|
+
fail ArgumentError, 'String is expected as sender[:amount]' unless sender[:amount].is_a?(String)
|
81
|
+
fail ArgumentError, 'Invalid amount format' unless sender[:amount] =~ /^\d+\.\d+$/
|
82
|
+
fail ArgumentError, 'Hash is expected as :receiver' unless params[:receiver].is_a?(Hash)
|
83
|
+
receiver = params[:receiver]
|
84
|
+
fail ArgumentError, 'String is expected as receiver[:currency]' unless receiver[:currency].is_a?(String)
|
85
|
+
Cubits.connection.post(
|
86
|
+
'/api/v1/sell',
|
87
|
+
sender: {
|
88
|
+
amount: sender[:amount]
|
89
|
+
},
|
90
|
+
receiver: {
|
91
|
+
currency: receiver[:currency]
|
92
|
+
}
|
93
|
+
)
|
94
|
+
end
|
34
95
|
end # module Helpers
|
35
96
|
end # module Cubits
|
data/lib/cubits/invoice.rb
CHANGED
data/lib/cubits/quote.rb
ADDED
data/lib/cubits/resource.rb
CHANGED
@@ -9,6 +9,24 @@ module Cubits
|
|
9
9
|
@path = p
|
10
10
|
end
|
11
11
|
|
12
|
+
# By convention collection name for the resource is the last part of the path
|
13
|
+
#
|
14
|
+
def self.collection_name
|
15
|
+
@path.split('/').last
|
16
|
+
end
|
17
|
+
|
18
|
+
# Sets exposed methods for the resource
|
19
|
+
#
|
20
|
+
def self.expose_methods(*args)
|
21
|
+
@exposed_methods = args
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return true if the method is exposed by this resource
|
25
|
+
#
|
26
|
+
def self.exposed_method?(method_name)
|
27
|
+
(@exposed_methods || []).include?(method_name)
|
28
|
+
end
|
29
|
+
|
12
30
|
# Returns API path to resource
|
13
31
|
#
|
14
32
|
def self.path_to(resource_or_id = nil)
|
@@ -22,6 +40,17 @@ module Cubits
|
|
22
40
|
end
|
23
41
|
end
|
24
42
|
|
43
|
+
# Loads collection of resources
|
44
|
+
#
|
45
|
+
# @return [Array<Resource>]
|
46
|
+
#
|
47
|
+
def self.all
|
48
|
+
fail NoMethodError, "Resource #{name} does not expose .all" unless exposed_method?(:all)
|
49
|
+
Cubits.connection.get(path_to)[collection_name].map { |r| new r }
|
50
|
+
rescue NotFound
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
25
54
|
# Loads resource
|
26
55
|
#
|
27
56
|
# @param id [String]
|
@@ -29,7 +58,8 @@ module Cubits
|
|
29
58
|
# @return nil if resource is not found
|
30
59
|
#
|
31
60
|
def self.find(id)
|
32
|
-
|
61
|
+
fail NoMethodError, "Resource #{name} does not expose .find" unless exposed_method?(:find)
|
62
|
+
new Cubits.connection.get(path_to(id))
|
33
63
|
rescue NotFound
|
34
64
|
nil
|
35
65
|
end
|
@@ -37,6 +67,9 @@ module Cubits
|
|
37
67
|
# Reloads resource
|
38
68
|
#
|
39
69
|
def reload
|
70
|
+
unless self.class.exposed_method?(:reload)
|
71
|
+
fail NoMethodError, "Resource #{self.class.name} does not expose #reload"
|
72
|
+
end
|
40
73
|
fail "Resource #{self.class.name} does not have an id" unless self.respond_to?(:id)
|
41
74
|
replace(self.class.find(id))
|
42
75
|
end
|
@@ -44,7 +77,8 @@ module Cubits
|
|
44
77
|
# Creates a new resource
|
45
78
|
#
|
46
79
|
def self.create(params = {})
|
47
|
-
|
80
|
+
fail NoMethodError, "Resource #{name} does not expose .create" unless exposed_method?(:create)
|
81
|
+
new Cubits.connection.post(path_to, params)
|
48
82
|
end
|
49
83
|
end # class Resource
|
50
84
|
end # module Cubits
|
data/lib/cubits/version.rb
CHANGED
data/lib/cubits.rb
CHANGED
@@ -6,6 +6,8 @@ require 'cubits/errors'
|
|
6
6
|
require 'cubits/helpers'
|
7
7
|
require 'cubits/resource'
|
8
8
|
require 'cubits/invoice'
|
9
|
+
require 'cubits/account'
|
10
|
+
require 'cubits/quote'
|
9
11
|
|
10
12
|
module Cubits
|
11
13
|
extend Cubits::Helpers
|
@@ -50,9 +52,10 @@ module Cubits
|
|
50
52
|
|
51
53
|
# Sets new base API URL
|
52
54
|
#
|
53
|
-
# @param new_base_url [URI]
|
55
|
+
# @param new_base_url [URI,String]
|
54
56
|
#
|
55
57
|
def self.base_url=(new_base_url)
|
58
|
+
new_base_url = URI.parse(new_base_url) if new_base_url.is_a?(String)
|
56
59
|
fail ArgumentError, 'URI is expected as new_base_url' unless new_base_url.is_a?(URI)
|
57
60
|
@base_url = new_base_url
|
58
61
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cubits do
|
4
|
+
context 'class methods,' do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to(:available?) }
|
8
|
+
it { is_expected.to respond_to(:send_money) }
|
9
|
+
it { is_expected.to respond_to(:buy) }
|
10
|
+
it { is_expected.to respond_to(:sell) }
|
11
|
+
end # class methods
|
12
|
+
end # describe Cubits::Account
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cubits::Invoice do
|
4
|
+
context 'class methods,' do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to(:create) }
|
8
|
+
it { is_expected.to respond_to(:find) }
|
9
|
+
end # class methods
|
10
|
+
|
11
|
+
it { is_expected.to respond_to(:reload) }
|
12
|
+
end # describe Cubits::Invoice
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cubits
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kukushkin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|
@@ -102,22 +102,29 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
|
+
- CHANGES.md
|
105
106
|
- Gemfile
|
106
107
|
- LICENSE.txt
|
107
108
|
- README.md
|
108
109
|
- Rakefile
|
109
110
|
- cubits.gemspec
|
110
111
|
- lib/cubits.rb
|
112
|
+
- lib/cubits/account.rb
|
111
113
|
- lib/cubits/connection.rb
|
112
114
|
- lib/cubits/errors.rb
|
113
115
|
- lib/cubits/helpers.rb
|
114
116
|
- lib/cubits/invoice.rb
|
117
|
+
- lib/cubits/quote.rb
|
115
118
|
- lib/cubits/resource.rb
|
116
119
|
- lib/cubits/version.rb
|
120
|
+
- spec/lib/cubits/account_spec.rb
|
117
121
|
- spec/lib/cubits/connection_spec.rb
|
122
|
+
- spec/lib/cubits/helpers_spec.rb
|
123
|
+
- spec/lib/cubits/invoice_spec.rb
|
124
|
+
- spec/lib/cubits/quote_spec.rb
|
118
125
|
- spec/lib/cubits_spec.rb
|
119
126
|
- spec/spec_helper.rb
|
120
|
-
homepage:
|
127
|
+
homepage: https://github.com/cubits/cubits-ruby
|
121
128
|
licenses:
|
122
129
|
- MIT
|
123
130
|
metadata: {}
|
@@ -142,6 +149,10 @@ signing_key:
|
|
142
149
|
specification_version: 4
|
143
150
|
summary: Ruby client for Cubits Merchant API
|
144
151
|
test_files:
|
152
|
+
- spec/lib/cubits/account_spec.rb
|
145
153
|
- spec/lib/cubits/connection_spec.rb
|
154
|
+
- spec/lib/cubits/helpers_spec.rb
|
155
|
+
- spec/lib/cubits/invoice_spec.rb
|
156
|
+
- spec/lib/cubits/quote_spec.rb
|
146
157
|
- spec/lib/cubits_spec.rb
|
147
158
|
- spec/spec_helper.rb
|