spree_core 3.1.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 92d2afeeba8bb057bcc78631c40187c1a5e77670
4
- data.tar.gz: 80cbb5297dc213e88e6e6a77d159a1ef6c5bea9a
3
+ metadata.gz: f10756db13ed5d6d5984d269af218f2ccc7f7d4a
4
+ data.tar.gz: 85728381ad5af005d31a82260b10f11d15c6a9e6
5
5
  SHA512:
6
- metadata.gz: 062f9429e4900f53a5f5925a29188ecdd56a63820f84fdbe43454a83393011c8e144b7e6349732a21cef8cf6fc02de2a94a7dc5b52eef0ddc78fb20aa4653404
7
- data.tar.gz: ace59dff074f95170b53c700edf77f15313e9b52eb42666f656fe0acdc99dff915b79f4330df4e6783326de0fce2d71def5e1bd2df26b4923cbf7c841b5930ec
6
+ metadata.gz: 2797ef84ec18533481db667260412257ff2263ac6dcca19c404e3fd6eac1f9e345ad71bd61457eab3b1992a74074203681ea94b924133bd9ff0778976ffb99c4
7
+ data.tar.gz: 2142a9ccd940c194ce71c6bc4ed9be2352f406a7e9b8022985e8d8ae1c0c9030024c43dde98b34dda5c546b5ddddd7710f041b6b9672478e4f4fdfff32caf4f1
@@ -60,7 +60,7 @@ module Spree
60
60
  end
61
61
 
62
62
  # Include any abilities registered by extensions, etc.
63
- Ability.abilities.each do |clazz|
63
+ Ability.abilities.merge(abilities_to_register).each do |clazz|
64
64
  ability = clazz.send(:new, user)
65
65
  @rules = rules + ability.send(:rules)
66
66
  end
@@ -68,5 +68,13 @@ module Spree
68
68
  # Protect admin role
69
69
  cannot [:update, :destroy], Role, name: ['admin']
70
70
  end
71
+
72
+ private
73
+
74
+ # you can override this method to register your abilities
75
+ # this method has to return array of classes
76
+ def abilities_to_register
77
+ []
78
+ end
71
79
  end
72
80
  end
@@ -38,12 +38,18 @@ module Spree
38
38
  attr_accessor :track_data
39
39
 
40
40
  CARD_TYPES = {
41
- visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
42
- master: /(^5[1-5][0-9]{14}$)|(^6759[0-9]{2}([0-9]{10})$)|(^6759[0-9]{2}([0-9]{12})$)|(^6759[0-9]{2}([0-9]{13})$)/,
43
- diners_club: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
44
- american_express: /^3[47][0-9]{13}$/,
45
- discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
46
- jcb: /^(?:2131|1800|35\d{3})\d{11}$/
41
+ visa: /^4\d{12}(\d{3})?(\d{3})?$/,
42
+ master: /^(5[1-5]\d{4}|677189|222[1-9]\d{2}|22[3-9]\d{3}|2[3-6]\d{4}|27[01]\d{3}|2720\d{2})\d{10}$/,
43
+ discover: /^(6011|65\d{2}|64[4-9]\d)\d{12}|(62\d{14})$/,
44
+ american_express: /^3[47]\d{13}$/,
45
+ diners_club: /^3(0[0-5]|[68]\d)\d{11}$/,
46
+ jcb: /^35(28|29|[3-8]\d)\d{12}$/,
47
+ switch: /^6759\d{12}(\d{2,3})?$/,
48
+ solo: /^6767\d{12}(\d{2,3})?$/,
49
+ dankort: /^5019\d{12}$/,
50
+ maestro: /^(5[06-8]|6\d)\d{10,17}$/,
51
+ forbrugsforeningen: /^600722\d{10}$/,
52
+ laser: /^(6304|6706|6709|6771(?!89))\d{8}(\d{4}|\d{6,7})?$/
47
53
  }
48
54
 
49
55
  def expiry=(expiry)
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  class Gateway::Bogus < Gateway
3
3
  TEST_VISA = ['4111111111111111','4012888888881881','4222222222222']
4
- TEST_MC = ['5500000000000004','5555555555554444','5105105105105100']
4
+ TEST_MC = ['5500000000000004','5555555555554444','5105105105105100','2223000010309703']
5
5
  TEST_AMEX = ['378282246310005','371449635398431','378734493671000','340000000000009']
6
6
  TEST_DISC = ['6011000000000004','6011111111111117','6011000990139424']
7
7
 
@@ -39,7 +39,9 @@ module Spree
39
39
  self.whitelisted_ransackable_attributes = ['path', 'promotion_category_id', 'code']
