fakturan_nu 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +8 -0
- data/config/locales/en.yml +2 -0
- data/fakturan_nu.gemspec +26 -0
- data/lib/fakturan_nu/address.rb +5 -0
- data/lib/fakturan_nu/base.rb +88 -0
- data/lib/fakturan_nu/client.rb +19 -0
- data/lib/fakturan_nu/error.rb +69 -0
- data/lib/fakturan_nu/invoice.rb +40 -0
- data/lib/fakturan_nu/middleware/parse_json.rb +23 -0
- data/lib/fakturan_nu/middleware/raise_error.rb +33 -0
- data/lib/fakturan_nu/product.rb +7 -0
- data/lib/fakturan_nu/row.rb +7 -0
- data/lib/fakturan_nu/spyke_extensions.rb +24 -0
- data/lib/fakturan_nu.rb +87 -0
- data/test/basics_test.rb +26 -0
- data/test/exceptions_test.rb +104 -0
- data/test/models_test.rb +142 -0
- data/test/test_helper.rb +40 -0
- data/test/vcr_cassettes/models.yml +480 -0
- metadata +231 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
VCR.turn_off!
|
3
|
+
|
4
|
+
module Fakturan
|
5
|
+
class ExceptionsTest < MiniTest::Test
|
6
|
+
|
7
|
+
# They are not, but I dislike them jumping around in the output. Makes it harder to compare two test runs.
|
8
|
+
i_suck_and_my_tests_are_order_dependent!
|
9
|
+
|
10
|
+
def test_raise_access_denied
|
11
|
+
stub_api_request(:get, '/clients/1').to_return(body: 'some json', status: 401)
|
12
|
+
error = assert_raises Fakturan::Error::AccessDenied do
|
13
|
+
Fakturan::Client.find(1)
|
14
|
+
end
|
15
|
+
assert_equal 401, error.status
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_raise_resource_not_found
|
19
|
+
stub_api_request(:get, '/clients/0').to_return(body: '{"error":"404 Not Found"}', status: 404)
|
20
|
+
error = assert_raises Fakturan::Error::ResourceNotFound do
|
21
|
+
Fakturan::Client.find(0)
|
22
|
+
end
|
23
|
+
assert_equal 404, error.status
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_raise_parse_error
|
27
|
+
stub_api_request(:get, '/clients/0').to_return(body: ')!"#/€!)"=#€()', status: 200)
|
28
|
+
error = assert_raises Fakturan::Error::ParseError do
|
29
|
+
Fakturan::Client.find(0)
|
30
|
+
end
|
31
|
+
assert error.response.is_a? Hash
|
32
|
+
assert_equal 200, error.status
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_raise_failed_connection
|
36
|
+
old_url = Fakturan.url
|
37
|
+
WebMock.disable!
|
38
|
+
Fakturan.url = 'http://0.0.0.0:1234' # I sure hope no one responds here. ;)
|
39
|
+
error = assert_raises Fakturan::Error::ConnectionFailed do
|
40
|
+
Fakturan::Client.find(1)
|
41
|
+
end
|
42
|
+
WebMock.enable!
|
43
|
+
Fakturan.url = old_url
|
44
|
+
assert_equal 407, error.status
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_raise_timeout_error
|
48
|
+
stub_api_request(:get, '/clients/1').to_timeout
|
49
|
+
error = assert_raises Fakturan::Error::ConnectionFailed do
|
50
|
+
Fakturan::Client.find(1)
|
51
|
+
end
|
52
|
+
assert_equal 407, error.status
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_raise_server_error_on_internal_server_error
|
56
|
+
stub_api_request(:get, '/clients/1').to_return(body: { error: '500 Internal server error' }.to_json, status: 500)
|
57
|
+
error = assert_raises Fakturan::Error::ServerError do
|
58
|
+
Fakturan::Client.find(1)
|
59
|
+
end
|
60
|
+
assert_equal 500, error.status
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_raise_client_error_on_bad_request # Don't think the api actually ever responds with a plain 400 a t m, but anyway...
|
64
|
+
stub_api_request(:post, '/invoices').to_return(body: { error: '400 Bad request' }.to_json, status: 400)
|
65
|
+
error = assert_raises Fakturan::Error::ClientError do
|
66
|
+
Fakturan::Invoice.create client: { address: '' } # Address should really be a hash
|
67
|
+
end
|
68
|
+
assert_equal 400, error.status
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_validation_errors_on_associations
|
72
|
+
stub_api_request(:post, '/invoices').to_return(body: {errors: {date: [{error: :blank},{error: :invalid}], rows: [{"0" => {"rows.product_code" => [{error: :too_long, count:30}]}}, {"2" => {"rows.product_code" => [{error: :too_long, count:30}]}}], "client.company" => [{ error: :blank}]}}.to_json, status: 422)
|
73
|
+
|
74
|
+
invoice = Fakturan::Invoice.new(client: {}, rows: [{product_code: '1234567890123456789012345678901'}, {product_code: '1'}, {product_code: '1234567890123456789012345678901'}])
|
75
|
+
invoice.save
|
76
|
+
|
77
|
+
assert_equal "Client company can't be blank", invoice.errors.to_a.last
|
78
|
+
assert_equal ({date: [{error: :blank}, {error: :invalid}]}), invoice.errors.details
|
79
|
+
assert_equal ({:product_code=>[{:error=>:too_long, :count=>30}]}), invoice.rows[0].errors.details
|
80
|
+
# This one checks that our index / ordering has succeded and we have put the errors on the correct object
|
81
|
+
assert_equal ({:product_code=>[{:error=>:too_long, :count=>30}]}), invoice.rows[2].errors.details
|
82
|
+
assert_equal ({:company=>[{:error=>:blank}]}), invoice.client.errors.details
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_raise_resource_invalid
|
86
|
+
stub_api_request(:post, '/invoices').to_return(body: { errors: { client_id: [{ error: :blank}], date: [{ error: :blank}, { error: :invalid}] }}.to_json, status: 422)
|
87
|
+
error = assert_raises Fakturan::Error::ResourceInvalid do
|
88
|
+
Fakturan::Invoice.create!
|
89
|
+
end
|
90
|
+
assert_equal 422, error.status
|
91
|
+
assert_equal "Client can't be blank", error.model.errors.to_a.first
|
92
|
+
assert_raises Fakturan::Error::ResourceInvalid do
|
93
|
+
Fakturan::Invoice.new.save!
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_errors_on_model
|
98
|
+
stub_api_request(:post, '/invoices').to_return(body: { errors: { client_id: [{ error: :blank}], date: [{ error: :blank}, { error: :invalid}] }}.to_json, status: 422)
|
99
|
+
invoice = Fakturan::Invoice.create
|
100
|
+
assert_equal "Client can't be blank", invoice.errors.to_a.first
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/test/models_test.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
VCR.turn_on!
|
3
|
+
|
4
|
+
|
5
|
+
module Fakturan
|
6
|
+
class ModelsTest < MiniTest::Test
|
7
|
+
|
8
|
+
def around(&block)
|
9
|
+
# https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/request-matching/playback-repeats
|
10
|
+
VCR.use_cassette("models",
|
11
|
+
:allow_playback_repeats => true,
|
12
|
+
:record => :new_episodes,
|
13
|
+
:match_requests_on => [:method, :uri, :body],
|
14
|
+
&block)
|
15
|
+
end
|
16
|
+
|
17
|
+
# They are not, but I dislike them jumping around in the output. Makes it harder to compare two test runs.
|
18
|
+
i_suck_and_my_tests_are_order_dependent!
|
19
|
+
|
20
|
+
def good_invoice_params
|
21
|
+
@good_invoice_params ||= { client: { company: 'Imagine it AB' }, date: Date.today, address: { name: "Imagine it AB", street_address: "Tage Erlandergatan 4" } }
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_good_invoice
|
25
|
+
return if @invoice # We won't change this instance so we really only need to do this once.
|
26
|
+
@invoice = Fakturan::Invoice.find(7757)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_find_one_and_access_attribute
|
30
|
+
client = Fakturan::Client.find(1)
|
31
|
+
assert client.name.is_a? String
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_should_create_associated_objects
|
35
|
+
get_good_invoice
|
36
|
+
assert_equal @invoice.address.name, 'DCT'
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_be_able_to_fetch_and_update_invoice
|
40
|
+
skip "Not implemented server side yet"
|
41
|
+
invoice = Fakturan::Invoice.find(71125)
|
42
|
+
invoice.days = 10
|
43
|
+
assert invoice.save
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_fetch_associated_record
|
47
|
+
get_good_invoice
|
48
|
+
client = Fakturan::Client.find(1)
|
49
|
+
assert_equal Fakturan::Client, client.class
|
50
|
+
assert_equal 'DCT', client.name
|
51
|
+
assert_equal client.name, @invoice.client.name
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_find_one_and_access_attribute
|
55
|
+
products = Fakturan::Product.all
|
56
|
+
assert products.first.product_code.is_a? String
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_get_collection
|
60
|
+
products = Fakturan::Product.all
|
61
|
+
assert_equal Fakturan::Product, products.first.class
|
62
|
+
assert products.first.is_a? Fakturan::Product
|
63
|
+
assert_equal 25, products.first.tax
|
64
|
+
assert_equal Fixnum, products.first.tax.class
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_save_should_return_false_then_true
|
68
|
+
p = Fakturan::Product.new
|
69
|
+
assert_equal false, p.save
|
70
|
+
p.name = "Testing"
|
71
|
+
assert_equal true, p.save
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_should_fetch_associated_records
|
75
|
+
skip "Not implemented server side yet"
|
76
|
+
client = Fakturan::Client.find(1)
|
77
|
+
assert_equal Fakturan::Invoice, client.invoices.first.class # Currently gives routing error
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_save_new_product
|
81
|
+
p = Fakturan::Product.new(name: "Shoes")
|
82
|
+
assert p.save
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_create_should_return_instance_when_successful
|
86
|
+
invoice = Fakturan::Invoice.create good_invoice_params
|
87
|
+
assert_equal Fakturan::Invoice, invoice.class
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_create_should_return_instance_when_unsuccessful
|
91
|
+
invoice = Fakturan::Invoice.create
|
92
|
+
assert_equal Fakturan::Invoice, invoice.class
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_create_bang_should_return_nil_when_unsuccessful
|
96
|
+
begin
|
97
|
+
invoice = Fakturan::Invoice.create!
|
98
|
+
rescue
|
99
|
+
end
|
100
|
+
assert_equal nil, invoice
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_create_bang_should_return_instance_when_successful
|
104
|
+
begin
|
105
|
+
invoice = Fakturan::Invoice.create! good_invoice_params
|
106
|
+
rescue
|
107
|
+
end
|
108
|
+
assert_equal Fakturan::Invoice, invoice.class
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_date_fields_should_not_be_typecast
|
112
|
+
get_good_invoice
|
113
|
+
assert_equal String, @invoice.date.class
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_getting_attribute_on_new_instance
|
117
|
+
invoice = Fakturan::Invoice.new
|
118
|
+
# Would blow up unless attributes are specified on model
|
119
|
+
assert_nil invoice.number
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_should_be_able_to_set_params_on_association
|
123
|
+
invoice = Fakturan::Invoice.new
|
124
|
+
invoice.date = Date.today.to_s
|
125
|
+
invoice.build_client
|
126
|
+
invoice.client.company = 'Imagine it AB'
|
127
|
+
assert invoice.save
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_calling_association_on_non_persisted_invoice_should_make_no_request
|
131
|
+
invoice = Fakturan::Invoice.new
|
132
|
+
begin
|
133
|
+
invoice.client
|
134
|
+
rescue Spyke::InvalidPathError
|
135
|
+
# Spyke throws this error because we are asking for an associated object without providing
|
136
|
+
# required params in url 'client/:id'
|
137
|
+
end
|
138
|
+
assert_not_requested :get, "http://#{API_USER}:#{API_PASS}@#{BASE_URL}/#{Fakturan::Client.new.uri}"
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'fakturan_nu'
|
2
|
+
require "minitest/autorun"
|
3
|
+
require 'minitest/reporters'
|
4
|
+
require 'webmock/minitest'
|
5
|
+
require 'json'
|
6
|
+
require 'vcr'
|
7
|
+
require 'minitest/around/unit'
|
8
|
+
|
9
|
+
# If we want to get VCR to save responses as json instead of binary (only happens sometimes):
|
10
|
+
# https://groups.google.com/forum/#!topic/vcr-ruby/2sKrJa86ktU
|
11
|
+
# http://stackoverflow.com/questions/21920259/how-to-edit-response-body-returned-by-vcr-gem
|
12
|
+
|
13
|
+
VCR.configure do |config|
|
14
|
+
config.cassette_library_dir = "test/vcr_cassettes"
|
15
|
+
config.hook_into :webmock
|
16
|
+
|
17
|
+
config.before_record do |i|
|
18
|
+
i.response.body.force_encoding('UTF-8')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Pretty colors
|
23
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
24
|
+
|
25
|
+
API_USER, API_PASS = 'dUmziS9k9Q5x0u4wot1H', 'DAW96mbxui8B3_CBFFFMr0HgfaCfpv7ajUfcZ38B'
|
26
|
+
BASE_URL = '0.0.0.0:3000/api/v2'
|
27
|
+
#WebMock.disable! # Do this if we want to run tests against local server
|
28
|
+
|
29
|
+
Fakturan.setup API_USER, API_PASS
|
30
|
+
Fakturan.url = "http://#{BASE_URL}"
|
31
|
+
|
32
|
+
module WebMock
|
33
|
+
module API
|
34
|
+
def stub_api_request(method, abs_path)
|
35
|
+
stub_request(method, "http://#{API_USER}:#{API_PASS}@#{BASE_URL}#{abs_path}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|