@@ -15,43 +15,19 @@ class Sub < Product; end
15
15
lambda_price_cents : 4000 )
16
16
end
17
17
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
+
18
26
describe ".monetize" do
19
27
let ( :service ) do
20
28
Service . create ( charge_cents : 2000 , discount_cents : 120 )
21
29
end
22
30
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
-
55
31
it "attaches a Money object to model field" do
56
32
expect ( product . price ) . to be_an_instance_of ( Money )
57
33
expect ( product . discount_value ) . to be_an_instance_of ( Money )
@@ -821,246 +797,5 @@ class SubProduct < Product
821
797
expect ( DummyProduct . currency ) . to eq ( Money ::Currency . find ( :gbp ) )
822
798
end
823
799
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
1065
800
end
1066
801
end
0 commit comments