40
40
 
41
41
  def self.with_coupon_code(coupon_code)
42
- where("lower(#{table_name}.code) = ?", coupon_code.strip.downcase).first
42
+ where("lower(#{table_name}.code) = ?", coupon_code.strip.downcase)
43
+ .includes(:promotion_actions).where.not(spree_promotion_actions: { id: nil })
44
+ .first
43
45
  end
44
46
 
45
47
  def self.active
@@ -0,0 +1,67 @@
1
+ class AddMissingIndexesOnSpreeTables < ActiveRecord::Migration
2
+ def change
3
+ if table_exists?(:spree_promotion_rules_users) && !index_exists?(:spree_promotion_rules_users,
4
+ [:user_id, :promotion_rule_id],
5
+ name: 'index_promotion_rules_users_on_user_id_and_promotion_rule_id')
6
+ add_index :spree_promotion_rules_users,
7
+ [:user_id, :promotion_rule_id],
8
+ name: 'index_promotion_rules_users_on_user_id_and_promotion_rule_id'
9
+ end
10
+
11
+ if table_exists?(:spree_products_promotion_rules) && !index_exists?(:spree_products_promotion_rules,
12
+ [:promotion_rule_id, :product_id],
13
+ name: 'index_products_promotion_rules_on_promotion_rule_and_product')
14
+ add_index :spree_products_promotion_rules,
15
+ [:promotion_rule_id, :product_id],
16
+ name: 'index_products_promotion_rules_on_promotion_rule_and_product'
17
+ end
18
+
19
+ unless index_exists? :spree_orders, :canceler_id
20
+ add_index :spree_orders, :canceler_id
21
+ end
22
+
23
+ unless index_exists? :spree_orders, :store_id
24
+ add_index :spree_orders, :store_id
25
+ end
26
+
27
+ if table_exists?(:spree_orders_promotions) && !index_exists?(:spree_orders_promotions, [:promotion_id, :order_id])
28
+ add_index :spree_orders_promotions, [:promotion_id, :order_id]
29
+ end
30
+
31
+ if table_exists?(:spree_properties_prototypes) && !index_exists?(:spree_properties_prototypes, :prototype_id)
32
+ add_index :spree_properties_prototypes, :prototype_id
33
+ end
34
+
35
+ if table_exists?(:spree_properties_prototypes) && !index_exists?(:spree_properties_prototypes,
36
+ [:prototype_id, :property_id],
37
+ name: 'index_properties_prototypes_on_prototype_and_property')
38
+ add_index :spree_properties_prototypes,
39
+ [:prototype_id, :property_id],
40
+ name: 'index_properties_prototypes_on_prototype_and_property'
41
+ end
42
+
43
+ if table_exists?(:spree_taxons_prototypes) && !index_exists?(:spree_taxons_prototypes, [:prototype_id, :taxon_id])
44
+ add_index :spree_taxons_prototypes, [:prototype_id, :taxon_id]
45
+ end
46
+
47
+ if table_exists?(:spree_option_types_prototypes) && !index_exists?(:spree_option_types_prototypes, :prototype_id)
48
+ add_index :spree_option_types_prototypes, :prototype_id
49
+ end
50
+
51
+ if table_exists?(:spree_option_types_prototypes) && !index_exists?(:spree_option_types_prototypes,
52
+ [:prototype_id, :option_type_id],
53
+ name: 'index_option_types_prototypes_on_prototype_and_option_type')
54
+ add_index :spree_option_types_prototypes,
55
+ [:prototype_id, :option_type_id],
56
+ name: 'index_option_types_prototypes_on_prototype_and_option_type'
57
+ end
58
+
59
+ if table_exists?(:spree_option_values_variants) && !index_exists?(:spree_option_values_variants,
60
+ [:option_value_id, :variant_id],
61
+ name: 'index_option_values_variants_on_option_value_and_variant')
62
+ add_index :spree_option_values_variants,
63
+ [:option_value_id, :variant_id],
64
+ name: 'index_option_values_variants_on_option_value_and_variant'
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
2
  def self.version
3
- "3.1.1"
3
+ "3.1.2"
4
4
  end
5
5
  end
@@ -38,6 +38,18 @@ describe Spree::Ability, :type => :model do
38
38
  end
39
39
  end
40
40
 
41
+ context '#abilities_to_register' do
42
+ it 'adds the ability to the list of abilities' do
43
+ allow_any_instance_of(Spree::Ability).to receive(:abilities_to_register) { [FooAbility] }
44
+ expect(Spree::Ability.new(user).abilities).to include FooAbility
45
+ end
46
+
47
+ it 'applies the registered abilities permissions' do
48
+ allow_any_instance_of(Spree::Ability).to receive(:abilities_to_register) { [FooAbility] }
49
+ expect(Spree::Ability.new(user).can?(:update, mock_model(Spree::Order, id: 1))).to be true
50
+ end
51
+ end
52
+
41
53
  context 'for general resource' do
42
54
  let(:resource) { Object.new }
43
55
 
@@ -222,6 +222,10 @@ describe Spree::CreditCard, type: :model do
222
222
  credit_card.cc_type = ''
223
223
  expect(credit_card.cc_type).to eq('master')
224
224
 
225
+ credit_card.number = '2223000010309703'
226
+ credit_card.cc_type = ''
227
+ expect(credit_card.cc_type).to eq('master')
228
+
225
229
  credit_card.number = '378282246310005'
226
230
  credit_card.cc_type = ''
227
231
  expect(credit_card.cc_type).to eq('american_express')
@@ -539,11 +539,31 @@ describe Spree::Promotion, :type => :model do
539
539
  # Regression test for #4081
540
540
  describe "#with_coupon_code" do
541
541
  context "and code stored in uppercase" do
