Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/aspire_budget.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'worksheets/backend_data'
require 'worksheets/transactions'
require 'worksheets/category_transfers'
require 'worksheets/dashboard'

require 'models/transaction'
require 'models/category_transfer'
Expand Down
6 changes: 4 additions & 2 deletions lib/worksheets/backend_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ class BackendData < WorksheetBase

# @return [String] the spreadsheet version
def version
version_column = ws.rows[0].index { |header| header.match?(/Update/) }
ws.rows[1][version_column]
@version ||= begin
version_column = ws.rows[0].index { |header| header.match?(/Update/) }
ws.rows[1][version_column]
end
end
end
end
Expand Down
49 changes: 49 additions & 0 deletions lib/worksheets/dashboard.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

require 'worksheets/worksheet_base'

module AspireBudget
module Worksheets
class Dashboard < WorksheetBase
WS_TITLE = 'Dashboard'

CELL_MAP_3_2_0 = {
available_to_budget: 'H2',
spent_this_month: 'I2',
budgeted_this_month: 'K2',
pending_transactions: 'O2'
}.freeze

CELL_MAP_3_1_0 = {
available_to_budget: 'C5',
spent_this_month: 'C6',
pending_transactions: 'C7'
}.freeze

IMMEDIATE_METHODS = (CELL_MAP_3_2_0.keys | CELL_MAP_3_1_0.keys)

private_constant :IMMEDIATE_METHODS

IMMEDIATE_METHODS.each do |data_name|
define_method data_name do
cell = cell_map[data_name] || raise("#{data_name} is not supported on #{spreadsheet_version}")
ws.numeric_value(cell)
end
end

private

def cell_map
case spreadsheet_version
when '3.2.0' then CELL_MAP_3_2_0
when '3.1.0' then CELL_MAP_3_1_0
else raise "version #{version} not supported"
end
end

def ws_title
'Dashboard'
end
end
end
end
25 changes: 20 additions & 5 deletions lib/worksheets/worksheet_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,30 @@ def respond_to_missing?(method_name, include_private = false)
end
end

# @see AspireBudget::Configuration#agent
# @return a new instance of the calling class configured with an agent
# Initializes the worksheet. To use the spreadsheet default
# +session+ / +spreadsheet_key+, just initialize without arguments.
# @param session [GoogleDrive::Session]
# @param spreadsheet_key [String] spreadsheet key as per its url
def initialize(session: nil, spreadsheet_key: nil)
@agent = AspireBudget.configuration.agent(session, spreadsheet_key)
# @param agent [GoogleDrive::Spreadsheet] an spreadsheet agent
# (used internally only)
def initialize(session: nil, spreadsheet_key: nil, agent: nil)
@agent = agent
@session = session
@spreadsheet_key = spreadsheet_key
end

# @return [Boolean] Whether the worksheet has unsaved changes
def dirty?
ws.dirty?
end

# @return [String] the spreadsheet version
# @see AspireBudget::Worksheets::BackendData#version
def spreadsheet_version
@backend_data ||= BackendData.new(agent: agent)
@backend_data.version
end

private

def ws
Expand All @@ -51,7 +62,11 @@ def ws

def worksheets
@worksheets ||=
@agent.worksheets.reduce({}) { |h, sheet| h.merge(sheet.title => sheet) }
agent.worksheets.reduce({}) { |h, sheet| h.merge(sheet.title => sheet) }
end

def agent
@agent ||= AspireBudget.configuration.agent(@session, @spreadsheet_key)
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions spec/fixtures/v3-1-0/dashboard_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"currency": [
[5, 3],
[6, 3],
[7, 3]
]
}
8 changes: 8 additions & 0 deletions spec/fixtures/v3-2-0/dashboard_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"currency": [
[2, 8],
[2, 9],
[2, 11],
[2, 15]
]
}
32 changes: 32 additions & 0 deletions spec/worksheets/dashboard_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

RSpec.describe AspireBudget::Worksheets::Dashboard do
context 'when on 3.2.0' do
describe 'immediate methods' do
before { use_spreadsheet_version 'v3-2-0' }

it 'returns the expected values' do
expect(subject.available_to_budget).to eq 11_505.0
expect(subject.spent_this_month).to eq 0.0
expect(subject.budgeted_this_month).to eq 0.0
expect(subject.pending_transactions).to eq 0.0
end
end
end

context 'when on 3.1.0' do
describe 'immediate methods' do
before { use_spreadsheet_version 'v3-1-0' }

it 'returns the expected values' do
expect(subject.available_to_budget).to eq(-495.00) # TODO: fix inconsistency
expect(subject.spent_this_month).to eq 0.0
expect(subject.pending_transactions).to eq 0.0
end

it 'raises on unavailable methods' do
expect { subject.budgeted_this_month }.to raise_error 'budgeted_this_month is not supported on 3.1.0'
end
end
end
end
23 changes: 10 additions & 13 deletions spec/worksheets/worksheet_base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,18 @@ def all
end
end

describe '.initialize' do
context 'when without arguments' do
it 'configures an agent without a session/key' do
allow(AspireBudget.configuration).to receive(:agent)
subject.new
expect(AspireBudget.configuration).to have_received(:agent).once.with(nil, nil)
end
describe '#spreadsheet_version' do
before do
backend_data = double
allow(AspireBudget::Worksheets::BackendData)
.to receive(:new)
.with(agent: an_instance_of(GoogleDrive::Spreadsheet))
.and_return(backend_data)
allow(backend_data).to receive(:version).and_return('0.0.0')
end

context 'when specifiying session and spreadsheet_key' do
it 'configures an agent with the specified arguments' do
allow(AspireBudget.configuration).to receive(:agent)
subject.new(session: 'foo', spreadsheet_key: 'bar')
expect(AspireBudget.configuration).to have_received(:agent).once.with('foo', 'bar')
end
it 'initializes the backenddata spreadsheet and calls #version on it' do
expect(subject.spreadsheet_version).to eq '0.0.0'
end
end
end