accodeing/fortnox-api

View on GitHub
spec/fortnox/api/repositories/invoice_spec.rb

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
# frozen_string_literal: true

require 'spec_helper'
require 'fortnox/api'
require 'fortnox/api/mappers'
require 'fortnox/api/repositories/invoice'
require 'fortnox/api/repositories/examples/all'
require 'fortnox/api/repositories/examples/find'
require 'fortnox/api/repositories/examples/search'
require 'fortnox/api/repositories/examples/save'
require 'fortnox/api/repositories/examples/save_with_nested_model'
require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
require 'fortnox/api/repositories/examples/only'

describe Fortnox::API::Repository::Invoice, integration: true, order: :defined do
  include Helpers::Configuration
  include Helpers::Repositories

  subject(:repository) { described_class.new }

  before { set_api_test_configuration }

  required_hash = { customer_number: '1' }

  include_examples '.save', :comments, additional_attrs: required_hash

  describe '#save' do
    context 'with unsaved parent' do
      subject(:saved_child) do
        parent_invoice = Fortnox::API::Model::Invoice.new(customer_number: '1')
        child_invoice = parent_invoice.update(due_date: '2023-01-01')

        VCR.use_cassette("#{vcr_dir}/save_new_with_unsaved_parent") do
          described_class.new.save(child_invoice)
        end
      end

      it 'sets attribute from parent when saved' do
        expect(saved_child.customer_number).to eq '1'
      end
    end
  end

  nested_model_hash = { price: 10, article_number: '101' }
  include_examples '.save with nested model',
                   required_hash,
                   :invoice_rows,
                   nested_model_hash,
                   [Fortnox::API::Types::InvoiceRow.new(nested_model_hash)]

  include_examples '.save with specially named attribute',
                   required_hash,
                   :ocr,
                   '426523791'

  # It is not possible to delete Invoces. Therefore, expected nr of Orders
  # when running .all will continue to increase (until 100, which is max by default).
  include_examples '.all', 34

  # VCR: Models needs to be created manually in Fortnox
  include_examples '.find', 1 do
    let(:find_by_hash_failure) { { yourreference: 'Not found' } }

    let(:single_param_find_by_hash) do
      { find_hash: { yourreference: 'Gandalf the Grey' }, matches: 2 }
    end
    let(:multi_param_find_by_hash) do
      { find_hash: { yourreference: 'Gandalf the Grey', ourreference: 'Radagast the Brown' },
        matches: 1 }
    end
  end

  include_examples '.search', :customername, 'Test', 1

  # VCR: Need to be set manually in Fortnox
  include_examples '.only', :fullypaid, 2

  describe 'country attribute' do
    def new_invoice(country:)
      described_class::MODEL.new(customer_number: 1, country: country)
    end

    context 'with valid country' do
      def save_invoice(country:, vcr_cassette: country)
        VCR.use_cassette("#{vcr_dir}/save_new_with_country_#{vcr_cassette}") do
          repository.save(new_invoice(country: country))
        end
      end

      it 'accepts English country names' do
        expect(save_invoice(country: 'Norway').country).to eq('NO')
      end

      it 'translates Swedish country names to English' do
        expect(save_invoice(country: 'Norge').country).to eq('NO')
      end

      it 'skips nil values' do
        expect(save_invoice(country: nil, vcr_cassette: 'nil').country).to eq('')
      end

      it 'skips empty string values' do
        expect(save_invoice(country: '', vcr_cassette: 'empty_string').country).to eq('')
      end

      describe 'GB' do
        subject { save_invoice(country: 'GB').country }

        it { is_expected.to eq('GB') }
      end

      describe 'VA' do
        subject { save_invoice(country: 'VA').country }

        it { is_expected.to eq('VA') }
      end

      describe 'VI' do
        subject { save_invoice(country: 'VI').country }

        it { is_expected.to eq('VI') }
      end

      describe 'special cases Sverige' do
        subject { save_invoice(country: 'Sverige').country }

        it { is_expected.to eq('SE') }
      end
    end
  end

  describe 'resetting values in Fortnox' do
    context 'with String values' do
      def new_invoice(comments:)
        described_class::MODEL.new(customer_number: 1, comments: comments)
      end

      let(:persisted_invoice) do
        VCR.use_cassette("#{vcr_dir}/save_new_with_comments") do
          repository.save(new_invoice(comments: 'A comment to be reset'))
        end
      end

      before { persisted_invoice }

      context 'when setting value to nil' do
        subject(:comments) { updated_persisted_invoice.comments }

        let(:updated_persisted_invoice) do
          VCR.use_cassette("#{vcr_dir}/save_old_with_nil_comments") do
            repository.save(persisted_invoice.update(comments: nil))
          end
        end

        it do
          pending "test to rerecord VCR cassette, maybe it's working now"
          expect(comments).to be_nil
        end
      end

      context 'when setting value to empty string' do
        subject(:comments) { updated_persisted_invoice.comments }

        let(:updated_persisted_invoice) do
          VCR.use_cassette("#{vcr_dir}/save_old_with_empty_comments") do
            repository.save(persisted_invoice.update(comments: ''))
          end
        end

        it 'does not reset the value' do
          expect(comments).to eq('A comment to be reset')
        end
      end
    end

    context 'with other values' do
      def new_invoice(country:)
        described_class::MODEL.new(customer_number: 1, country: country)
      end

      let(:persisted_invoice) do
        VCR.use_cassette("#{vcr_dir}/save_new_with_country") do
          repository.save(new_invoice(country: 'Sverige'))
        end
      end

      before { persisted_invoice }

      context 'when setting value to nil' do
        subject(:country) { updated_persisted_invoice.country }

        let(:updated_persisted_invoice) do
          # TODO: This VCR cassette needs to be re-recorded again
          # when the we fix #172.
          VCR.use_cassette("#{vcr_dir}/save_old_with_nil_country") do
            repository.save(persisted_invoice.update(country: nil))
          end
        end

        it 'is nil' do
          pending 'see comment above'
          expect(country).to be_nil
        end
      end

      context 'when setting value to empty string' do
        subject(:country) { updated_persisted_invoice.country }

        let(:updated_persisted_invoice) do
          VCR.use_cassette("#{vcr_dir}/save_old_with_empty_country") do
            repository.save(persisted_invoice.update(country: ''))
          end
        end

        it 'does not reset the country' do
          expect(country).to eq('SE')
        end
      end
    end
  end

  describe 'limits for invoice_row' do
    describe 'description' do
      let(:model) do
        described_class::MODEL.new(
          customer_number: '1',
          invoice_rows: [
            {
              article_number: '101',
              description: 'a' * 255
            }
          ]
        )
      end
      let(:saving_with_max_row_description) do
        VCR.use_cassette("#{vcr_dir}/row_description_limit") { repository.save(model) }
      end

      it 'allows 255 characters' do
        expect { saving_with_max_row_description }.not_to raise_error
      end
    end
  end
end