Feature: Expense summary endpoint #75
							
								
								
									
										24
									
								
								app/queries/expenses/total_query.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/queries/expenses/total_query.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| module Expenses | ||||
|   class TotalQuery | ||||
|     def call | ||||
|       ActiveRecord::Base.connection.execute(query).first | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def query | ||||
|       <<~SQL | ||||
|         SELECT count(amount) as fixed, | ||||
|                0 as fixed_count, | ||||
|                0 as variable, | ||||
|                0 as variable_count, | ||||
|                0 as total, | ||||
|                0 as total_count, | ||||
|                0 as max_projected, | ||||
|                0 as per_person | ||||
|         FROM EXPENSES | ||||
|         LIMIT 1; | ||||
|       SQL | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										16
									
								
								spec/factories/expense.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								spec/factories/expense.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| FactoryBot.define do | ||||
|     factory :expense do | ||||
|       sequence(:name) { |i| "Expense #{i}" } | ||||
|       pricing_type { "fixed" } | ||||
|       amount { 100 } | ||||
|     end | ||||
| 
 | ||||
|     trait :fixed do | ||||
|       pricing_type { "fixed" } | ||||
|     end | ||||
| 
 | ||||
|     trait :per_person do | ||||
|       pricing_type { "per_person" } | ||||
|     end | ||||
|   end | ||||
|    | ||||
							
								
								
									
										84
									
								
								spec/queries/expenses/total_query_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								spec/queries/expenses/total_query_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| module Expenses | ||||
|   RSpec.describe TotalQuery do | ||||
|     describe '#call' do | ||||
|       let(:response) { described_class.new.call } | ||||
| 
 | ||||
|       before do | ||||
|         create_list(:guest, 2, status: :confirmed) | ||||
|         create_list(:guest, 3, status: :considered) | ||||
|         create_list(:guest, 4, status: :invited) | ||||
|         create_list(:guest, 5, status: :tentative) | ||||
|         create_list(:guest, 6, status: :declined) | ||||
|       end | ||||
| 
 | ||||
|       context "when there is no expense" do | ||||
|         it "returns zero in all values", :aggregate_failures do | ||||
|           expect(response["fixed"]).to be_zero | ||||
|           expect(response["fixed_count"]).to be_zero | ||||
|           expect(response["variable"]).to be_zero | ||||
|           expect(response["variable_count"]).to be_zero | ||||
|           expect(response["total"]).to be_zero | ||||
|           expect(response["total_count"]).to be_zero | ||||
|           expect(response["max_projected"]).to be_zero | ||||
|           expect(response["per_person"]).to be_zero | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context "when there are only fixed expenses" do | ||||
|         before do | ||||
|           create(:expense, :fixed, amount: 100) | ||||
|           create(:expense, :fixed, amount: 200) | ||||
|         end | ||||
| 
 | ||||
|         it "returns the sum of fixed expenses" do | ||||
|           expect(response["fixed"]).to eq(300) | ||||
|           expect(response["fixed_count"]).to eq(2) | ||||
|           expect(response["variable"]).to be_zero | ||||
|           expect(response["variable_count"]).to be_zero | ||||
|           expect(response["total"]).to eq(300) | ||||
|           expect(response["total_count"]).to eq(2) | ||||
|           expect(response["max_projected"]).to eq(300) | ||||
|           expect(response["per_person"]).to eq(150) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context "when there are only variable expenses" do | ||||
|         before do | ||||
|           create(:expense, :per_person, amount: 100) | ||||
|           create(:expense, :per_person, amount: 200) | ||||
|         end | ||||
| 
 | ||||
|         it "returns zero in the values and nonzero in the count", :aggregate_failures do | ||||
|           expect(response["fixed"]).to be_zero | ||||
|           expect(response["fixed_count"]).to be_zero | ||||
|           expect(response["variable"]).to eq(300) | ||||
|           expect(response["variable_count"]).to eq(2) | ||||
|           expect(response["total"]).to eq(2*300) | ||||
|           expect(response["total_count"]).to eq(2) | ||||
|           expect(response["max_projected"]).to eq(11*300) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context "when there are both fixed and variable expenses" do | ||||
|         before do | ||||
|           create(:expense, :fixed, amount: 100) | ||||
|           create(:expense, :fixed, amount: 200) | ||||
|           create(:expense, :per_person, amount: 50) | ||||
|         end | ||||
| 
 | ||||
|         it "returns the sum of fixed and variable expenses", :aggregate_failures do | ||||
|           expect(response["fixed"]).to eq(300) | ||||
|           expect(response["fixed_count"]).to eq(2) | ||||
|           expect(response["variable"]).to eq(50) | ||||
|           expect(response["variable_count"]).to eq(1) | ||||
|           expect(response["total"]).to eq(100 + 200 + 50 * 2) | ||||
|           expect(response["total_count"]).to eq(3) | ||||
|           expect(response["max_projected"]).to eq(100 + 200 + 11*50) | ||||
|           expect(response["per_person"]).to eq(200) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user