require 'rails_helper'

RSpec.describe Loa::OrcamentosDaDespesaController, type: :controller do
	sign_in_admin
	set_orcamento_na_sessao

	describe "GET #edit" do
		let :subacao do
			FactoryBot.create :subacao_1005_0001, :orcamento_2016
		end

		it "renderiza a subação requisitada" do
			get :edit, id: subacao.id
			expect(assigns(:subacao)).to eq subacao
		end

		it "renderiza o template 'edit'" do
			get :edit, id: subacao.id
			expect(response).to render_template('edit')
		end

		it "renderiza os dados do iduso requisitado" do
			get :edit, id: subacao.id
			expect(assigns(:iduso)).to eq Loa::OrcamentoDaDespesa.idusos
		end
	end

	describe "PUT #update" do
		before do
			@subacao = FactoryBot.create :subacao_1005_0001, :orcamento_2016
			@elemento_de_despesa = FactoryBot.create :elemento_de_despesa_material_de_consumo
			@fonte_de_recursos = FactoryBot.create :alienacao_de_bens
		end

		context "quando não há parâmetro id" do
			it "cria elementos de despesa por subação para subação requisitada" do
				atributos_de_elementos_de_despesa_por_subacao =  {
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							elemento_de_despesa_id: @elemento_de_despesa.id,
						}
					}
				}

				expect {
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				}.to change(@subacao.elementos_de_despesa_por_subacao, :count).by( 1 )

			end

			it "cria orçamento da despesa por elementos de despesa para a subacao requisitada" do
				atributos_de_elementos_de_despesa_por_subacao =  {
					fixacao_da_despesa: 99.00,
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							elemento_de_despesa_id: @elemento_de_despesa.id,
							orcamentos_da_despesa_attributes: {
								"0" => {
									valor: 99.00,
									fonte_de_recursos_id: @fonte_de_recursos.id
								}
							}
						}
					}
				}

				expect {
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				}.to change(@subacao.orcamentos_da_despesa, :count).by( 1 )

			end
		end

		context "quando há parâmetro id" do
			it "atualiza elementos de despesa por subação da subação requisitada" do
				elemento_de_despesa_por_subacao = @subacao.elementos_de_despesa_por_subacao.create!(
					elemento_de_despesa_id: @elemento_de_despesa.id,
					status_do_orcamento: 0
				)

				outro_elemento_de_despesa = FactoryBot.create(:elemento_de_despesa_material_de_consumo, codigo: '31304100', descricao: 'Contribuições')

				atributos_de_elementos_de_despesa_por_subacao =  {
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							id: elemento_de_despesa_por_subacao.id,
							elemento_de_despesa_id: outro_elemento_de_despesa.id
						}
					}
				}

				put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				elemento_de_despesa_por_subacao.reload
				expect( elemento_de_despesa_por_subacao.elemento_de_despesa ).to eq outro_elemento_de_despesa

			end

			it "atualiza os orçamentos da despesa da subação requisitada" do
				orcamento_saude = FactoryBot.create(:orcamento_da_despesa_saude)

				atributos_de_elementos_de_despesa_por_subacao =  {
					fixacao_da_despesa: 192.99,
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							id: orcamento_saude.elemento_de_despesa_por_subacao_id,
							orcamentos_da_despesa_attributes: {
								"0" => {
									id: orcamento_saude.id,
									valor: 192.99
								}
							}
						}
					}
				}
				put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				orcamento_saude.reload
				expect( orcamento_saude.valor ).to eq 192.99

			end
		end

		context "quando há o parâmetro _destroy" do
			it "apaga o elemento de despesa por subação da subação requisitada" do
				elemento_de_despesa_por_subacao = FactoryBot.create( :elemento_de_despesa_por_subacao )

				atributos_de_elementos_de_despesa_por_subacao =  {
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							id: elemento_de_despesa_por_subacao.id,
							_destroy: true
						}
					}
				}

				expect{
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				}.to change( @subacao.elementos_de_despesa_por_subacao, :count ).by( -1 )

			end

			it "apaga os orçamentos da despesa da subação requisitada" do
				orcamento_saude = FactoryBot.create( :orcamento_da_despesa_saude )

				atributos_de_elementos_de_despesa_por_subacao =  {
					fixacao_da_despesa: 192.99,
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							id: orcamento_saude.elemento_de_despesa_por_subacao_id,
							orcamentos_da_despesa_attributes: {
								"0" => {
									id: orcamento_saude.id,
									valor: 192.99,
									_destroy: true
								}
							}
						}
					}
				}

				expect{
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
					}.to change( @subacao.orcamentos_da_despesa, :count ).by( -1 )

				end
			end

		context "com parâmetros inválidos" do
			it "renderiza template edit" do
				orcamento_saude = FactoryBot.create(:orcamento_da_despesa_saude)

				atributos_de_elementos_de_despesa_por_subacao =  {
					elementos_de_despesa_por_subacao_attributes: {
						"0" => {
							id: orcamento_saude.elemento_de_despesa_por_subacao_id,
							orcamentos_da_despesa_attributes: {
								"0" => {
									id: orcamento_saude.id,
									valor: 0.00,
								}
							}
						}
					}
				}

				put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
				expect(response).to render_template("edit")
			end
		end

		context "com parâmetros válidos" do
			context 'quando orçamento trabalha com subação' do
				it "redireciona para a subação requisitada" do
					atributos_de_elementos_de_despesa_por_subacao =  {
						elementos_de_despesa_por_subacao_attributes: {}
					}
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
					expect( response ).to redirect_to @subacao
				end
			end
			context 'quando orçamento não trabalha com subação' do
				it "redireciona para a ação da subação requisitada" do
					orcamento_atual_nao_trabalha_com_subacoes
					atributos_de_elementos_de_despesa_por_subacao =  {
						elementos_de_despesa_por_subacao_attributes: {}
					}
					put :update, id: @subacao.id, loa_subacao: atributos_de_elementos_de_despesa_por_subacao
					expect( response ).to redirect_to @subacao.acao
				end
			end
		end
	end
end