542
- let!(:promotion) { create(:promotion, :code => "MY-COUPON-123") }
542
+ let!(:promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
543
543
  it "finds the code with lowercase" do
544
544
  expect(Spree::Promotion.with_coupon_code("my-coupon-123")).to eql promotion
545
545
  end
546
546
  end
547
+
548
+ context "and there are multiple coupons with the same code" do
549
+ context "and only one has any actions" do
550
+ let!(:promotion_without_actions) { create(:promotion, code: "MY-COUPON-123").actions.clear }
551
+ let!(:promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
552
+
553
+ it "then returns the one with an action" do
554
+ expect(Spree::Promotion.with_coupon_code("MY-COUPON-123").actions.exists?).to be
555
+ end
556
+ end
557
+
558
+ context "and all of them has actions" do
559
+ let!(:first_promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
560
+ let!(:second_promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
561
+
562
+ it "then returns the first one with an action" do
563
+ expect(Spree::Promotion.with_coupon_code("MY-COUPON-123").id).to eq(first_promotion.id)
564
+ end
565
+ end
566
+ end
547
567
  end
548
568
 
549
569
  describe '#used_by?' do
@@ -62,7 +62,9 @@ describe Spree::Zone, :type => :model do
62
62
 
63
63
  context "when both zones have the same number of members" do
64
64
  it "should return the zone that was created first" do
65
- expect(Spree::Zone.match(address)).to eq(country_zone)
65
+ Timecop.scale(100) do
66
+ expect(Spree::Zone.match(address)).to eq(country_zone)
67
+ end
66
68
  end
67
69
  end
68
70
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.require_path = 'lib'
21
21
 
22
- s.add_dependency 'activemerchant', '~> 1.49.0'
22
+ s.add_dependency 'activemerchant', '~> 1.59'
23
23
  s.add_dependency 'acts_as_list', '0.7.2'
24
24
  s.add_dependency 'awesome_nested_set', '~> 3.0.1'
25
25
  s.add_dependency 'carmen', '~> 1.0.0'
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_dependency 'paperclip', '~> 4.3.0'
35
35
  s.add_dependency 'paranoia', '~> 2.1.0'
36
36
  s.add_dependency 'premailer-rails'
37
- s.add_dependency 'rails', '~> 4.2.7.1'
37
+ s.add_dependency 'rails', '~> 4.2.5'
38
38
  s.add_dependency 'ransack', '~> 1.4.1'
39
39
  s.add_dependency 'responders'
40
40
  s.add_dependency 'state_machines-activerecord', '~> 0.2'
@@ -1,11 +1,10 @@
1
- // Generated by CoffeeScript 1.4.0
1
+ // Generated by CoffeeScript 1.7.1
2
2
  (function() {
3
- var $, cardFromNumber, cardFromType, cards, defaultFormat, formatBackCardNumber, formatBackExpiry, formatCardNumber, formatExpiry, formatForwardExpiry, formatForwardSlash, hasTextSelected, luhnCheck, reFormatCardNumber, restrictCVC, restrictCardNumber, restrictExpiry, restrictNumeric, setCardType,
3
+ var $, cardFromNumber, cardFromType, cards, defaultFormat, formatBackCardNumber, formatBackExpiry, formatCardNumber, formatExpiry, formatForwardExpiry, formatForwardSlashAndSpace, hasTextSelected, luhnCheck, reFormatCVC, reFormatCardNumber, reFormatExpiry, reFormatNumeric, replaceFullWidthChars, restrictCVC, restrictCardNumber, restrictExpiry, restrictNumeric, safeVal, setCardType,
4
4
  __slice = [].slice,
5
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
6
- _this = this;
5
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
7
6
 
8
- $ = jQuery;
7
+ $ = window.jQuery || window.Zepto || window.$;
9
8
 
10
9
  $.payment = {};
11
10
 
@@ -19,80 +18,92 @@
19
18
 
20
19
  defaultFormat = /(\d{1,4})/g;
21
20
 
22
- cards = [
21
+ $.payment.cards = cards = [
23
22
  {
24
23
  type: 'maestro',
25
- pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
24
+ patterns: [5018, 502, 503, 506, 56, 58, 639, 6220, 67],
26
25
  format: defaultFormat,
27
26
  length: [12, 13, 14, 15, 16, 17, 18, 19],
28
27
  cvcLength: [3],
29
28
  luhn: true
30
29
  }, {
31
- type: 'dinersclub',
32
- pattern: /^(36|38|30[0-5])/,
30
+ type: 'forbrugsforeningen',
31
+ patterns: [600],
33
32
  format: defaultFormat,
34
- length: [14],
35
- cvcLength: [3],
36
- luhn: true
37
- }, {
38
- type: 'laser',
39
- pattern: /^(6706|6771|6709)/,
40
- format: defaultFormat,
41
- length: [16, 17, 18, 19],
33
+ length: [16],
42
34
  cvcLength: [3],
43
35
  luhn: true
44
36
  }, {
45
- type: 'jcb',
46
- pattern: /^35/,
37
+ type: 'dankort',
38
+ patterns: [5019],
47
39
  format: defaultFormat,
48
40
  length: [16],
49
41
  cvcLength: [3],
50
42
  luhn: true
51
43
  }, {
52
- type: 'unionpay',
53
- pattern: /^62/,
54
- format: defaultFormat,
55
- length: [16, 17, 18, 19],
56
- cvcLength: [3],
57
- luhn: false
58
- }, {
59
- type: 'discover',
60
- pattern: /^(6011|65|64[4-9]|622)/,
44
+ type: 'visa',
45
+ patterns: [4],
61
46
  format: defaultFormat,
62
- length: [16],
47
+ length: [13, 16],
63
48
  cvcLength: [3],
64
49
  luhn: true
65
50
  }, {
66
51
  type: 'mastercard',
67
- pattern: /^5[1-5]/,
52
+ patterns: [51, 52, 53, 54, 55, 22, 23, 24, 25, 26, 27],
68
53
  format: defaultFormat,
69
54
  length: [16],
70
55
  cvcLength: [3],
71
56
  luhn: true
72
57
  }, {
73
58
  type: 'amex',
74
- pattern: /^3[47]/,
59
+ patterns: [34, 37],
75
60
  format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
76
61
  length: [15],
77
62
  cvcLength: [3, 4],
78
63
  luhn: true
79
64
  }, {
80
- type: 'visa',
81
- pattern: /^4/,
65
+ type: 'dinersclub',
66
+ patterns: [30, 36, 38, 39],
67
+ format: /(\d{1,4})(\d{1,6})?(\d{1,4})?/,
68
+ length: [14],
69
+ cvcLength: [3],
70
+ luhn: true
71
+ }, {
72
+ type: 'discover',
73
+ patterns: [60, 64, 65, 622],
82
74
  format: defaultFormat,
83
- length: [13, 14, 15, 16],
75
+ length: [16],
76
+ cvcLength: [3],
77
+ luhn: true
78
+ }, {
79
+ type: 'unionpay',
80
+ patterns: [62, 88],
81
+ format: defaultFormat,
82
+ length: [16, 17, 18, 19],
83
+ cvcLength: [3],
84
+ luhn: false
85
+ }, {
86
+ type: 'jcb',
87
+ patterns: [35],
88
+ format: defaultFormat,
89
+ length: [16],
84
90
  cvcLength: [3],
85
91
  luhn: true
86
92
  }
87
93
  ];
88
94
 
89
95
  cardFromNumber = function(num) {
90
- var card, _i, _len;
96
+ var card, p, pattern, _i, _j, _len, _len1, _ref;
91
97
  num = (num + '').replace(/\D/g, '');
92
98
  for (_i = 0, _len = cards.length; _i < _len; _i++) {
93
99
  card = cards[_i];
94
- if (card.pattern.test(num)) {
95
- return card;
100
+ _ref = card.patterns;
101
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
102
+ pattern = _ref[_j];
103
+ p = pattern + '';
104
+ if (num.substr(0, p.length) === p) {
105
+ return card;
106
+ }
96
107
  }
97
108
  }
98
109
  };
@@ -131,20 +142,82 @@
131
142
  if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) {
132
143
  return true;
133
144
  }
134
- if (typeof document !== "undefined" && document !== null ? (_ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text : void 0 : void 0 : void 0) {
135
- return true;
145
+ if ((typeof document !== "undefined" && document !== null ? (_ref = document.selection) != null ? _ref.createRange : void 0 : void 0) != null) {
146
+ if (document.selection.createRange().text) {
147
+ return true;
148
+ }
136
149
  }
137
150
  return false;
138
151
  };
139
152
 
153
+ safeVal = function(value, $target) {
154
+ var currPair, cursor, digit, error, last, prevPair;
155
+ try {
156
+ cursor = $target.prop('selectionStart');
157
+ } catch (_error) {
158
+ error = _error;
159
+ cursor = null;
160
+ }
161
+ last = $target.val();
162
+ $target.val(value);
163
+ if (cursor !== null && $target.is(":focus")) {
164
+ if (cursor === last.length) {
165
+ cursor = value.length;
166
+ }
167
+ if (last !== value) {
168
+ prevPair = last.slice(cursor - 1, +cursor + 1 || 9e9);
169
+ currPair = value.slice(cursor - 1, +cursor + 1 || 9e9);
170
+ digit = value[cursor];
171
+ if (/\d/.test(digit) && prevPair === ("" + digit + " ") && currPair === (" " + digit)) {
172
+ cursor = cursor + 1;
173
+ }
174
+ }
175
+ $target.prop('selectionStart', cursor);
176
+ return $target.prop('selectionEnd', cursor);
177
+ }
178
+ };
179
+
180
+ replaceFullWidthChars = function(str) {
181
+ var chars, chr, fullWidth, halfWidth, idx, value, _i, _len;
182
+ if (str == null) {
183
+ str = '';
184
+ }
185
+ fullWidth = '\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19';
186
+ halfWidth = '0123456789';
187
+ value = '';
188
+ chars = str.split('');
189
+ for (_i = 0, _len = chars.length; _i < _len; _i++) {
190
+ chr = chars[_i];
191
+ idx = fullWidth.indexOf(chr);
192
+ if (idx > -1) {
193
+ chr = halfWidth[idx];
194
+ }
195
+ value += chr;
196
+ }
197
+ return value;
198
+ };
199
+
200
+ reFormatNumeric = function(e) {
201
+ var $target;
202
+ $target = $(e.currentTarget);
203
+ return setTimeout(function() {
204
+ var value;
205
+ value = $target.val();
206
+ value = replaceFullWidthChars(value);
207
+ value = value.replace(/\D/g, '');
208
+ return safeVal(value, $target);
209
+ });
210
+ };
211
+
140
212
  reFormatCardNumber = function(e) {
141
- var _this = this;
213
+ var $target;
214
+ $target = $(e.currentTarget);
142
215
  return setTimeout(function() {
143
- var $target, value;
144
- $target = $(e.currentTarget);
216
+ var value;
145
217
  value = $target.val();
218
+ value = replaceFullWidthChars(value);
146
219
  value = $.payment.formatCardNumber(value);
147
- return $target.val(value);
220
+ return safeVal(value, $target);
148
221
  });
149
222
  };
150
223
 
@@ -175,10 +248,14 @@
175
248
  }
176
249
  if (re.test(value)) {
177
250
  e.preventDefault();
178
- return $target.val(value + ' ' + digit);
251
+ return setTimeout(function() {
252
+ return $target.val(value + ' ' + digit);
253
+ });
179
254
  } else if (re.test(value + digit)) {
180
255
  e.preventDefault();
181
- return $target.val(value + digit + ' ');
256
+ return setTimeout(function() {
257
+ return $target.val(value + digit + ' ');
258
+ });
182
259
  }
183
260
  };
184
261
 
@@ -186,9 +263,6 @@
186
263
  var $target, value;
187
264
  $target = $(e.currentTarget);
188
265
  value = $target.val();
189
- if (e.meta) {
190
- return;
191
- }
192
266
  if (e.which !== 8) {
193
267
  return;
194
268
  }
@@ -197,13 +271,29 @@
197
271
  }
198
272
  if (/\d\s$/.test(value)) {
199
273
  e.preventDefault();
200
- return $target.val(value.replace(/\d\s$/, ''));
274
+ return setTimeout(function() {
275
+ return $target.val(value.replace(/\d\s$/, ''));
276
+ });
201
277
  } else if (/\s\d?$/.test(value)) {
202
278
  e.preventDefault();
203
- return $target.val(value.replace(/\s\d?$/, ''));
279
+ return setTimeout(function() {
280
+ return $target.val(value.replace(/\d$/, ''));
281
+ });
204
282
  }
205
283
  };
206
284
 
285
+ reFormatExpiry = function(e) {
286
+ var $target;
287
+ $target = $(e.currentTarget);
288
+ return setTimeout(function() {
289
+ var value;
290
+ value = $target.val();
291
+ value = replaceFullWidthChars(value);
292
+ value = $.payment.formatExpiry(value);
293
+ return safeVal(value, $target);
294
+ });
295
+ };
296
+
207
297
  formatExpiry = function(e) {
208
298
  var $target, digit, val;
209
299
  digit = String.fromCharCode(e.which);
@@ -214,10 +304,21 @@
214
304
  val = $target.val() + digit;
215
305
  if (/^\d$/.test(val) && (val !== '0' && val !== '1')) {
216
306
  e.preventDefault();
217
- return $target.val("0" + val + " / ");
307
+ return setTimeout(function() {
308
+ return $target.val("0" + val + " / ");
309
+ });
218
310
  } else if (/^\d\d$/.test(val)) {
219
311
  e.preventDefault();
220
- return $target.val("" + val + " / ");
312
+ return setTimeout(function() {
313
+ var m1, m2;
314
+ m1 = parseInt(val[0], 10);
315
+ m2 = parseInt(val[1], 10);
316
+ if (m2 > 2 && m1 !== 0) {
317
+ return $target.val("0" + m1 + " / " + m2);
318
+ } else {
319
+ return $target.val("" + val + " / ");
320
+ }
321
+ });
221
322
  }
222
323
  };
223
324
 
@@ -234,10 +335,10 @@
234
335
  }
235
336
  };
236
337
 
237
- formatForwardSlash = function(e) {
238
- var $target, slash, val;
239
- slash = String.fromCharCode(e.which);
240
- if (slash !== '/') {
338
+ formatForwardSlashAndSpace = function(e) {
339
+ var $target, val, which;
340
+ which = String.fromCharCode(e.which);
341
+ if (!(which === '/' || which === ' ')) {
241
342
  return;
242
343
  }
243
344
  $target = $(e.currentTarget);
@@ -249,9 +350,6 @@
249
350
 
250
351
  formatBackExpiry = function(e) {
251
352
  var $target, value;
252
- if (e.meta) {
253
- return;
254
- }
255
353
  $target = $(e.currentTarget);
256
354
  value = $target.val();
257
355
  if (e.which !== 8) {
@@ -260,15 +358,26 @@
260
358
  if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
261
359
  return;
262
360
  }
263
- if (/\d(\s|\/)+$/.test(value)) {
361
+ if (/\d\s\/\s$/.test(value)) {
264
362
  e.preventDefault();
265
- return $target.val(value.replace(/\d(\s|\/)*$/, ''));
266
- } else if (/\s\/\s?\d?$/.test(value)) {
267
- e.preventDefault();
268
- return $target.val(value.replace(/\s\/\s?\d?$/, ''));
363
+ return setTimeout(function() {
364
+ return $target.val(value.replace(/\d\s\/\s$/, ''));
365
+ });
269
366
  }
270
367
  };
271
368
 
369
+ reFormatCVC = function(e) {
370
+ var $target;
371
+ $target = $(e.currentTarget);
372
+ return setTimeout(function() {
373
+ var value;
374
+ value = $target.val();
375
+ value = replaceFullWidthChars(value);
376
+ value = value.replace(/\D/g, '').slice(0, 4);
377
+ return safeVal(value, $target);
378
+ });
379
+ };
380
+
272
381
  restrictNumeric = function(e) {
273
382
  var input;
274
383
  if (e.metaKey || e.ctrlKey) {
@@ -330,6 +439,9 @@
330
439
  if (!/^\d+$/.test(digit)) {
331
440
  return;
332
441
  }
442
+ if (hasTextSelected($target)) {
443
+ return;
444
+ }
333
445
  val = $target.val() + digit;
334
446
  return val.length <= 4;
335
447
  };
@@ -358,33 +470,44 @@
358
470
  };
359
471
 
360
472
  $.payment.fn.formatCardCVC = function() {
361
- this.payment('restrictNumeric');
473
+ this.on('keypress', restrictNumeric);
362
474
  this.on('keypress', restrictCVC);
475
+ this.on('paste', reFormatCVC);
476
+ this.on('change', reFormatCVC);
477
+ this.on('input', reFormatCVC);
363
478
  return this;
364
479
  };
365
480
 
366
481
  $.payment.fn.formatCardExpiry = function() {
367
- this.payment('restrictNumeric');
482
+ this.on('keypress', restrictNumeric);
368
483
  this.on('keypress', restrictExpiry);
369
484
  this.on('keypress', formatExpiry);
370
- this.on('keypress', formatForwardSlash);
485
+ this.on('keypress', formatForwardSlashAndSpace);
371
486
  this.on('keypress', formatForwardExpiry);
372
487
  this.on('keydown', formatBackExpiry);
488
+ this.on('change', reFormatExpiry);
489
+ this.on('input', reFormatExpiry);
373
490
  return this;
374
491
  };
375
492
 
376
493
  $.payment.fn.formatCardNumber = function() {
377
- this.payment('restrictNumeric');
494
+ this.on('keypress', restrictNumeric);
378
495
  this.on('keypress', restrictCardNumber);
379
496
  this.on('keypress', formatCardNumber);
380
497
  this.on('keydown', formatBackCardNumber);
381
498
  this.on('keyup', setCardType);
382
499
  this.on('paste', reFormatCardNumber);
500
+ this.on('change', reFormatCardNumber);
501
+ this.on('input', reFormatCardNumber);
502
+ this.on('input', setCardType);
383
503
  return this;
384
504
  };
385
505
 
386
506
  $.payment.fn.restrictNumeric = function() {
387
507
  this.on('keypress', restrictNumeric);
508
+ this.on('paste', reFormatNumeric);
509
+ this.on('change', reFormatNumeric);
510
+ this.on('input', reFormatNumeric);
388
511
  return this;
389
512
  };
390
513
 
@@ -394,8 +517,7 @@
394
517
 
395
518
  $.payment.cardExpiryVal = function(value) {
396
519
  var month, prefix, year, _ref;
397
- value = value.replace(/\s/g, '');
398
- _ref = value.split('/', 2), month = _ref[0], year = _ref[1];
520
+ _ref = value.split(/[\s\/]+/, 2), month = _ref[0], year = _ref[1];
399
521
  if ((year != null ? year.length : void 0) === 2 && /^\d+$/.test(year)) {
400
522
  prefix = (new Date).getFullYear();
401
523
  prefix = prefix.toString().slice(0, 2);
@@ -423,7 +545,7 @@
423
545
  };
424
546
 
425
547
  $.payment.validateCardExpiry = function(month, year) {
426
- var currentTime, expiry, prefix, _ref;
548
+ var currentTime, expiry, _ref;
427
549
  if (typeof month === 'object' && 'month' in month) {
428
550
  _ref = month, month = _ref.month, year = _ref.year;
429
551
  }
@@ -438,13 +560,18 @@
438
560
  if (!/^\d+$/.test(year)) {
439
561
  return false;
440
562
  }
441
- if (!(parseInt(month, 10) <= 12)) {
563
+ if (!((1 <= month && month <= 12))) {
442
564
  return false;
443
565
  }
444
566
  if (year.length === 2) {
445
- prefix = (new Date).getFullYear();
446
- prefix = prefix.toString().slice(0, 2);
447
- year = prefix + year;
567
+ if (year < 70) {
568
+ year = "20" + year;
569
+ } else {
570
+ year = "19" + year;
571
+ }
572
+ }
573
+ if (year.length !== 4) {
574
+ return false;
448
575
  }
449
576
  expiry = new Date(year, month);
450
577
  currentTime = new Date;
@@ -454,13 +581,14 @@
454
581
  };
455
582
 
456
583
  $.payment.validateCardCVC = function(cvc, type) {
457
- var _ref, _ref1;
584
+ var card, _ref;
458
585
  cvc = $.trim(cvc);
459
586
  if (!/^\d+$/.test(cvc)) {
460
587
  return false;
461
588
  }
462
- if (type) {
463
- return _ref = cvc.length, __indexOf.call((_ref1 = cardFromType(type)) != null ? _ref1.cvcLength : void 0, _ref) >= 0;
589
+ card = cardFromType(type);
590
+ if (card != null) {
591
+ return _ref = cvc.length, __indexOf.call(card.cvcLength, _ref) >= 0;
464
592
  } else {
465
593
  return cvc.length >= 3 && cvc.length <= 4;
466
594
  }
@@ -476,22 +604,49 @@
476
604
 
477
605
  $.payment.formatCardNumber = function(num) {
478
606
  var card, groups, upperLength, _ref;
607
+ num = num.replace(/\D/g, '');
479
608
  card = cardFromNumber(num);
480
609
  if (!card) {
481
610
  return num;
482
611
  }
483
612
  upperLength = card.length[card.length.length - 1];
484
- num = num.replace(/\D/g, '');
485
- num = num.slice(0, +upperLength + 1 || 9e9);
613
+ num = num.slice(0, upperLength);
486
614
  if (card.format.global) {
487
615
  return (_ref = num.match(card.format)) != null ? _ref.join(' ') : void 0;
488
616
  } else {
489
617
  groups = card.format.exec(num);
490
- if (groups != null) {
491
- groups.shift();
618
+ if (groups == null) {
619
+ return;
492
620
  }
493
- return groups != null ? groups.join(' ') : void 0;
621
+ groups.shift();
622
+ groups = $.grep(groups, function(n) {
623
+ return n;
624
+ });
625
+ return groups.join(' ');
494
626
  }
495
627
  };
496
628
 
497
- }).call(this);
629
+ $.payment.formatExpiry = function(expiry) {
630
+ var mon, parts, sep, year;
631
+ parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
632
+ if (!parts) {
633
+ return '';
634
+ }
635
+ mon = parts[1] || '';
636
+ sep = parts[2] || '';
637
+ year = parts[3] || '';
638
+ if (year.length > 0) {
639
+ sep = ' / ';
640
+ } else if (sep === ' /') {
641
+ mon = mon.substring(0, 1);
642
+ sep = '';
643
+ } else if (mon.length === 2 || sep.length > 0) {
644
+ sep = ' / ';
645
+ } else if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
646
+ mon = "0" + mon;
647
+ sep = ' / ';
648
+ }
649
+ return mon + sep + year;
650
+ };
651
+
652
+ }).call(this);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-16 00:00:00.000000000 Z
11
+ date: 2016-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemerchant
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.49.0
19
+ version: '1.59'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.49.0
26
+ version: '1.59'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: acts_as_list
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -226,14 +226,14 @@ dependencies:
226
226
  requirements:
227
227
  - - "~>"
228
228
  - !ruby/object:Gem::Version
229
- version: 4.2.7.1
229
+ version: 4.2.5
230
230
  type: :runtime
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
- version: 4.2.7.1
236
+ version: 4.2.5
237
237
  - !ruby/object:Gem::Dependency
238
238
  name: ransack
239
239
  requirement: !ruby/object:Gem::Requirement
@@ -793,7 +793,7 @@ files:
793
793
  - db/migrate/20150128060325_remove_spree_configurations.rb
794
794
  - db/migrate/20150216173445_add_index_to_spree_stock_items_variant_id.rb
795
795
  - db/migrate/20150309161154_ensure_payments_have_numbers.rb
796
- - db/migrate/20150314013438_add_missing_indexes.rb
796
+ - db/migrate/20150314013438_add_missing_indexes_on_spree_tables.rb
797
797
  - db/migrate/20150317174308_remove_duplicated_indexes_from_multi_columns.rb
798
798
  - db/migrate/20150324104002_remove_user_index_from_spree_state_changes.rb
799
799
  - db/migrate/20150515211137_fix_adjustment_order_id.rb
@@ -1,25 +0,0 @@
1
- class AddMissingIndexes < ActiveRecord::Migration
2
- def change
3
- add_index :spree_promotion_rules_users,
4
- [:user_id, :promotion_rule_id],
5
- name: 'index_promotion_rules_users_on_user_id_and_promotion_rule_id'
6
- add_index :spree_products_promotion_rules,
7
- [:promotion_rule_id, :product_id],
8
- name: 'index_products_promotion_rules_on_promotion_rule_and_product'
9
- add_index :spree_orders, :canceler_id
10
- add_index :spree_orders, :store_id
11
- add_index :spree_orders_promotions, [:promotion_id, :order_id]
12
- add_index :spree_properties_prototypes, :prototype_id
13
- add_index :spree_properties_prototypes,
14
- [:prototype_id, :property_id],
15
- name: 'index_properties_prototypes_on_prototype_and_property'
16
- add_index :spree_taxons_prototypes, [:prototype_id, :taxon_id]
17
- add_index :spree_option_types_prototypes, :prototype_id
18
- add_index :spree_option_types_prototypes,
19
- [:prototype_id, :option_type_id],
20
- name: 'index_option_types_prototypes_on_prototype_and_option_type'
21
- add_index :spree_option_values_variants,
22
- [:option_value_id, :variant_id],
23
- name: 'index_option_values_variants_on_option_value_and_variant'
24
- end
25
- end