Skip to content

Commit f5b1978

Browse files
committed
Splitting the monetizable specs into separate files for better organization
1 parent ce4a0f5 commit f5b1978

File tree

2 files changed

+296
-273
lines changed

2 files changed

+296
-273
lines changed

spec/active_record/monetizable_spec.rb renamed to spec/active_record/monetizable/monetize_spec.rb

Lines changed: 8 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,19 @@ class Sub < Product; end
1515
lambda_price_cents: 4000)
1616
end
1717

18+
def update_product(*attributes)
19+
if defined?(::ActiveRecord::VERSION) && ::ActiveRecord::VERSION::MAJOR >= 5
20+
product.update(*attributes)
21+
else
22+
product.update_attributes(*attributes)
23+
end
24+
end
25+
1826
describe ".monetize" do
1927
let(:service) do
2028
Service.create(charge_cents: 2000, discount_cents: 120)
2129
end
2230

23-
def update_product(*attributes)
24-
if defined?(::ActiveRecord::VERSION) && ::ActiveRecord::VERSION::MAJOR >= 5
25-
product.update(*attributes)
26-
else
27-
product.update_attributes(*attributes)
28-
end
29-
end
30-
31-
context ".monetized_attributes" do
32-
33-
class InheritedMonetizeProduct < Product
34-
monetize :special_price_cents
35-
end
36-
37-
it "should be inherited by subclasses" do
38-
assert_monetized_attributes(Sub.monetized_attributes, Product.monetized_attributes)
39-
end
40-
41-
it "should be inherited by subclasses with new monetized attribute" do
42-
assert_monetized_attributes(InheritedMonetizeProduct.monetized_attributes, Product.monetized_attributes.merge(special_price: "special_price_cents"))
43-
end
44-
45-
def assert_monetized_attributes(monetized_attributes, expected_attributes)
46-
expect(monetized_attributes).to include expected_attributes
47-
expect(expected_attributes).to include monetized_attributes
48-
expect(monetized_attributes.size).to eql expected_attributes.size
49-
monetized_attributes.keys.each do |key|
50-
expect(key.is_a? String).to be_truthy
51-
end
52-
end
53-
end
54-
5531
it "attaches a Money object to model field" do
5632
expect(product.price).to be_an_instance_of(Money)
5733
expect(product.discount_value).to be_an_instance_of(Money)
@@ -821,246 +797,5 @@ class SubProduct < Product
821797
expect(DummyProduct.currency).to eq(Money::Currency.find(:gbp))
822798
end
823799
end
824-
825-
describe "#read_monetized" do
826-
it "returns monetized attribute's value" do
827-
reduced_price = product.read_monetized(:reduced_price, :reduced_price_cents)
828-
829-
expect(reduced_price).to be_an_instance_of(Money)
830-
expect(reduced_price).to eq(Money.new(product.reduced_price_cents, product.reduced_price_currency))
831-
end
832-
833-
context "memoize" do
834-
it "memoizes monetized attribute's value" do
835-
product.instance_variable_set '@reduced_price', nil
836-
reduced_price = product.read_monetized(:reduced_price, :reduced_price_cents)
837-
838-
expect(product.instance_variable_get('@reduced_price')).to eq(reduced_price)
839-
end
840-
841-
it "resets memoized attribute's value if amount has changed" do
842-
reduced_price = product.read_monetized(:reduced_price, :reduced_price_cents)
843-
product.reduced_price_cents = 100
844-
845-
expect(product.read_monetized(:reduced_price, :reduced_price_cents)).not_to eq(reduced_price)
846-
end
847-
848-
it "resets memoized attribute's value if currency has changed" do
849-
reduced_price = product.read_monetized(:reduced_price, :reduced_price_cents)
850-
product.reduced_price_currency = 'CAD'
851-
852-
expect(product.read_monetized(:reduced_price, :reduced_price_cents)).not_to eq(reduced_price)
853-
end
854-
end
855-
856-
context "with preserve_user_input set" do
857-
around(:each) do |example|
858-
MoneyRails::Configuration.preserve_user_input = true
859-
example.run
860-
MoneyRails::Configuration.preserve_user_input = false
861-
end
862-
863-
it "has no effect if validation passes" do
864-
product.price = '14'
865-
866-
expect(product.save).to be_truthy
867-
expect(product.read_monetized(:price, :price_cents).to_s).to eq('14.00')
868-
end
869-
870-
it "preserves user input if validation fails" do
871-
product.price = '14,0'
872-
873-
expect(product.save).to be_falsy
874-
expect(product.read_monetized(:price, :price_cents).to_s).to eq('14,0')
875-
end
876-
end
877-
878-
context "with a monetized attribute that is nil" do
879-
let(:service) do
880-
Service.create(discount_cents: nil)
881-
end
882-
let(:default_currency_lambda) { double("Default Currency Fallback") }
883-
subject { service.read_monetized(:discount, :discount_cents, options) }
884-
885-
around(:each) do |example|
886-
service # Instantiate instance which relies on Money.default_currency
887-
original_default_currency = Money.default_currency
888-
Money.default_currency = -> { default_currency_lambda.read_currency }
889-
example.run
890-
Money.default_currency = original_default_currency
891-
end
892-
893-
context "when allow_nil options is set" do
894-
let(:options) { { allow_nil: true } }
895-
it "does not attempt to read the fallback default currency" do
896-
expect(default_currency_lambda).not_to receive(:read_currency)
897-
subject
898-
end
899-
end
900-
end
901-
end
902-
903-
describe "#write_monetized" do
904-
let(:value) { Money.new(1_000, 'LVL') }
905-
906-
it "sets monetized attribute's value to Money object" do
907-
product.write_monetized :price, :price_cents, value, false, nil, {}
908-
909-
expect(product.price).to be_an_instance_of(Money)
910-
expect(product.price_cents).to eq(value.cents)
911-
# Because :price does not have a column for currency
912-
expect(product.price.currency).to eq(Product.currency)
913-
end
914-
915-
it "sets monetized attribute's value from a given Fixnum" do
916-
product.write_monetized :price, :price_cents, 10, false, nil, {}
917-
918-
expect(product.price).to be_an_instance_of(Money)
919-
expect(product.price_cents).to eq(1000)
920-
end
921-
922-
it "sets monetized attribute's value from a given Float" do
923-
product.write_monetized :price, :price_cents, 10.5, false, nil, {}
924-
925-
expect(product.price).to be_an_instance_of(Money)
926-
expect(product.price_cents).to eq(1050)
927-
end
928-
929-
it "resets monetized attribute when given blank input" do
930-
product.write_monetized :price, :price_cents, nil, false, nil, { allow_nil: true }
931-
932-
expect(product.price).to eq(nil)
933-
end
934-
935-
it "sets monetized attribute to 0 when given a blank value" do
936-
currency = product.price.currency
937-
product.write_monetized :price, :price_cents, nil, false, nil, {}
938-
939-
expect(product.price.amount).to eq(0)
940-
expect(product.price.currency).to eq(currency)
941-
end
942-
943-
it "does not memoize monetized attribute's value if currency is read-only" do
944-
product.write_monetized :price, :price_cents, value, false, nil, {}
945-
946-
price = product.instance_variable_get('@price')
947-
948-
expect(price).to be_an_instance_of(Money)
949-
expect(price.amount).not_to eq(value.amount)
950-
end
951-
952-
describe "instance_currency_name" do
953-
it "updates instance_currency_name attribute" do
954-
product.write_monetized :sale_price, :sale_price_amount, value, false, :sale_price_currency_code, {}
955-
956-
expect(product.sale_price).to eq(value)
957-
expect(product.sale_price_currency_code).to eq('LVL')
958-
end
959-
960-
it "memoizes monetized attribute's value with currency" do
961-
product.write_monetized :sale_price, :sale_price_amount, value, false, :sale_price_currency_code, {}
962-
963-
expect(product.instance_variable_get('@sale_price')).to eq(value)
964-
end
965-
966-
it "ignores empty instance_currency_name" do
967-
product.write_monetized :sale_price, :sale_price_amount, value, false, '', {}
968-
969-
expect(product.sale_price.amount).to eq(value.amount)
970-
expect(product.sale_price.currency).to eq(Product.currency)
971-
end
972-
973-
it "ignores instance_currency_name that model does not respond to" do
974-
product.write_monetized :sale_price, :sale_price_amount, value, false, :non_existing_currency, {}
975-
976-
expect(product.sale_price.amount).to eq(value.amount)
977-
expect(product.sale_price.currency).to eq(Product.currency)
978-
end
979-
end
980-
981-
describe "error handling" do
982-
let!(:old_price_value) { product.price }
983-
984-
it "ignores values that do not implement to_money method" do
985-
product.write_monetized :price, :price_cents, [10], false, nil, {}
986-
987-
expect(product.price).to eq(old_price_value)
988-
end
989-
990-
context "raise_error_on_money_parsing enabled" do
991-
before { MoneyRails.raise_error_on_money_parsing = true }
992-
after { MoneyRails.raise_error_on_money_parsing = false }
993-
994-
it "raises a MoneyRails::Error when given an invalid value" do
995-
expect {
996-
product.write_monetized :price, :price_cents, '10-50', false, nil, {}
997-
}.to raise_error(MoneyRails::Error)
998-
end
999-
1000-
it "raises a MoneyRails::Error error when trying to set invalid currency" do
1001-
allow(product).to receive(:currency_for_price).and_return('INVALID_CURRENCY')
1002-
expect {
1003-
product.write_monetized :price, :price_cents, 10, false, nil, {}
1004-
}.to raise_error(MoneyRails::Error)
1005-
end
1006-
end
1007-
1008-
context "raise_error_on_money_parsing disabled" do
1009-
it "ignores when given invalid value" do
1010-
product.write_monetized :price, :price_cents, '10-50', false, nil, {}
1011-
1012-
expect(product.price).to eq(old_price_value)
1013-
end
1014-
1015-
it "raises a MoneyRails::Error error when trying to set invalid currency" do
1016-
allow(product).to receive(:currency_for_price).and_return('INVALID_CURRENCY')
1017-
product.write_monetized :price, :price_cents, 10, false, nil, {}
1018-
1019-
# Can not use public accessor here because currency_for_price is stubbed
1020-
expect(product.instance_variable_get('@price')).to eq(old_price_value)
1021-
end
1022-
end
1023-
end
1024-
end
1025-
1026-
describe "#currency_for" do
1027-
it "detects currency based on instance currency name" do
1028-
product = Product.new(sale_price_currency_code: 'CAD')
1029-
currency = product.send(:currency_for, :sale_price, :sale_price_currency_code, nil)
1030-
1031-
expect(currency).to be_an_instance_of(Money::Currency)
1032-
expect(currency.iso_code).to eq('CAD')
1033-
end
1034-
1035-
it "detects currency based on currency passed as a block" do
1036-
product = Product.new
1037-
currency = product.send(:currency_for, :lambda_price, nil, ->(_) { 'CAD' })
1038-
1039-
expect(currency).to be_an_instance_of(Money::Currency)
1040-
expect(currency.iso_code).to eq('CAD')
1041-
end
1042-
1043-
it "detects currency based on currency passed explicitly" do
1044-
product = Product.new
1045-
currency = product.send(:currency_for, :bonus, nil, 'CAD')
1046-
1047-
expect(currency).to be_an_instance_of(Money::Currency)
1048-
expect(currency.iso_code).to eq('CAD')
1049-
end
1050-
1051-
it "falls back to a registered currency" do
1052-
product = Product.new
1053-
currency = product.send(:currency_for, :amount, nil, nil)
1054-
1055-
expect(currency).to eq(Product.currency)
1056-
end
1057-
1058-
it "falls back to a default currency" do
1059-
transaction = Transaction.new
1060-
currency = transaction.send(:currency_for, :amount, nil, nil)
1061-
1062-
expect(currency).to eq(Money.default_currency)
1063-
end
1064-
end
1065800
end
1066801
end

0 commit comments

Comments
 (0)