require 'rails_helper'

RSpec.describe Contabilidade::RetencoesController, type: :controller do
	sign_in_admin
	cria_configuracao_default
	set_contabilidade_na_sessao

	describe "GET #edit" do
		before do
			@pagamento = FactoryBot.create :pagamento_de_pessoal
			get :edit, params: {pagamento_id:  @pagamento.id }
		end

		it "atribui o pagamento corrente à @pagamento" do
			expect(assigns(:pagamento)).to eq @pagamento
		end

		it 'renderiza template :edit' do
			expect(response).to render_template :edit
		end
	end

	describe "PUT #update" do
		context 'quando não é passado o parâmetro id' do
			before do
				@pagamento = FactoryBot.create :pagamento_de_pessoal
				@servico = FactoryBot.create :servico_para_explorarao_de_rodovia
			end

			context 'com parâmetros válidos' do
				before do
					@atributos_das_retencoes = {
						retencoes_attributes: {
							"0" => {
								imposto_id: @servico.id,
								imposto_type: @servico.class.name,
								base_de_calculo: 4.5,
								aliquota: 2.0
							}
						}
					}
				end

				it 'cria a(s) retenção(oes) p/ o pagamento' do
					expect {
						post :update, params: { pagamento_id: @pagamento.id, contabilidade_pagamento: @atributos_das_retencoes }
					}.to change(Contabilidade::Retencao, :count).by(1)
				end

				it 'redireciona para o pagamento' do
					post :update, params: { pagamento_id: @pagamento.id, contabilidade_pagamento: @atributos_das_retencoes }
					expect(response).to redirect_to @pagamento
				end
			end

			context 'com parâmetros inválidos' do
				before do
					@atributos_das_retencoes = {
						retencoes_attributes: {
							"0" => {
								imposto_id: '',
								imposto_type: @servico.class.name,
								base_de_calculo: 4.5,
								aliquota: 2.0
							}
						}
					}
				end

				it 'não cria a(s) retenção(oes) p/ o pagamento' do
					expect {
						post :update, params: { pagamento_id: @pagamento.id, contabilidade_pagamento: @atributos_das_retencoes }
					}.not_to change(Contabilidade::Retencao, :count)
				end

				it 'renderia template de edit' do
					post :update, params: { pagamento_id: @pagamento.id, contabilidade_pagamento: @atributos_das_retencoes }
					expect(response).to render_template :edit
				end
			end
		end

		context 'quando é passado o parâmetro id' do
			before do
				@retencao_iss = FactoryBot.create :retencao_iss
			end

			context 'com parâmetros válidos' do
				before do
					@atributos_das_retencoes = {
						retencoes_attributes: {
							"0" => {
								id: @retencao_iss.id,
								aliquota: 1.5
							}
						}
					}

					post :update, params: { pagamento_id: @retencao_iss.pagamento_id, contabilidade_pagamento: @atributos_das_retencoes }
				end

				it 'atualiza a(s) retenção(oes) do pagamento' do
					@retencao_iss.reload
					expect(@retencao_iss.aliquota.to_f).to eq 1.5
				end

				it 'redireciona para o pagamento' do
					expect(response).to redirect_to @retencao_iss.pagamento
				end
			end

			context 'com parâmetros inválidos' do
				it 'renderiza o template de :edit' do
					atributos_das_retencoes = {
						retencoes_attributes: {
							"0" => {
								id: @retencao_iss.id,
								aliquota: ''
							}
						}
					}

					post :update, params: { pagamento_id: @retencao_iss.pagamento_id, contabilidade_pagamento: atributos_das_retencoes }
					expect(response).to render_template :edit
				end
			end
		end

		context 'quando é passado o parâmetro _destroy' do
			it 'remove a(s) retenção(ões) calculadas do pagamento' do
				pagamento = FactoryBot.create :pagamento_de_pessoal
				retencao_iss = FactoryBot.create :retencao_iss, pagamento_id: pagamento.id

				atributos_das_retencoes = {
					retencoes_attributes: {
						"0" => {
							id: retencao_iss.id,
							_destroy: '1'
						}
					}
				}

				expect {
					post :update, params: { pagamento_id: pagamento.id, contabilidade_pagamento: atributos_das_retencoes }
				}.to change( pagamento.retencoes, :count ).by(-1)
			end
		end
	end
end
