tests: minitest + rack-test suite, bin/test with ephemeral Postgres
This commit is contained in:
parent
8468b3d099
commit
43bed98329
13 changed files with 456 additions and 2 deletions
115
test/invoice_test.rb
Normal file
115
test/invoice_test.rb
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
require_relative 'test_helper'
|
||||
|
||||
class InvoiceTest < Minitest::Test
|
||||
def setup
|
||||
skip 'TEST_DATABASE_URL not set' unless TestDb.available?
|
||||
TestDb.clean!
|
||||
@year = Date.today.year
|
||||
end
|
||||
|
||||
def insert_number(num)
|
||||
DB.connection[:invoices].insert(
|
||||
uuid: SecureRandom.uuid, number: num, client_name: 'c', client_email: 'c@example.com',
|
||||
currency: 'EUR', gel_rate: 3, subtotal: 1,
|
||||
items: [{ 'description' => 'x', 'qty' => '1', 'unit_price' => '1' }].to_json,
|
||||
issued_on: Date.today, due_on: Date.today + 14, pdf_key: 'k', created_at: Time.now.utc
|
||||
)
|
||||
end
|
||||
|
||||
def test_allocate_number_starts_at_one
|
||||
assert_equal "INV-#{@year}-0001", Invoice.allocate_number
|
||||
end
|
||||
|
||||
def test_allocate_number_increments
|
||||
insert_number("INV-#{@year}-0001")
|
||||
insert_number("INV-#{@year}-0002")
|
||||
assert_equal "INV-#{@year}-0003", Invoice.allocate_number
|
||||
end
|
||||
|
||||
def test_allocate_number_sorts_numerically_past_9999
|
||||
insert_number("INV-#{@year}-9999")
|
||||
insert_number("INV-#{@year}-10000")
|
||||
assert_equal "INV-#{@year}-10001", Invoice.allocate_number
|
||||
end
|
||||
|
||||
def test_allocate_number_ignores_other_years
|
||||
insert_number("INV-#{@year - 1}-0500")
|
||||
assert_equal "INV-#{@year}-0001", Invoice.allocate_number
|
||||
end
|
||||
|
||||
def test_duplicate_number_raises_unique_violation
|
||||
insert_number("INV-#{@year}-0001")
|
||||
assert_raises(Sequel::UniqueConstraintViolation) { insert_number("INV-#{@year}-0001") }
|
||||
end
|
||||
|
||||
def test_build_round_trip
|
||||
inv = Invoice.build(
|
||||
client_name: 'ACME', client_email: 'billing@example.com', client_address: '',
|
||||
currency: 'EUR', gel_rate: '3.05', issued_on: '', due_on: '', notes: '',
|
||||
items: [{ 'description' => 'work', 'qty' => '2', 'unit_price' => '100.50' }]
|
||||
)
|
||||
inv.pdf_key = "invoices/#{inv.number}-#{inv.uuid}.pdf"
|
||||
inv.save_changes
|
||||
|
||||
saved = Invoice[uuid: inv.uuid]
|
||||
assert_equal BigDecimal('201'), saved.total
|
||||
assert_equal BigDecimal('613.05'), saved.total_gel
|
||||
assert_equal 'pending', saved.status
|
||||
refute saved.ltc?
|
||||
end
|
||||
|
||||
def test_build_derives_ltc_amount_from_rate
|
||||
inv = Invoice.build(
|
||||
client_name: 'ACME', client_email: 'billing@example.com',
|
||||
currency: 'EUR', gel_rate: '3.05',
|
||||
items: [{ 'description' => 'work', 'qty' => '1', 'unit_price' => '100' }],
|
||||
ltc_address: 'ltc1qexampleexampleexampleexample', ltc_rate: '80', ltc_amount: ''
|
||||
)
|
||||
assert inv.ltc?
|
||||
assert_equal BigDecimal('1.25'), inv.ltc_amount_due
|
||||
end
|
||||
end
|
||||
|
||||
class InvoiceValidationTest < Minitest::Test
|
||||
BASE = {
|
||||
client_name: 'ACME', client_email: 'billing@example.com', currency: 'EUR',
|
||||
gel_rate: '3.05', ltc_address: '', ltc_rate: '', ltc_amount: '',
|
||||
items: [{ 'description' => 'work', 'qty' => '1', 'unit_price' => '100' }]
|
||||
}.freeze
|
||||
|
||||
def setup
|
||||
skip 'TEST_DATABASE_URL not set' unless TestDb.available?
|
||||
@app = AsxpioWeb.new!
|
||||
end
|
||||
|
||||
def validate(over = {})
|
||||
@app.send(:validate_invoice_params, BASE.merge(over).dup)
|
||||
end
|
||||
|
||||
def test_valid_params_pass
|
||||
assert_empty validate
|
||||
end
|
||||
|
||||
def test_gel_rate_must_be_positive
|
||||
assert_includes validate(gel_rate: '0'), :gel_rate
|
||||
assert_includes validate(gel_rate: '-2.9'), :gel_rate
|
||||
refute_includes validate(gel_rate: '2.95'), :gel_rate
|
||||
end
|
||||
|
||||
def test_item_numbers_must_parse
|
||||
assert_includes validate(items: [{ 'description' => 'w', 'qty' => '1,5', 'unit_price' => '100' }]), :items
|
||||
assert_includes validate(items: [{ 'description' => 'w', 'qty' => '1', 'unit_price' => 'abc' }]), :items
|
||||
end
|
||||
|
||||
def test_blank_item_numbers_allowed
|
||||
assert_empty validate(items: [{ 'description' => 'w', 'qty' => '', 'unit_price' => '' }])
|
||||
end
|
||||
|
||||
def test_at_least_one_item_required
|
||||
assert_includes validate(items: [{ 'description' => '', 'qty' => '1', 'unit_price' => '1' }]), :items
|
||||
end
|
||||
|
||||
def test_ltc_address_format
|
||||
assert_includes validate(ltc_address: 'not-an-address'), :ltc_address
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue