Last active
September 24, 2016 18:12
-
-
Save lukemorton/260cc1535e67cd2a76c8463beaa64596 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
extend self | |
SENIOR_CITIZEN_DISCOUNT = 5 | |
def billable_accounts | |
Account.where(free: false) | |
end | |
def monthly_bill(account) | |
Bill.new( | |
account: account, | |
amount: account.plan.amount - discounts(account), | |
) | |
end | |
def discounts(account) | |
if account.type == :senior_citizen | |
SENIOR_CITIZEN_DISCOUNT | |
else | |
0 | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FactoryGirl.create_list(:account, 2) | |
expect(Billing.billable_accounts.count).to eq(2) | |
expect(Billing.billable_accounts).to include(a_kind_of(Account)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
expect(Account).to receive(:where).with(free: false).and_return([:account]) | |
expect(Billing.billable_accounts).to contain_exactly(:account) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
standard_account = double(type: :standard, plan: double(amount: 10)) | |
bill = Billing.monthly_bill(standard_account) | |
expect(bill.account).to eq(standard_account) | |
expect(bill.amount).to eq(10) | |
senior_account = double(type: :senior_citizen, plan: double(amount: 10)) | |
bill = Billing.monthly_bill(senior_account) | |
expect(bill.amount).to eq(5) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing) do | |
context 'calculating discount' do | |
it 'should calculate discount correctly' do | |
account = Account.new(type: :senior_citizen) | |
discount = Billing.discount(account) | |
expect(discount).to eq(5) | |
end | |
end | |
context 'retrieving billable accounts' do | |
it 'should retrieve billable accounts' do | |
expect(Account).to receive(:where).with(free: false).and_return([:account]) | |
expect(Billing.billable_accounts).to contain_exactly(:account) | |
end | |
end | |
context 'creating monthly bill' do | |
it 'should create £10 bill for standard account' do | |
standard_account = double(type: :standard, plan: double(amount: 10)) | |
bill = Billing.monthly_bill(standard_account) | |
expect(bill.account).to eq(standard_account) | |
expect(bill.amount).to eq(10) | |
end | |
it 'should create £5 bill for senior citizen' do | |
senior_account = double(type: :senior_citizen, plan: double(amount: 10)) | |
bill = Billing.monthly_bill(senior_account) | |
expect(bill.amount).to eq(5) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
# [..] | |
private | |
def discounts(account) | |
if account.type == :senior_citizen | |
SENIOR_CITIZEN_DISCOUNT | |
else | |
0 | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
module Accounts | |
extend self | |
def all | |
Account.where(free: false) | |
end | |
end | |
module MonthlyBill | |
extend self | |
SENIOR_CITIZEN_DISCOUNT = 5 | |
def for_account(account) | |
Bill.new( | |
account: account, | |
amount: account.plan.amount - discounts(account), | |
) | |
end | |
private | |
def discounts(account) | |
if account.type == :senior_citizen | |
SENIOR_CITIZEN_DISCOUNT | |
else | |
0 | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing::Accounts) do | |
context 'retrieving billable accounts' do | |
it 'should retrieve billable accounts' do | |
expect(Account).to receive(:where).with(free: false).and_return([:account]) | |
expect(Billing::Accounts.all).to contain_exactly(:account) | |
end | |
end | |
end | |
describe(Billing::MonthlyBill) | |
context 'creating monthly bill' do | |
it 'should create £10 bill for standard account' do | |
standard_account = double(type: :standard, plan: double(amount: 10)) | |
bill = Billing::MonthlyBill.for_account(standard_account) | |
expect(bill.account).to eq(standard_account) | |
expect(bill.amount).to eq(10) | |
end | |
it 'should create £5 bill for senior citizen' do | |
senior_account = double(type: :senior_citizen, plan: double(amount: 10)) | |
bill = Billing::MonthlyBill.monthly_bill(senior_account) | |
expect(bill.amount).to eq(5) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MonthlyBillingJob | |
def perform | |
Billing::Accounts.all.each do |account| | |
bill = Billing::MonthlyBill.for_account(account) | |
bill.save! | |
BillMailer.new_bill(bill).deliver_now | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MonthlyBillingJob | |
def perform(create_and_send_monthly_bill) | |
create_and_send_monthly_bill.to_all_accounts | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(MonthlyBillingJob) do | |
it 'should send bills to all accounts' do | |
create_and_send_monthly_bill = double(to_all_accounts: nil) | |
MonthlyBillingJob.new.perform(create_and_send_monthly_bill) | |
expect(create_and_send_monthly_bill).to have_received(:to_all_accounts) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
class CreateAndSendMonthlyBill | |
def to_all_accounts | |
Billing::Accounts.all.each do |account| | |
bill = Billing::MonthlyBill.for_account(account) | |
bill.save! | |
BillMailer.new_bill(bill).deliver_now | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing::CreateAndSendMonthlyBill) do | |
it 'should create and send bills to all accounts' do | |
account = double(type: :standard, plan: double(amount: 10)) | |
expect(Account).to receive(:where).with(free: false).and_return([account]) | |
bill = double(save!: true) | |
expect(bill).to receive(:save!) | |
expect(Billing::MonthlyBill).to receive(:for_account).and_return(bill) | |
mail = double(deliver_now: nil) | |
expect(BillMailer).to receive(:new_bill).and_return(mail) | |
expect(mail).to receive(:deliver_now) | |
sender = Billing::CreateAndSendMonthlyBill.new | |
sender.to_all_accounts | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing::CreateAndSendMonthlyBill) do | |
it 'should create and send bills to all accounts' do | |
billing_accounts = double(all: [:account]) | |
bill = double(save!: true) | |
expect(bill).to receive(:save!) | |
monthly_bill_initialiser = double(for_account: bill) | |
mail = double(deliver_now: nil) | |
expect(BillMailer).to receive(:new_bill).and_return(mail) | |
expect(mail).to receive(:deliver_now) | |
sender = Billing::CreateAndSendMonthlyBill.new( | |
billing_accounts: billing_accounts, | |
monthly_bill_initialiser: monthly_bill_initialiser, | |
) | |
sender.to_all_accounts | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
class CreateAndSendMonthlyBill | |
def initialize( | |
billing_accounts: Billing::Accounts, | |
monthly_bill_initialiser: Billing::MonthlyBill | |
) | |
@billing_accounts = billing_accounts | |
@monthly_bill_initialiser = monthly_bill_initialiser | |
end | |
def to_all_accounts | |
@billing_accounts.all.each do |account| | |
bill = @monthly_bill_initialiser.for_account(account) | |
bill.save! | |
BillMailer.new_bill(bill).deliver_now | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
class CreateAndSendMonthlyBill | |
def initialize( | |
billing_accounts: Accounts, | |
create_monthly_bill: CreateMonthlyBill.new, | |
send_monthly_bill: SendMonthlyBill.new | |
) | |
@billing_accounts = billing_accounts | |
@create_monthly_bill = create_monthly_bill | |
@send_monthly_bill = send_monthly_bill | |
end | |
def to_all_accounts | |
@billing_accounts.all.each do |account| | |
bill = @create_monthly_bill.for_account(account) | |
@send_monthly_bill.send(bill) | |
end | |
end | |
end | |
end | |
module Billing | |
class CreateMonthlyBill | |
def initialize(monthly_bill_initialiser: Billing::MonthlyBill) | |
@monthly_bill_initialiser = monthly_bill_initialiser | |
end | |
def for_account(account) | |
bill = @monthly_bill_initialiser.for_account(account) | |
bill.save! | |
bill | |
end | |
end | |
end | |
module Billing | |
class SendMonthlyBill | |
def send(bill) | |
BillMailer.new_bill(bill).deliver_now | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing::CreateMonthlyBill) do | |
it 'should create bill for account' do | |
bill = double(save!: true) | |
expect(bill).to receive(:save!) | |
monthly_bill_initialiser = double(for_account: bill) | |
create_monthly_bill = Billing::CreateMonthlyBill.new( | |
monthly_bill_initialiser: monthly_bill_initialiser, | |
) | |
create_monthly_bill.for_account(:account) | |
end | |
end | |
describe(Billing::SendMonthlyBill) do | |
it 'should send bill' do | |
mail = double(deliver_now: nil) | |
expect(BillMailer).to receive(:new_bill).and_return(mail) | |
expect(mail).to receive(:deliver_now) | |
send_monthly_bill = Billing::SendMonthlyBill.new | |
send_monthly_bill.send(:buil) | |
end | |
end | |
describe(Billing::CreateAndSendMonthlyBill) do | |
it 'should create and send bills to all accounts' do | |
create_monthly_bill = double(for_account: :bill) | |
send_monthly_bill = double(send: :bill) | |
sender = Billing::CreateAndSendMonthlyBill.new( | |
billing_accounts: double(all: [:account]), | |
create_monthly_bill: create_monthly_bill, | |
send_monthly_bill: send_monthly_bill, | |
) | |
sender.to_all_accounts | |
expect(create_monthly_bill).to have_received(:for_account) | |
expect(send_monthly_bill).to have_received(:send) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
class FindAccounts | |
def all | |
Account.where(free: false) | |
end | |
end | |
end | |
describe(Billing::FindAccounts) do | |
context 'retrieving billable accounts' do | |
it 'should retrieve billable accounts' do | |
expect(Account).to receive(:where).with(free: false).and_return([:account]) | |
expect(Billing::FindAccounts.new.all).to contain_exactly(:account) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Billing | |
class CreateMonthlyBill | |
SENIOR_CITIZEN_DISCOUNT = 5 | |
def initialize(bill: Bill.new) | |
@bill = bill | |
end | |
def for_account(account) | |
@bill.account = account | |
@bill.amount = account.plan.amount - discounts(account) | |
@bill.save! | |
@bill | |
end | |
private | |
def discounts(account) | |
if account.type == :senior_citizen | |
SENIOR_CITIZEN_DISCOUNT | |
else | |
0 | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe(Billing::CreateMonthlyBill) do | |
context 'creating monthly bill' do | |
let(:bill) do | |
double( | |
:account= => nil, | |
:amount= => nil, | |
:save! => true | |
) | |
end | |
it 'should create £10 bill for standard account' do | |
standard_account = double(type: :standard, plan: double(amount: 10)) | |
Billing::CreateMonthlyBill.new(bill: bill).for_account(standard_account) | |
expect(bill).to have_received(:account=).with(standard_account) | |
expect(bill).to have_received(:amount=).with(10) | |
expect(bill).to have_received(:save!) | |
end | |
it 'should create £5 bill for senior citizen' do | |
senior_account = double(type: :senior_citizen, plan: double(amount: 10)) | |
Billing::CreateMonthlyBill.new(bill: bill).for_account(senior_account) | |
expect(bill).to have_received(:amount=).with(5) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app | |
├── jobs | |
│ └── monthly_billing_job.rb | |
├── mailers | |
│ └── bill_mailer.rb | |
└── models | |
├── account.rb | |
└── bill.rb | |
lib | |
├── billing | |
│ ├── create_and_send_monthly_bill.rb | |
│ ├── create_monthly_bill.rb | |
│ ├── find_accounts.rb | |
│ └── send_monthly_bill.rb | |
└── dependencies.rb | |
spec/app | |
└── jobs | |
└── monthly_billing_job_spec.rb | |
spec/lib | |
└── billing | |
├── create_and_send_monthly_bill_spec.rb | |
├── create_monthly_bill_spec.rb | |
├── find_accounts_spec.rb | |
└── send_monthly_bill_spec.rb |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
lib/billing | |
├── create_and_send_monthly_bill.rb | |
├── create_monthly_bill.rb | |
└── send_monthly_bill.rb | |
spec/billing | |
├── create_and_send_monthly_bill_spec.rb | |
├── create_monthly_bill_spec.rb | |
└── send_monthly_bill_spec.rb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment