Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: dontangg/envelopes
base: 87fd342421
...
head fork: dontangg/envelopes
compare: 81ce1eafed
  • 6 commits
  • 20 files changed
  • 0 commit comments
  • 1 contributor
View
7 Gemfile
@@ -2,10 +2,12 @@ source 'http://rubygems.org'
gem 'rails', '3.2.2'
gem 'unicorn' unless RUBY_PLATFORM =~ /mingw32/i
+gem 'mongoid', '~> 2.4.7'
+gem 'bson_ext', '~> 1.6.1'
gem 'jquery-rails'
gem 'cancan', '~> 1.6'
gem 'syrup', '~> 0.0.9'
-gem 'gibberish'
+gem 'gibberish', '~> 1.2.0' # To encrypt bank passwords
gem 'bcrypt-ruby', '~> 3.0.0' # To use ActiveModel has_secure_password
# gem 'ruby-debug19', :require => 'ruby-debug' # To use debugger
@@ -16,7 +18,7 @@ group :assets do
gem 'uglifier', '>= 1.0.3'
end
-gem 'sqlite3', group: [:development, :test]
+gem 'factory_girl_rails', group: [:development, :test]
group :development do
gem 'guard-test'
@@ -24,4 +26,3 @@ group :development do
gem 'foreman'
end
-gem 'pg', group: :production
View
40 Gemfile.lock
@@ -31,6 +31,9 @@ GEM
arel (3.0.2)
bcrypt-ruby (3.0.1)
bcrypt-ruby (3.0.1-x86-mingw32)
+ bson (1.6.1)
+ bson_ext (1.6.1)
+ bson (~> 1.6.1)
builder (3.0.0)
cancan (1.6.7)
coffee-rails (3.2.2)
@@ -45,12 +48,15 @@ GEM
erubis (2.7.0)
execjs (1.3.0)
multi_json (~> 1.0)
+ factory_girl (3.0.0)
+ activesupport (>= 3.0.0)
+ factory_girl_rails (3.0.0)
+ factory_girl (~> 3.0.0)
+ railties (>= 3.0.0)
ffi (1.0.11)
- foreman (0.40.0)
- term-ansicolor (~> 1.0.7)
+ foreman (0.41.0)
thor (>= 0.13.6)
- foreman (0.40.0-x86-mingw32)
- term-ansicolor (~> 1.0.7)
+ foreman (0.41.0-x86-mingw32)
thor (>= 0.13.6)
win32console (~> 1.3.0)
gibberish (1.2.0)
@@ -67,8 +73,8 @@ GEM
railties (>= 3.2.0, < 5.0)
thor (~> 0.14)
json (1.6.5)
- kgio (2.7.2)
- mail (2.4.3)
+ kgio (2.7.4)
+ mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
@@ -80,15 +86,19 @@ GEM
nokogiri (~> 1.4)
ntlm-http (~> 0.1, >= 0.1.1)
webrobots (~> 0.0, >= 0.0.9)
- mime-types (1.17.2)
+ mime-types (1.18)
+ mongo (1.6.1)
+ bson (~> 1.6.1)
+ mongoid (2.4.7)
+ activemodel (~> 3.1)
+ mongo (~> 1.3)
+ tzinfo (~> 0.3.22)
multi_json (1.1.0)
net-http-digest_auth (1.2)
net-http-persistent (2.5.2)
nokogiri (1.5.2)
nokogiri (1.5.2-x86-mingw32)
ntlm-http (0.1.1)
- pg (0.13.2)
- pg (0.13.2-x86-mingw32)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.2)
@@ -118,7 +128,7 @@ GEM
rdoc (3.12)
json (~> 1.4)
sass (3.1.15)
- sass-rails (3.2.4)
+ sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
@@ -126,12 +136,9 @@ GEM
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
- sqlite3 (1.3.5)
- sqlite3 (1.3.5-x86-mingw32)
syrup (0.0.9)
mechanize (>= 1.0.0)
multi_json (>= 1.0.3)
- term-ansicolor (1.0.7)
test-unit (2.4.8)
thor (0.14.6)
tilt (1.3.3)
@@ -159,17 +166,18 @@ PLATFORMS
DEPENDENCIES
bcrypt-ruby (~> 3.0.0)
+ bson_ext (~> 1.6.1)
cancan (~> 1.6)
coffee-rails (~> 3.2.1)
+ factory_girl_rails
foreman
- gibberish
+ gibberish (~> 1.2.0)
guard-test
jquery-rails
- pg
+ mongoid (~> 2.4.7)
rails (= 3.2.2)
rb-fsevent
sass-rails (~> 3.2.3)
- sqlite3
syrup (~> 0.0.9)
uglifier (>= 1.0.3)
unicorn
View
43 app/models/bank.rb
@@ -0,0 +1,43 @@
+class Bank
+ include Mongoid::Document
+
+ embedded_in :user
+ embeds_many :secret_questions
+
+ field :syrup_id, type: String
+ field :username, type: String
+ field :password_cipher, type: String
+ field :account_id, type: String
+ field :imported_at, type: DateTime
+
+ # don't include a mongo id on this embedded document
+ def identify
+ end
+
+ def password
+ unless self.password_cipher.blank?
+ cipher = Gibberish::AES.new(user.email + 's')
+ cipher.dec(self.password_cipher)
+ end
+ end
+
+ def password=(unencrypted_password)
+ unless unencrypted_password.blank?
+ cipher = Gibberish::AES.new(user.email + 's')
+ self.password_cipher = cipher.enc(unencrypted_password)
+ end
+ end
+
+end
+
+class SecretQuestion
+ include Mongoid::Document
+
+ embedded_in :bank
+
+ field :question, type: String
+ field :answer, type: String
+
+ def identify
+ end
+end
View
154 app/models/envelope.rb
@@ -1,20 +1,112 @@
-class Envelope < ActiveRecord::Base
+class Envelope
+ include Mongoid::Document
- default_scope order(arel_table[:name])
- scope :owned_by, lambda { |user_id| where(user_id: user_id) }
+ embedded_in :user
+ embeds_one :expense
+
+ field :name, type: String
+ field :income, type: Boolean
+ field :unassigned, type: Boolean
+ field :parent_envelope_id, type: BSON::ObjectId
+
+ default_scope order_by([[:name, :asc]])
scope :income, where(income: true)
scope :unassigned, where(unassigned: true)
scope :generic, where(income: false, unassigned: false)
- belongs_to :user
- belongs_to :parent_envelope, class_name: 'Envelope', foreign_key: 'parent_envelope_id'
- has_many :child_envelopes, class_name: 'Envelope', foreign_key: 'parent_envelope_id'
- has_many :transactions
+ ##has_many :transactions
- after_create :move_parents_transactions
- before_destroy :check_for_transactions
+ ##after_create :move_parents_transactions
+ ##before_destroy :check_for_transactions
- serialize :expense, Expense
+ class << self
+ #def income
+ # self.first(conditions: {income: true}) #where(income: true)
+ #end
+ end
+
+ # This overrides the default to_param method that just returns id
+ def to_param
+ name.parameterize if id # I think that this needs to return nil if this envelope hasn't been saved
+ end
+
+ def parent_envelope_id=(new_id)
+ super
+ @parent_envelope = nil
+ end
+
+ def parent_envelope
+ if self.parent_envelope_id
+ @parent_envelope ||= self.user.envelopes.select { |envelope| envelope.id == self.parent_envelope_id }.first
+ else
+ nil
+ end
+ end
+
+ def parent_envelope=(new_parent_envelope)
+ @parent_envelope = nil
+ self.parent_envelope_id = new_parent_envelope.id
+ end
+
+ def child_envelopes
+ @child_envelopes ||= self.user.envelopes.select { |envelope| self.id == envelope.parent_envelope_id }
+ end
+
+ def self_and_child_envelope_ids
+ child_ids = [self.id]
+
+ child_envelopes.each do |child|
+ child_ids.concat child.self_and_child_envelope_ids
+ end
+
+ child_ids
+ end
+
+ def transactions(start_date, end_date = Date.today)
+ start_year_month = start_date.strftime("%Y-%m")
+ end_year_month = end_date.strftime("%Y-%m")
+ groups = TransactionGroup.where(:year_month.gte => start_year_month)
+ .and(:year_month.lte => end_year_month)
+ .and(:envelope_id.in => self_and_child_envelope_ids)
+ .desc(:year_month)
+ transactions = []
+ groups.each do |group|
+ group.transactions.each do |txn|
+ transactions << txn if txn.posted_at >= start_date && txn.posted_at <= end_date
+ end
+ end
+
+ # Sort by posted_at, then payee, then unique_count
+ transactions.sort! do |a, b|
+ result = b.posted_at <=> a.posted_at
+ if result == 0
+ result = a.payee <=> b.payee
+ if result == 0
+ result = a.unique_count <=> b.unique_count
+ end
+ end
+
+ result
+ end
+
+ transactions
+ end
+
+ def total_amount
+ unless @total_amount
+ # Add up all child envelopes transactions
+ @total_amount = child_envelopes.inject(0) { |running_total, child_envelope| running_total + (child_envelope.total_amount || 0) }
+
+ # Add up all my transactions
+ groups = TransactionGroup.where(envelope_id: self.id).only(:total_amount)
+ @total_amount = groups.inject(@total_amount) { |running_total, group| running_total + (group.total_amount || 0) }
+ end
+ @total_amount
+ end
+
+
+ ###############
+
attr_accessor :suggested_amount
@@ -44,19 +136,9 @@ def expense=(new_expense)
end
end
- # This overrides the default to_param method that just returns id
- # This causes our find method to still work because find calls to_i() on it which will just return the id
- def to_param
- "#{id}-#{name.parameterize}" if id
- end
-
- def total_amount
- @total_amount ||= read_attribute(:total_amount) || transactions.sum(:amount)
- end
-
- def total_amount=(new_amount)
- @total_amount = new_amount
- end
+ #def total_amount=(new_amount)
+ # @total_amount = new_amount
+ #end
def inclusive_total_amount(organized_envelopes = nil)
children = organized_envelopes.nil? ? self.child_envelopes : organized_envelopes[id]
@@ -69,9 +151,7 @@ def full_name(all_envelopes = nil)
name = if parent_envelope_id.nil?
self.name
else
- parent_envelope = all_envelopes ? all_envelopes.select {|envelope| envelope.id == self.parent_envelope_id}.first : Envelope.find(self.parent_envelope_id)
-
- parent_full_name = parent_envelope.full_name(all_envelopes)
+ parent_full_name = self.parent_envelope.full_name(all_envelopes)
"#{parent_full_name}: #{self.name}"
end
@@ -154,28 +234,6 @@ def self.add_funded_this_month(envelopes, user_id)
end
end
- def all_transactions(organized_envelopes = nil)
- if self.id == 0 && organized_envelopes.present? # All Transactions envelope
- all_child_envelope_ids = []
- organized_envelopes[nil].each do |envelope|
- all_child_envelope_ids.concat Envelope.all_child_envelope_ids(envelope.id, organized_envelopes)
- end
- all_child_envelope_ids.concat organized_envelopes['sys']
- else
- all_child_envelope_ids = Envelope.all_child_envelope_ids(self.id, organized_envelopes) << self.id
- end
- Transaction.where(envelope_id: all_child_envelope_ids)
- end
-
- def self.all_child_envelope_ids(envelope_id, organized_envelopes = nil)
- children = organized_envelopes ? organized_envelopes[envelope_id] : Envelope.where(parent_envelope_id: envelope_id)
- all_child_ids = children.map(&:id)
- children.each do |child|
- all_child_ids << all_child_envelope_ids(child.id, organized_envelopes)
- end
- all_child_ids.flatten
- end
-
def self.all_envelope(total_amount = nil)
env = Envelope.new(name: 'All Transactions')
env.total_amount = total_amount if total_amount
View
1  app/models/expense.rb
@@ -1,4 +1,5 @@
class Expense
+ include Mongoid::Document
def amount
@amount ||= 0.0
View
20 app/models/rule.rb
@@ -1,12 +1,20 @@
-class Rule < ActiveRecord::Base
- default_scope order(arel_table[:order])
- scope :owned_by, lambda { |user_id| where(user_id: user_id) }
+class Rule
+ include Mongoid::Document
- validates_presence_of :search_text, :user_id
-
- belongs_to :user
+ embedded_in :user
belongs_to :envelope
+ field :search_text, type: String
+ field :replacement_text, type: String
+ field :order, type: Integer
+
+ default_scope order_by([[:order, :asc]])
+
+ validates_presence_of :search_text
+
+ def identify
+ end
+
def run(payee)
if payee && payee.downcase.include?(self.search_text.downcase)
payee = self.replacement_text if self.replacement_text.present?
View
22 app/models/transaction.rb
@@ -1,17 +1,17 @@
-class Transaction < ActiveRecord::Base
- default_scope order(arel_table[:posted_at].desc)
- scope :starting_at, lambda {|start_date| where(arel_table[:posted_at].gteq(start_date)) }
- scope :ending_at, lambda {|end_date| where(arel_table[:posted_at].lteq(end_date)) }
- scope :without_transfers, where(arel_table[:unique_id].not_eq(nil))
+class Transaction
+ ##default_scope order(arel_table[:posted_at].desc)
+ ##scope :starting_at, lambda {|start_date| where(arel_table[:posted_at].gteq(start_date)) }
+ ##scope :ending_at, lambda {|end_date| where(arel_table[:posted_at].lteq(end_date)) }
+ ##scope :without_transfers, where(arel_table[:unique_id].not_eq(nil))
- validates_presence_of :posted_at, :payee, :original_payee, :amount, :envelope_id
- validates_uniqueness_of :unique_id, :allow_nil => true
+ ##validates_presence_of :posted_at, :payee, :original_payee, :amount, :envelope_id
+ ##validates_uniqueness_of :unique_id, :allow_nil => true
- before_save :strip_payee
- after_save :check_associated_transaction
+ ##before_save :strip_payee
+ ##after_save :check_associated_transaction
- belongs_to :envelope
- belongs_to :associated_transaction, class_name: 'Transaction', foreign_key: 'associated_transaction_id'
+ ##belongs_to :envelope
+ ##belongs_to :associated_transaction, class_name: 'Transaction', foreign_key: 'associated_transaction_id'
def self.owned_by(user_id)
user_id = user_id.id if user_id.respond_to? :id
View
57 app/models/user.rb
@@ -1,31 +1,46 @@
-class User < ActiveRecord::Base
- attr_accessible :email, :password, :password_confirmation, :bank_id, :bank_username, :bank_password, :bank_secret_questions, :bank_account_id
+class User
+ include Mongoid::Document
+ include Mongoid::Timestamps
+ include ActiveModel::SecurePassword
+
+ # Define the fields
+ field :email, type: String
+ field :password_digest, type: String
+
+ # Define embeds
+ embeds_one :bank
+ embeds_many :rules
+ embeds_many :envelopes
+
+ # Mass asignment protection
+ attr_accessible :email, :password, :password_confirmation
+
has_secure_password
+
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email, :on => :create
- has_many :rules
-
- serialize :bank_secret_questions
+ class << self
+ def find_by_email(email)
+ self.first(conditions: {email: email})
+ end
+ end
- def email=(new_email)
- pass = self.bank_password
- super
- self.bank_password = pass
+ def income_envelope
+ self.envelopes.income.first
end
-
- def bank_password
- unless self.bank_password_cipher.blank?
- cipher = Gibberish::AES.new(self.email + 's')
- cipher.dec(self.bank_password_cipher)
- end
+
+ def unassigned_envelope
+ self.envelopes.unassigned.first
end
-
- def bank_password=(unencrypted_password)
- unless unencrypted_password.blank?
- cipher = Gibberish::AES.new(self.email + 's')
- self.bank_password_cipher = cipher.enc(unencrypted_password)
- end
+
+ def email=(new_email)
+ # Since the email is used while encrypting/decrypting the bank password,
+ # we need to make sure we update the encrypted value if the email changes
+ pass = self.bank.password if self.bank
+ super
+ self.bank.password = pass if self.bank
end
+
end
View
9 config/application.rb
@@ -1,6 +1,13 @@
require File.expand_path('../boot', __FILE__)
-require 'rails/all'
+# require 'rails/all'
+# require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "active_resource/railtie"
+require "sprockets/railtie"
+require "rails/test_unit/railtie"
+
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
View
25 config/database.yml
@@ -1,25 +0,0 @@
-# SQLite version 3.x
-# gem install sqlite3
-#
-# Ensure the SQLite 3 gem is defined in your Gemfile
-# gem 'sqlite3'
-development:
- adapter: sqlite3
- database: db/development.sqlite3
- pool: 5
- timeout: 5000
-
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
-test:
- adapter: sqlite3
- database: db/test.sqlite3
- pool: 5
- timeout: 5000
-
-production:
- adapter: sqlite3
- database: db/production.sqlite3
- pool: 5
- timeout: 5000
View
7 config/environments/development.rb
@@ -29,11 +29,14 @@
config.assets.debug = true
# Raise exception on mass assignment protection for Active Record models
- config.active_record.mass_assignment_sanitizer = :strict
+ # config.active_record.mass_assignment_sanitizer = :strict
+ # Mongoid supports this via attr_protected and attr_accessible
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
- config.active_record.auto_explain_threshold_in_seconds = 0.5
+ # config.active_record.auto_explain_threshold_in_seconds = 0.5
+ # Mongoid supports explain queries, but doesn't run them automatically
+ # Run them manually: y Model.where(...).execute.explain
config.log_tags = [:uuid, :remote_ip]
View
2  config/environments/test.rb
@@ -38,6 +38,6 @@
config.active_support.deprecation = :stderr
# Raise exception on mass assignment protection for Active Record models
- config.active_record.mass_assignment_sanitizer = :strict
+ # config.active_record.mass_assignment_sanitizer = :strict
end
View
10 config/mongoid.yml
@@ -0,0 +1,10 @@
+development:
+ host: localhost
+ database: envelopes
+
+test:
+ host: localhost
+ database: envelopes_test
+
+production:
+ uri: <%= ENV['MONGOLAB_URI'] %>
View
23 test/factories/envelopes.rb
@@ -0,0 +1,23 @@
+
+FactoryGirl.define do
+ factory :envelope do
+ user { FactoryGirl.build(:user) }
+ income false
+ unassigned false
+
+ factory :income_envelope do
+ name 'Available Cash'
+ income true
+ end
+
+ factory :unassigned_envelope do
+ name 'Unassigned'
+ unassigned true
+ end
+
+ factory :auto_envelope do
+ name 'Auto'
+ end
+ end
+end
+
View
11 test/factories/rules.rb
@@ -0,0 +1,11 @@
+
+FactoryGirl.define do
+ factory :rule do
+ user { FactoryGirl.build(:user) }
+ search_text 'WALMART'
+ replacement_text 'Walmart'
+ sequence :order
+ envelope_id 123
+ end
+end
+
View
12 test/factories/users.rb
@@ -0,0 +1,12 @@
+
+FactoryGirl.define do
+ factory :user do
+ email 'jim@example.com'
+ password 'jimpass'
+ #password_digest BCrypt::Password.create('jimpass')
+ end
+end
+
+##someone:
+## email: someone@example.com
+## password_digest: <%= BCrypt::Password.create('a pass') %>
View
21 test/test_helper.rb
@@ -3,19 +3,34 @@
require 'rails/test_help'
#require 'turn'
-
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
- fixtures :all
+ #
+ # fixtures :all
def login_as(user)
session[:user_id] = users(user).id
end
-
+
def logout
session.delete :user_id
end
end
+
+class ActiveSupport::TestCase
+ # Drop all collections after each test case.
+ def teardown
+ # TODO: Find out why data is still erased when the test fails
+ Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop) if self.passed?
+ end
+
+ # Make sure that each test case has a teardown method to clear the db after each test.
+ def inherited(base)
+ base.define_method teardown do
+ super
+ end
+ end
+end
View
93 test/unit/envelope_test.rb
@@ -1,16 +1,17 @@
require 'test_helper'
class EnvelopeTest < ActiveSupport::TestCase
- test "owned_by scope should return envelopes owned by the user specified" do
- envelopes = Envelope.owned_by(1)
-
- envelopes.each do |envelope|
- assert_equal 1, envelope.user_id, "owned_by(1) should only return envelopes owned by user 1"
- end
+ def setup_envelopes
+ income_envelope = FactoryGirl.create(:income_envelope)
+ user = income_envelope.user
+ @user_id = user.id
+ FactoryGirl.create(:unassigned_envelope, user: user)
+ FactoryGirl.create(:auto_envelope, user: user)
end
-
+
test "income scope should return income envelopes" do
- envelope = Envelope.income.first
+ setup_envelopes
+ envelope = User.find(@user_id).envelopes.income.first
assert_equal "Available Cash", envelope.name
assert envelope.parent_envelope_id.nil?, "The income envelope should not have a parent envelope"
@@ -19,7 +20,8 @@ class EnvelopeTest < ActiveSupport::TestCase
end
test "unassigned scope should return unassigned envelopes" do
- envelope = Envelope.unassigned.first
+ setup_envelopes
+ envelope = User.find(@user_id).envelopes.unassigned.first
assert "Unassigned", envelope.name
assert envelope.parent_envelope_id.nil?, "The unassigned envelope should not have a parent envelope"
@@ -28,24 +30,27 @@ class EnvelopeTest < ActiveSupport::TestCase
end
test "generic scope should return generic envelopes" do
- envelopes = Envelope.generic
+ setup_envelopes
+ envelopes = User.find(@user_id).envelopes.generic
+
+ assert !envelopes.empty?, "Can't do a proper test without any generic envelopes"
envelopes.each do |envelope|
- assert !envelope.income?
- assert !envelope.unassigned?
+ assert !envelope.income?, "Generic envelopes are not income envelopes"
+ assert !envelope.unassigned?, "Generic envelopes are not unassigned envelopes"
end
end
test "parent_envelope returns the parent envelope" do
- fuel_envelope = envelopes(:fuel)
- auto_envelope = envelopes(:auto)
+ auto_envelope = FactoryGirl.create(:envelope, name: 'Auto')
+ fuel_envelope = FactoryGirl.create(:envelope, name: 'Fuel', user: auto_envelope.user, parent_envelope: auto_envelope)
assert_equal auto_envelope, fuel_envelope.parent_envelope
end
test "child_envelopes returns the child envelopes" do
- fuel_envelope = envelopes(:fuel)
- auto_envelope = envelopes(:auto)
+ auto_envelope = FactoryGirl.create(:envelope, name: 'Auto')
+ fuel_envelope = FactoryGirl.create(:envelope, name: 'Fuel', user: auto_envelope.user, parent_envelope: auto_envelope)
assert auto_envelope.child_envelopes.include?(fuel_envelope)
end
@@ -68,21 +73,24 @@ class EnvelopeTest < ActiveSupport::TestCase
assert_equal :yearly, new_envelope.expense.frequency
end
- test "to_param returns id-name.parameterize" do
- envelope = envelopes(:available_cash)
+ test "to_param returns name.parameterize" do
+ auto_envelope = FactoryGirl.create(:envelope, name: 'Available Cash')
- assert_equal "#{envelope.id}-available-cash", envelope.to_param
+ assert_equal "available-cash", auto_envelope.to_param
end
- test "transactions scope returns all transactions for this envelope" do
- food_envelope = envelopes(:food)
- assert_equal 2, food_envelope.transactions.size
-
- auto_envelope = envelopes(:auto)
- assert_equal 0, auto_envelope.transactions.size
-
- cash_envelope = envelopes(:available_cash)
- assert_equal 1, cash_envelope.transactions.size
+ test "transactions scope returns all transactions and child transactions for this envelope" do
+ # Create envelopes
+ gifts_envelope = FactoryGirl.create(:envelope, name: 'Gifts')
+ holidays_envelope = FactoryGirl.create(:envelope, name: 'Holidays', user: gifts_envelope.user, parent_envelope: gifts_envelope)
+ christmas_envelope = FactoryGirl.create(:envelope, name: 'Christmas', user: gifts_envelope.user, parent_envelope: holidays_envelope)
+
+ # Create transactions
+ FactoryGirl.create(:transaction)
+
+ transactions = gifts_envelope.all_transactions(Date.today - 1.month)
+
+ assert_equal 3, transactions.size
end
test "total_amount returns sum of all transactions" do
@@ -96,26 +104,23 @@ class EnvelopeTest < ActiveSupport::TestCase
end
test "full_name returns this and parent envelope names separated by colons" do
- food_envelope = envelopes(:food)
- assert_equal "Food", food_envelope.full_name
-
- groceries_envelope = envelopes(:groceries)
- assert_equal "Food: Groceries", groceries_envelope.full_name
+ gifts_envelope = FactoryGirl.create(:envelope, name: 'Gifts')
+ holidays_envelope = FactoryGirl.create(:envelope, name: 'Holidays', user: gifts_envelope.user, parent_envelope: gifts_envelope)
+ christmas_envelope = FactoryGirl.create(:envelope, name: 'Christmas', user: gifts_envelope.user, parent_envelope: holidays_envelope)
+
+ assert_equal "Gifts", gifts_envelope.full_name
+ assert_equal "Gifts: Holidays", holidays_envelope.full_name
+ assert_equal "Gifts: Holidays: Christmas", christmas_envelope.full_name
end
- test "all_child_envelope_ids returns an array of all child envelope ids" do
- child_envelope_ids = Envelope.all_child_envelope_ids(envelopes(:gifts).id)
- assert_equal [envelopes(:holidays).id, envelopes(:christmas).id, envelopes(:valentines).id], child_envelope_ids
+ test "self_and_child_envelope_ids returns an array of all child envelope ids" do
+ auto_envelope = FactoryGirl.create(:envelope, name: 'Auto')
+ fuel_envelope = FactoryGirl.create(:envelope, name: 'Fuel', user: auto_envelope.user, parent_envelope: auto_envelope)
+
+ child_envelope_ids = auto_envelope.self_and_child_envelope_ids
+ assert_equal [auto_envelope.id, fuel_envelope.id], child_envelope_ids
end
- test "all_transactions returns all transactions for that envelope and all children" do
- sql = envelopes(:gifts).all_transactions(nil).to_sql
- assert sql.include?(envelopes(:gifts).id.to_s)
- assert sql.include?(envelopes(:holidays).id.to_s)
- assert sql.include?(envelopes(:christmas).id.to_s)
- assert sql.include?(envelopes(:valentines).id.to_s)
- end
-
test "amount_funded_this_month returns a sum of the positive transaction amounts" do
amount = envelopes(:groceries).amount_funded_this_month.to_f
View
46 test/unit/rule_test.rb
@@ -1,18 +1,40 @@
require 'test_helper'
class RuleTest < ActiveSupport::TestCase
- test "search text and user id are required" do
- rule = Rule.new
- assert !rule.save
-
- rule.user_id = users(:jim).id
- assert !rule.save
- rule.user_id = nil
-
- rule.search_text = 'test'
- assert !rule.save
+ test "search text is required" do
+ user = FactoryGirl.create(:user)
+
+ rule = user.rules.build
+ assert !user.save
- rule.user_id = users(:jim).id
- assert rule.save
+ rule.search_text = 'test search text'
+ assert user.save
+ end
+
+ test "running a rule returns the correct replacement and envelope id" do
+ rule = FactoryGirl.create(:rule)
+
+ result = rule.run("12398465 P.O.S. WALMART 142")
+
+ assert_equal "Walmart", result[0]
+ assert_equal 123, result[1]
+ end
+
+ test "rules should be read in the right order" do
+ user = FactoryGirl.create(:user)
+
+ FactoryGirl.create(:rule, user: user, order: 2)
+ FactoryGirl.create(:rule, user: user, order: 1)
+ FactoryGirl.create(:rule, user: user, order: 4)
+ FactoryGirl.create(:rule, user: user, order: 3)
+
+ # Read the user to get the order right
+ user = User.find(user.id)
+
+ prev_order = 0
+ user.rules.each do |rule|
+ assert prev_order < rule.order, "Rules should be ordered (#{prev_order} < #{rule.order})"
+ prev_order = rule.order
+ end
end
end
View
48 test/unit/user_test.rb
@@ -9,13 +9,55 @@ class UserTest < ActiveSupport::TestCase
assert !u.save, "Saved the user without an email"
end
+ test "should save with correct info supplied" do
+ u = User.new(email: 'email', password: 'pass')
+
+ assert u.save, "Didn't save the user even though email and password were supplied"
+ end
+
test "if user changes their email address, the bank password is re-encrypted" do
- u = User.new(email: 'test', bank_password: 'mypass')
+ u = User.new(email: 'test')
+ u.build_bank
+ u.bank.password = 'mypass'
- assert_equal 'mypass', u.bank_password
+ assert_equal 'mypass', u.bank.password
u.email = 'newtest'
- assert_equal 'mypass', u.bank_password
+ assert_equal 'mypass', u.bank.password
+ end
+
+ test "should not allow duplicate emails to be saved" do
+ u1 = User.create(email: 'email', password: 'pass')
+
+ u2 = User.new(email: 'email', password: 'pass')
+
+ assert !u2.save, "Allowed multiple users to be created with the same email address"
end
+
+ test "should not allow password_digest to be mass assigned" do
+ u = User.new(email: 'email', password_digest: 'passdigest')
+
+ assert_equal 'email', u.email
+ assert u.password_digest.blank?
+
+ u.password_digest = 'passdigest'
+
+ assert_equal 'passdigest', u.password_digest
+ end
+
+ test "income_envelope should get the income envelope" do
+ user_id = FactoryGirl.create(:income_envelope).user.id
+ envelope = User.find(user_id).income_envelope
+
+ assert envelope.income?
+ end
+
+ test "unassigned_envelope should get the unassigned envelope" do
+ user_id = FactoryGirl.create(:unassigned_envelope).user.id
+ envelope = User.find(user_id).unassigned_envelope
+
+ assert envelope.unassigned?
+ end
+
end

No commit comments for this range

Something went wrong with that request. Please try again.