2019-04-04 11:57:36 +02:00
# frozen_string_literal: true
2016-12-01 13:08:41 +01:00
require 'coveralls'
Coveralls . wear! ( 'rails' )
2016-03-23 18:39:41 +01:00
ENV [ 'RAILS_ENV' ] || = 'test'
2020-12-15 15:48:13 +01:00
require_relative '../config/environment'
2020-03-30 10:59:11 +02:00
require 'action_dispatch'
2016-03-23 18:39:41 +01:00
require 'rails/test_help'
2016-04-06 15:15:09 +02:00
require 'vcr'
2016-04-04 17:42:45 +02:00
require 'sidekiq/testing'
require 'minitest/reporters'
2016-04-06 15:15:09 +02:00
2019-10-01 14:32:30 +02:00
include ActionDispatch :: TestProcess
2016-04-06 15:15:09 +02:00
VCR . configure do | config |
2019-04-04 11:57:36 +02:00
config . cassette_library_dir = 'test/vcr_cassettes'
2016-04-06 15:15:09 +02:00
config . hook_into :webmock
2021-06-11 14:29:30 +02:00
config . filter_sensitive_data ( 'sk_test_testfaketestfaketestfake' ) { Setting . get ( 'stripe_secret_key' ) }
config . filter_sensitive_data ( 'pk_test_faketestfaketestfaketest' ) { Setting . get ( 'stripe_public_key' ) }
2016-04-06 15:15:09 +02:00
end
2016-04-11 15:31:25 +02:00
Sidekiq :: Testing . fake!
2021-05-19 18:12:52 +02:00
Minitest :: Reporters . use! [ Minitest :: Reporters :: DefaultReporter . new ( color : true ) ] unless ENV [ 'RM_INFO' ]
2016-04-04 17:42:45 +02:00
2016-03-23 18:39:41 +01:00
class ActiveSupport :: TestCase
# Add more helper methods to be used by all tests here...
2020-12-15 15:48:13 +01:00
ActiveRecord :: Migration . check_pending!
2016-04-04 17:42:45 +02:00
fixtures :all
2016-04-05 09:51:12 +02:00
def json_response ( body )
JSON . parse ( body , symbolize_names : true )
end
2016-04-06 11:27:56 +02:00
2016-04-06 15:22:32 +02:00
def default_headers
2020-03-11 16:18:17 +01:00
{ 'Accept' = > Mime [ :json ] , 'Content-Type' = > Mime [ :json ] . to_s }
2016-04-06 15:22:32 +02:00
end
2019-09-11 16:19:24 +02:00
def stripe_payment_method ( error : nil )
2019-04-04 11:57:36 +02:00
number = '4242424242424242'
2016-04-06 16:26:45 +02:00
exp_month = 4
2019-12-02 15:29:05 +01:00
exp_year = DateTime . current . next_year . year
2019-04-04 11:57:36 +02:00
cvc = '314'
2016-04-06 16:26:45 +02:00
case error
when / card_declined /
2019-04-04 11:57:36 +02:00
number = '4000000000000002'
2016-04-06 16:26:45 +02:00
when / incorrect_number /
2019-04-04 11:57:36 +02:00
number = '4242424242424241'
2016-04-06 16:26:45 +02:00
when / invalid_expiry_month /
exp_month = 15
when / invalid_expiry_year /
exp_year = 1964
when / invalid_cvc /
2019-04-04 11:57:36 +02:00
cvc = '99'
2016-04-06 16:26:45 +02:00
end
2019-09-11 16:19:24 +02:00
Stripe :: PaymentMethod . create (
2020-06-10 11:33:03 +02:00
{
type : 'card' ,
card : {
number : number ,
exp_month : exp_month ,
exp_year : exp_year ,
cvc : cvc
}
} ,
{ api_key : Setting . get ( 'stripe_secret_key' ) }
2016-04-06 11:27:56 +02:00
) . id
end
2016-04-11 15:31:25 +02:00
# Force the invoice generation worker to run NOW and check the resulting file generated.
# Delete the file afterwards.
# @param invoice {Invoice}
def assert_invoice_pdf ( invoice )
assert_not_nil invoice , 'Invoice was not created'
invoice_worker = InvoiceWorker . new
2017-12-14 15:52:34 +01:00
invoice_worker . perform ( invoice . id , invoice & . user & . subscription & . expired_at )
2016-04-11 15:31:25 +02:00
assert File . exist? ( invoice . file ) , 'Invoice PDF was not generated'
2016-12-01 11:37:09 +01:00
# now we check the file content
reader = PDF :: Reader . new ( invoice . file )
assert_equal 1 , reader . page_count # single page invoice
ht_amount = invoice . total
page = reader . pages . first
lines = page . text . scan ( / ^.+ / )
lines . each do | line |
# check that the numbers printed into the PDF file match the total stored in DB
if line . include? I18n . t ( 'invoices.total_amount' )
assert_equal invoice . total / 100 . 0 , parse_amount_from_invoice_line ( line ) , 'Invoice total rendered in the PDF file does not match'
end
# check that the VAT was correctly applied if it was configured
2019-04-04 11:57:36 +02:00
ht_amount = parse_amount_from_invoice_line ( line ) if line . include? I18n . t ( 'invoices.including_total_excluding_taxes' )
2016-12-01 11:37:09 +01:00
end
2019-10-01 14:32:30 +02:00
vat_service = VatHistoryService . new
vat_rate = vat_service . invoice_vat ( invoice )
if vat_rate . positive?
2019-08-14 10:54:19 +02:00
computed_ht = sprintf ( '%.2f' , ( invoice . total / ( vat_rate / 100 . 00 + 1 ) ) / 100 . 00 ) . to_f
2016-12-01 12:12:44 +01:00
assert_equal computed_ht , ht_amount , 'Total excluding taxes rendered in the PDF file is not computed correctly'
2016-12-01 11:37:09 +01:00
else
assert_equal invoice . total , ht_amount , 'VAT information was rendered in the PDF file despite that VAT was disabled'
end
2019-06-03 14:17:37 +02:00
# check the recipient & the address
if invoice . invoicing_profile . organization
assert lines . first . include? ( invoice . invoicing_profile . organization . name ) , 'On the PDF invoice, organization name is invalid'
assert invoice . invoicing_profile . organization . address . address . include? ( lines [ 2 ] . split ( ' ' ) . last . strip ) , 'On the PDF invoice, organization address is invalid'
else
assert lines . first . include? ( invoice . invoicing_profile . full_name ) , 'On the PDF invoice, customer name is invalid'
assert invoice . invoicing_profile . address . address . include? ( lines [ 2 ] . split ( ' ' ) . last . strip ) , 'On the PDF invoice, customer address is invalid'
end
# check the email
assert lines [ 1 ] . include? ( invoice . invoicing_profile . email ) , 'On the PDF invoice, email is invalid'
2016-04-11 15:31:25 +02:00
File . delete ( invoice . file )
end
2016-07-27 11:28:54 +02:00
# Force the statistics export generation worker to run NOW and check the resulting file generated.
# Delete the file afterwards.
# @param export {Export}
def assert_export_xlsx ( export )
assert_not_nil export , 'Export was not created'
if export . category == 'statistics'
export_worker = StatisticsExportWorker . new
export_worker . perform ( export . id )
assert File . exist? ( export . file ) , 'Export XLSX was not generated'
File . delete ( export . file )
else
skip ( 'Unable to test export which is not of the category "statistics"' )
end
end
2016-12-01 11:37:09 +01:00
2019-04-04 12:06:57 +02:00
def assert_archive ( accounting_period )
assert_not_nil accounting_period , 'AccountingPeriod was not created'
archive_worker = ArchiveWorker . new
archive_worker . perform ( accounting_period . id )
assert FileTest . exist? ( accounting_period . archive_file ) , 'ZIP archive was not generated'
# Extract archive
require 'tmpdir'
require 'fileutils'
dest = " #{ Dir . tmpdir } /accounting/ #{ accounting_period . id } "
FileUtils . mkdir_p " #{ dest } /accounting "
Zip :: File . open ( accounting_period . archive_file ) do | zip_file |
# Handle entries one by one
zip_file . each do | entry |
# Extract to file/directory/symlink
entry . extract ( " #{ dest } / #{ entry . name } " )
end
end
# Check archive matches
2021-04-16 10:34:02 +02:00
require 'integrity/checksum'
2019-04-04 12:06:57 +02:00
sumfile = File . read ( " #{ dest } /checksum.sha256 " ) . split ( " \t " )
2021-04-16 10:34:02 +02:00
assert_equal sumfile [ 0 ] , Integrity :: Checksum . file ( " #{ dest } / #{ sumfile [ 1 ] } " ) , 'archive checksum does not match'
2019-04-04 12:06:57 +02:00
archive = File . read ( " #{ dest } / #{ sumfile [ 1 ] } " )
archive_json = JSON . parse ( archive )
invoices = Invoice . where (
'created_at >= :start_date AND created_at <= :end_date' ,
start_date : accounting_period . start_at . to_datetime , end_date : accounting_period . end_at . to_datetime
)
assert_equal invoices . count , archive_json [ 'invoices' ] . count
assert_equal accounting_period . footprint , archive_json [ 'period_footprint' ]
require 'version'
assert_equal Version . current , archive_json [ 'software' ] [ 'version' ]
# we clean up the files before quitting
FileUtils . rm_rf ( dest )
FileUtils . rm_rf ( accounting_period . archive_folder )
end
2018-12-06 18:26:01 +01:00
def assert_dates_equal ( expected , actual , msg = nil )
assert_not_nil actual , msg
assert_equal expected . to_date , actual . to_date , msg
end
2016-12-01 11:37:09 +01:00
private
# Parse a line of text read from a PDF file and return the price included inside
# Line of text should be of form 'Label $10.00'
# @returns {float}
2020-03-11 16:18:17 +01:00
def parse_amount_from_invoice_line ( line )
line [ line . rindex ( ' ' ) + 1 .. - 1 ] . tr ( I18n . t ( 'number.currency.format.unit' ) , '' ) . to_f
2016-12-01 11:37:09 +01:00
end
2016-04-04 17:42:45 +02:00
end
class ActionDispatch :: IntegrationTest
include Warden :: Test :: Helpers
Warden . test_mode!
2016-03-23 18:39:41 +01:00
end