symmetric-encryption 3.7.2 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +65 -83
- data/Rakefile +4 -4
- data/lib/rails/generators/symmetric_encryption/config/config_generator.rb +3 -3
- data/lib/rails/generators/symmetric_encryption/heroku_config/heroku_config_generator.rb +3 -3
- data/lib/rails/generators/symmetric_encryption/new_keys/new_keys_generator.rb +2 -2
- data/lib/symmetric_encryption.rb +7 -1
- data/lib/symmetric_encryption/cipher.rb +180 -50
- data/lib/symmetric_encryption/coerce.rb +75 -0
- data/lib/symmetric_encryption/config.rb +88 -0
- data/lib/symmetric_encryption/extensions/active_record/base.rb +2 -2
- data/lib/symmetric_encryption/extensions/mongoid/encrypted.rb +2 -2
- data/lib/symmetric_encryption/generator.rb +5 -1
- data/lib/symmetric_encryption/railtie.rb +3 -3
- data/lib/symmetric_encryption/railties/symmetric_encryption.rake +6 -6
- data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -1
- data/lib/symmetric_encryption/reader.rb +16 -14
- data/lib/symmetric_encryption/symmetric_encryption.rb +30 -285
- data/lib/symmetric_encryption/version.rb +1 -1
- data/lib/symmetric_encryption/writer.rb +13 -13
- data/test/active_record_test.rb +126 -73
- data/test/cipher_test.rb +42 -42
- data/test/mongo_mapper_test.rb +171 -114
- data/test/mongoid_test.rb +173 -115
- data/test/reader_test.rb +63 -63
- data/test/symmetric_encryption_test.rb +81 -80
- data/test/test_db.sqlite3 +0 -0
- data/test/test_helper.rb +1 -2
- data/test/writer_test.rb +20 -20
- metadata +13 -13
- data/lib/_test_empty +0 -0
data/test/cipher_test.rb
CHANGED
@@ -3,9 +3,9 @@ require_relative 'test_helper'
|
|
3
3
|
# Unit Test for SymmetricEncryption::Cipher
|
4
4
|
#
|
5
5
|
class CipherTest < Minitest::Test
|
6
|
-
|
6
|
+
describe 'standalone' do
|
7
7
|
|
8
|
-
|
8
|
+
it "allow setting the cipher_name" do
|
9
9
|
cipher = SymmetricEncryption::Cipher.new(
|
10
10
|
cipher_name: 'aes-128-cbc',
|
11
11
|
key: '1234567890ABCDEF1234567890ABCDEF',
|
@@ -15,7 +15,7 @@ class CipherTest < Minitest::Test
|
|
15
15
|
assert_equal 'aes-128-cbc', cipher.cipher_name
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
it "not require an iv" do
|
19
19
|
cipher = SymmetricEncryption::Cipher.new(
|
20
20
|
key: '1234567890ABCDEF1234567890ABCDEF',
|
21
21
|
encoding: :none
|
@@ -29,7 +29,7 @@ class CipherTest < Minitest::Test
|
|
29
29
|
assert_equal result, cipher.encrypt('Hello World')
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
it "throw an exception on bad data" do
|
33
33
|
cipher = SymmetricEncryption::Cipher.new(
|
34
34
|
cipher_name: 'aes-128-cbc',
|
35
35
|
key: '1234567890ABCDEF1234567890ABCDEF',
|
@@ -45,26 +45,26 @@ class CipherTest < Minitest::Test
|
|
45
45
|
|
46
46
|
[false, true].each do |always_add_header|
|
47
47
|
SymmetricEncryption::Cipher::ENCODINGS.each do |encoding|
|
48
|
-
|
49
|
-
|
50
|
-
@social_security_number
|
51
|
-
@social_security_number_encrypted
|
48
|
+
describe "encoding: #{encoding} with#{'out' unless always_add_header} header" do
|
49
|
+
before do
|
50
|
+
@social_security_number = "987654321"
|
51
|
+
@social_security_number_encrypted =
|
52
52
|
case encoding
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
53
|
+
when :base64
|
54
|
+
always_add_header ? "QEVuQwAAyTeLjsHTa8ykoO95K0KQmg==\n" : "yTeLjsHTa8ykoO95K0KQmg==\n"
|
55
|
+
when :base64strict
|
56
|
+
always_add_header ? "QEVuQwAAyTeLjsHTa8ykoO95K0KQmg==" : "yTeLjsHTa8ykoO95K0KQmg=="
|
57
|
+
when :base16
|
58
|
+
always_add_header ? "40456e430000c9378b8ec1d36bcca4a0ef792b42909a" : "c9378b8ec1d36bcca4a0ef792b42909a"
|
59
|
+
when :none
|
60
|
+
bin = always_add_header ? "@EnC\x00\x00\xC97\x8B\x8E\xC1\xD3k\xCC\xA4\xA0\xEFy+B\x90\x9A" : "\xC97\x8B\x8E\xC1\xD3k\xCC\xA4\xA0\xEFy+B\x90\x9A"
|
61
|
+
bin.force_encoding(Encoding.find("binary"))
|
62
|
+
else
|
63
|
+
raise "Add test for encoding: #{encoding}"
|
64
|
+
end
|
65
65
|
@social_security_number_encrypted_with_secondary_1 = "D1UCu38pqJ3jc0GvwJHiow==\n"
|
66
|
-
@non_utf8
|
67
|
-
@cipher
|
66
|
+
@non_utf8 = "\xc2".force_encoding('binary')
|
67
|
+
@cipher = SymmetricEncryption::Cipher.new(
|
68
68
|
key: 'ABCDEF1234567890ABCDEF1234567890',
|
69
69
|
iv: 'ABCDEF1234567890',
|
70
70
|
cipher_name: 'aes-128-cbc',
|
@@ -73,17 +73,17 @@ class CipherTest < Minitest::Test
|
|
73
73
|
)
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
it "encrypt simple string" do
|
77
77
|
assert_equal @social_security_number_encrypted, @cipher.encrypt(@social_security_number)
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
it "decrypt string" do
|
81
81
|
assert decrypted = @cipher.decrypt(@social_security_number_encrypted)
|
82
82
|
assert_equal @social_security_number, decrypted
|
83
83
|
assert_equal Encoding.find('utf-8'), decrypted.encoding, decrypted
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
it 'return BINARY encoding for non-UTF-8 encrypted data' do
|
87
87
|
assert_equal Encoding.find('binary'), @non_utf8.encoding
|
88
88
|
assert_equal true, @non_utf8.valid_encoding?
|
89
89
|
assert encrypted = @cipher.encrypt(@non_utf8)
|
@@ -93,28 +93,28 @@ class CipherTest < Minitest::Test
|
|
93
93
|
assert_equal @non_utf8, decrypted
|
94
94
|
end
|
95
95
|
|
96
|
-
|
96
|
+
it "return nil when encrypting nil" do
|
97
97
|
assert_equal nil, @cipher.encrypt(nil)
|
98
98
|
end
|
99
99
|
|
100
|
-
|
100
|
+
it "return '' when encrypting ''" do
|
101
101
|
assert_equal '', @cipher.encrypt('')
|
102
102
|
end
|
103
103
|
|
104
|
-
|
104
|
+
it "return nil when decrypting nil" do
|
105
105
|
assert_equal nil, @cipher.decrypt(nil)
|
106
106
|
end
|
107
107
|
|
108
|
-
|
108
|
+
it "return '' when decrypting ''" do
|
109
109
|
assert_equal '', @cipher.decrypt('')
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
@cipher
|
115
|
+
describe 'with configuration' do
|
116
|
+
before do
|
117
|
+
@cipher = SymmetricEncryption::Cipher.new(
|
118
118
|
key: '1234567890ABCDEF1234567890ABCDEF',
|
119
119
|
iv: '1234567890ABCDEF',
|
120
120
|
encoding: :none
|
@@ -125,20 +125,20 @@ class CipherTest < Minitest::Test
|
|
125
125
|
@social_security_number_encrypted.force_encoding('binary') if defined?(Encoding)
|
126
126
|
|
127
127
|
@sample_data = [
|
128
|
-
{
|
128
|
+
{text: '555052345', encrypted: ''}
|
129
129
|
]
|
130
130
|
end
|
131
131
|
|
132
|
-
|
132
|
+
it "default to 'aes-256-cbc'" do
|
133
133
|
assert_equal 'aes-256-cbc', @cipher.cipher_name
|
134
134
|
end
|
135
135
|
|
136
|
-
|
137
|
-
|
136
|
+
describe "with header" do
|
137
|
+
before do
|
138
138
|
@social_security_number = "987654321"
|
139
139
|
end
|
140
140
|
|
141
|
-
|
141
|
+
it "build and parse header" do
|
142
142
|
assert random_key_pair = SymmetricEncryption::Cipher.random_key_pair('aes-128-cbc')
|
143
143
|
assert binary_header = SymmetricEncryption::Cipher.build_header(SymmetricEncryption.cipher.version, compressed=true, random_key_pair[:iv], random_key_pair[:key], random_key_pair[:cipher_name])
|
144
144
|
header = SymmetricEncryption::Cipher.parse_header!(binary_header)
|
@@ -154,17 +154,17 @@ class CipherTest < Minitest::Test
|
|
154
154
|
assert_equal random_cipher.encrypt(string, false, false), cipher.encrypt(string, false, false), "Encrypted values differ"
|
155
155
|
end
|
156
156
|
|
157
|
-
|
158
|
-
assert encrypted = @cipher.binary_encrypt(@social_security_number,false,false,false)
|
157
|
+
it "encrypt and then decrypt without a header" do
|
158
|
+
assert encrypted = @cipher.binary_encrypt(@social_security_number, false, false, false)
|
159
159
|
assert_equal @social_security_number, @cipher.decrypt(encrypted)
|
160
160
|
end
|
161
161
|
|
162
|
-
|
162
|
+
it "encrypt and then decrypt using random iv" do
|
163
163
|
assert encrypted = @cipher.encrypt(@social_security_number, random_iv=true)
|
164
164
|
assert_equal @social_security_number, @cipher.decrypt(encrypted)
|
165
165
|
end
|
166
166
|
|
167
|
-
|
167
|
+
it "encrypt and then decrypt using random iv with compression" do
|
168
168
|
assert encrypted = @cipher.encrypt(@social_security_number, random_iv=true, compress=true)
|
169
169
|
assert_equal @social_security_number, @cipher.decrypt(encrypted)
|
170
170
|
end
|
@@ -172,4 +172,4 @@ class CipherTest < Minitest::Test
|
|
172
172
|
end
|
173
173
|
|
174
174
|
end
|
175
|
-
end
|
175
|
+
end
|
data/test/mongo_mapper_test.rb
CHANGED
@@ -5,9 +5,10 @@ begin
|
|
5
5
|
|
6
6
|
# Initialize MongoMapper
|
7
7
|
config_file = File.join('test', 'config', 'mongo_mapper.yml')
|
8
|
-
config
|
8
|
+
config = YAML.load(ERB.new(File.read(config_file)).result)
|
9
9
|
MongoMapper.setup(config, 'test', logger: SemanticLogger['Mongo'])
|
10
10
|
|
11
|
+
#@formatter:off
|
11
12
|
class MongoMapperUser
|
12
13
|
include MongoMapper::Document
|
13
14
|
|
@@ -34,58 +35,74 @@ begin
|
|
34
35
|
validates :encrypted_social_security_number, symmetric_encryption: true
|
35
36
|
end
|
36
37
|
|
38
|
+
class MongoMapperUniqueUser
|
39
|
+
include MongoMapper::Document
|
40
|
+
|
41
|
+
encrypted_key :email, String, symmetric_encryption: true
|
42
|
+
encrypted_key :username, String, symmetric_encryption: true
|
43
|
+
|
44
|
+
validates_uniqueness_of :encrypted_email, allow_blank: true, if: :encrypted_email_changed?
|
45
|
+
validates_uniqueness_of :encrypted_username, allow_blank: true, if: :encrypted_username_changed?
|
46
|
+
|
47
|
+
validates :username,
|
48
|
+
length: {in: 3..20},
|
49
|
+
format: {with: /\A[\w\d\-[[:alnum:]]]+\z/},
|
50
|
+
allow_blank: true
|
51
|
+
end
|
52
|
+
#@formatter:on
|
53
|
+
|
37
54
|
#
|
38
55
|
# Unit Tests for MongoMapper
|
39
56
|
#
|
40
57
|
class MongoMapperTest < Minitest::Test
|
41
|
-
|
42
|
-
|
43
|
-
@bank_account_number
|
58
|
+
describe 'MongoMapperUser' do
|
59
|
+
before do
|
60
|
+
@bank_account_number = "1234567890"
|
44
61
|
@bank_account_number_encrypted = "QEVuQwIAL94ArJeFlJrZp6SYsvoOGA=="
|
45
62
|
|
46
|
-
@social_security_number
|
63
|
+
@social_security_number = "987654321"
|
47
64
|
@social_security_number_encrypted = "QEVuQwIAS+8X1NRrqdfEIQyFHVPuVA=="
|
48
65
|
|
49
|
-
@integer
|
66
|
+
@integer = 32768
|
50
67
|
@integer_encrypted = "FA3smFQEKqB/ITv+A0xACg=="
|
51
68
|
|
52
|
-
@float
|
69
|
+
@float = 0.9867
|
53
70
|
@float_encrypted = "z7Pwt2JDp74d+u0IXFAdrQ=="
|
54
71
|
|
55
|
-
@date
|
72
|
+
@date = Date.parse('20120320')
|
56
73
|
@date_encrypted = "WTkSPHo5ApSSHBJMxxWt2A=="
|
57
74
|
|
58
|
-
@string
|
75
|
+
@string = "A string containing some data to be encrypted with a random initialization vector"
|
59
76
|
@long_string = "A string containing some data to be encrypted with a random initialization vector and compressed since it takes up so much space in plain text form"
|
60
77
|
|
61
|
-
@integer_value
|
62
|
-
@float_value
|
63
|
-
@decimal_value
|
78
|
+
@integer_value = 12
|
79
|
+
@float_value = 88.12345
|
80
|
+
@decimal_value = BigDecimal.new("22.51")
|
64
81
|
@datetime_value = DateTime.new(2001, 11, 26, 20, 55, 54, "-5")
|
65
|
-
@time_value
|
66
|
-
@date_value
|
67
|
-
@h
|
82
|
+
@time_value = Time.new(2013, 01, 01, 22, 30, 00, "-04:00")
|
83
|
+
@date_value = Date.new(1927, 04, 02)
|
84
|
+
@h = {a: 'A', b: 'B'}
|
68
85
|
|
69
86
|
@user = MongoMapperUser.new(
|
70
87
|
encrypted_bank_account_number: @bank_account_number_encrypted,
|
71
88
|
encrypted_social_security_number: @social_security_number_encrypted,
|
72
|
-
name:
|
89
|
+
name: "Joe Bloggs",
|
73
90
|
# data type specific fields
|
74
|
-
integer_value:
|
75
|
-
aliased_integer_value:
|
76
|
-
float_value:
|
77
|
-
decimal_value:
|
78
|
-
datetime_value:
|
79
|
-
time_value:
|
80
|
-
date_value:
|
81
|
-
true_value:
|
82
|
-
false_value:
|
83
|
-
data_yaml:
|
84
|
-
data_json:
|
91
|
+
integer_value: @integer_value,
|
92
|
+
aliased_integer_value: @integer_value,
|
93
|
+
float_value: @float_value,
|
94
|
+
decimal_value: @decimal_value,
|
95
|
+
datetime_value: @datetime_value,
|
96
|
+
time_value: @time_value,
|
97
|
+
date_value: @date_value,
|
98
|
+
true_value: true,
|
99
|
+
false_value: false,
|
100
|
+
data_yaml: @h.dup,
|
101
|
+
data_json: @h.dup
|
85
102
|
)
|
86
103
|
end
|
87
104
|
|
88
|
-
|
105
|
+
it "have encrypted methods" do
|
89
106
|
assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
|
90
107
|
assert_equal true, @user.respond_to?(:encrypted_social_security_number)
|
91
108
|
assert_equal true, @user.respond_to?(:encrypted_string)
|
@@ -99,7 +116,7 @@ begin
|
|
99
116
|
assert_equal false, @user.respond_to?(:encrypted_name=)
|
100
117
|
end
|
101
118
|
|
102
|
-
|
119
|
+
it "have unencrypted methods" do
|
103
120
|
assert_equal true, @user.respond_to?(:bank_account_number)
|
104
121
|
assert_equal true, @user.respond_to?(:social_security_number)
|
105
122
|
assert_equal true, @user.respond_to?(:string)
|
@@ -113,22 +130,22 @@ begin
|
|
113
130
|
assert_equal true, @user.respond_to?(:name=)
|
114
131
|
end
|
115
132
|
|
116
|
-
|
133
|
+
it "support aliased fields" do
|
117
134
|
assert_equal true, @user.respond_to?(:aliased_integer_value=)
|
118
135
|
assert_equal true, @user.respond_to?(:aliased_integer_value)
|
119
136
|
end
|
120
137
|
|
121
|
-
|
138
|
+
it "have unencrypted values" do
|
122
139
|
assert_equal @bank_account_number, @user.bank_account_number
|
123
140
|
assert_equal @social_security_number, @user.social_security_number
|
124
141
|
end
|
125
142
|
|
126
|
-
|
143
|
+
it "have encrypted values" do
|
127
144
|
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
128
145
|
assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
|
129
146
|
end
|
130
147
|
|
131
|
-
|
148
|
+
it "support same iv" do
|
132
149
|
@user.social_security_number = @social_security_number
|
133
150
|
assert first_value = @user.social_security_number
|
134
151
|
# Assign the same value
|
@@ -136,7 +153,7 @@ begin
|
|
136
153
|
assert_equal first_value, @user.social_security_number
|
137
154
|
end
|
138
155
|
|
139
|
-
|
156
|
+
it "support a random iv" do
|
140
157
|
@user.string = @string
|
141
158
|
assert first_value = @user.encrypted_string
|
142
159
|
# Assign the same value
|
@@ -144,31 +161,31 @@ begin
|
|
144
161
|
assert_equal true, first_value != @user.encrypted_string
|
145
162
|
end
|
146
163
|
|
147
|
-
|
148
|
-
@user.string
|
164
|
+
it "support a random iv and compress" do
|
165
|
+
@user.string = @long_string
|
149
166
|
@user.long_string = @long_string
|
150
167
|
|
151
168
|
assert_equal true, (@user.encrypted_long_string.length.to_f / @user.encrypted_string.length) < 0.8
|
152
169
|
end
|
153
170
|
|
154
|
-
|
155
|
-
user
|
171
|
+
it "encrypt" do
|
172
|
+
user = MongoMapperUser.new
|
156
173
|
user.bank_account_number = @bank_account_number
|
157
174
|
assert_equal @bank_account_number, user.bank_account_number
|
158
175
|
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
159
176
|
end
|
160
177
|
|
161
|
-
|
178
|
+
it "all paths it lead to the same result" do
|
162
179
|
assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
|
163
180
|
assert_equal @bank_account_number, @user.social_security_number
|
164
181
|
end
|
165
182
|
|
166
|
-
|
183
|
+
it "all paths it lead to the same result 2" do
|
167
184
|
assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
|
168
185
|
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
169
186
|
end
|
170
187
|
|
171
|
-
|
188
|
+
it "all paths it lead to the same result, check uninitialized" do
|
172
189
|
user = MongoMapperUser.new
|
173
190
|
assert_equal nil, user.social_security_number
|
174
191
|
assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
|
@@ -180,7 +197,7 @@ begin
|
|
180
197
|
assert_equal nil, user.encrypted_social_security_number
|
181
198
|
end
|
182
199
|
|
183
|
-
|
200
|
+
it "allow unencrypted values to be passed to the constructor" do
|
184
201
|
user = MongoMapperUser.new(bank_account_number: @bank_account_number, social_security_number: @social_security_number)
|
185
202
|
assert_equal @bank_account_number, user.bank_account_number
|
186
203
|
assert_equal @social_security_number, user.social_security_number
|
@@ -188,7 +205,7 @@ begin
|
|
188
205
|
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
189
206
|
end
|
190
207
|
|
191
|
-
|
208
|
+
it "allow both encrypted and unencrypted values to be passed to the constructor" do
|
192
209
|
user = MongoMapperUser.new(encrypted_bank_account_number: @bank_account_number_encrypted, social_security_number: @social_security_number)
|
193
210
|
assert_equal @bank_account_number, user.bank_account_number
|
194
211
|
assert_equal @social_security_number, user.social_security_number
|
@@ -196,32 +213,57 @@ begin
|
|
196
213
|
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
197
214
|
end
|
198
215
|
|
199
|
-
|
200
|
-
|
216
|
+
describe 'changed?' do
|
217
|
+
before do
|
218
|
+
@user.save!
|
219
|
+
end
|
220
|
+
|
221
|
+
after do
|
222
|
+
@user.destroy if @user
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'return false if it was not changed' do
|
226
|
+
assert_equal false, @user.encrypted_bank_account_number_changed?
|
227
|
+
assert_equal false, @user.bank_account_number_changed?
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'return true if it was changed' do
|
231
|
+
@user.bank_account_number = '15424623'
|
232
|
+
assert_equal true, @user.encrypted_bank_account_number_changed?
|
233
|
+
assert_equal true, @user.bank_account_number_changed?
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "data types" do
|
238
|
+
before do
|
201
239
|
@user.save!
|
202
240
|
@user_clone = MongoMapperUser.find(@user.id)
|
203
241
|
end
|
204
242
|
|
205
|
-
|
206
|
-
|
243
|
+
after do
|
244
|
+
@user.destroy if @user
|
245
|
+
end
|
246
|
+
|
247
|
+
describe "aliased fields" do
|
248
|
+
it "return correct data type" do
|
207
249
|
@user_clone.aliased_integer_value = "5"
|
208
250
|
assert_equal 5, @user_clone.aliased_integer_value
|
209
251
|
end
|
210
252
|
end
|
211
253
|
|
212
|
-
|
213
|
-
|
254
|
+
describe "integer values" do
|
255
|
+
it "return correct data type" do
|
214
256
|
assert_equal @integer_value, @user_clone.integer_value
|
215
257
|
assert @user.clone.integer_value.kind_of?(Integer)
|
216
258
|
end
|
217
259
|
|
218
|
-
|
260
|
+
it "coerce data type before save" do
|
219
261
|
u = MongoMapperUser.new(integer_value: "5")
|
220
262
|
assert_equal 5, u.integer_value
|
221
263
|
assert u.integer_value.kind_of?(Integer)
|
222
264
|
end
|
223
265
|
|
224
|
-
|
266
|
+
it "permit replacing value with nil" do
|
225
267
|
@user_clone.integer_value = nil
|
226
268
|
@user_clone.save!
|
227
269
|
|
@@ -230,8 +272,8 @@ begin
|
|
230
272
|
assert_nil @user.encrypted_integer_value
|
231
273
|
end
|
232
274
|
|
233
|
-
|
234
|
-
new_integer_value
|
275
|
+
it "permit replacing value" do
|
276
|
+
new_integer_value = 98
|
235
277
|
@user_clone.integer_value = new_integer_value
|
236
278
|
@user_clone.save!
|
237
279
|
|
@@ -240,19 +282,19 @@ begin
|
|
240
282
|
end
|
241
283
|
end
|
242
284
|
|
243
|
-
|
244
|
-
|
285
|
+
describe "float values" do
|
286
|
+
it "return correct data type" do
|
245
287
|
assert_equal @float_value, @user_clone.float_value
|
246
288
|
assert @user.clone.float_value.kind_of?(Float)
|
247
289
|
end
|
248
290
|
|
249
|
-
|
291
|
+
it "coerce data type before save" do
|
250
292
|
u = MongoMapperUser.new(float_value: "5.6")
|
251
293
|
assert_equal 5.6, u.float_value
|
252
294
|
assert u.float_value.kind_of?(Float)
|
253
295
|
end
|
254
296
|
|
255
|
-
|
297
|
+
it "permit replacing value with nil" do
|
256
298
|
@user_clone.float_value = nil
|
257
299
|
@user_clone.save!
|
258
300
|
|
@@ -261,8 +303,8 @@ begin
|
|
261
303
|
assert_nil @user.encrypted_float_value
|
262
304
|
end
|
263
305
|
|
264
|
-
|
265
|
-
new_float_value
|
306
|
+
it "permit replacing value" do
|
307
|
+
new_float_value = 45.4321
|
266
308
|
@user_clone.float_value = new_float_value
|
267
309
|
@user_clone.save!
|
268
310
|
|
@@ -271,19 +313,19 @@ begin
|
|
271
313
|
end
|
272
314
|
end
|
273
315
|
|
274
|
-
|
275
|
-
|
316
|
+
describe "decimal values" do
|
317
|
+
it "return correct data type" do
|
276
318
|
assert_equal @decimal_value, @user_clone.decimal_value
|
277
319
|
assert @user.clone.decimal_value.kind_of?(BigDecimal)
|
278
320
|
end
|
279
321
|
|
280
|
-
|
322
|
+
it "coerce data type before save" do
|
281
323
|
u = MongoMapperUser.new(decimal_value: "99.95")
|
282
324
|
assert_equal BigDecimal.new("99.95"), u.decimal_value
|
283
325
|
assert u.decimal_value.kind_of?(BigDecimal)
|
284
326
|
end
|
285
327
|
|
286
|
-
|
328
|
+
it "permit replacing value with nil" do
|
287
329
|
@user_clone.decimal_value = nil
|
288
330
|
@user_clone.save!
|
289
331
|
|
@@ -292,8 +334,8 @@ begin
|
|
292
334
|
assert_nil @user.encrypted_decimal_value
|
293
335
|
end
|
294
336
|
|
295
|
-
|
296
|
-
new_decimal_value
|
337
|
+
it "permit replacing value" do
|
338
|
+
new_decimal_value = BigDecimal.new("99.95")
|
297
339
|
@user_clone.decimal_value = new_decimal_value
|
298
340
|
@user_clone.save!
|
299
341
|
|
@@ -302,20 +344,20 @@ begin
|
|
302
344
|
end
|
303
345
|
end
|
304
346
|
|
305
|
-
|
306
|
-
|
347
|
+
describe "datetime values" do
|
348
|
+
it "return correct data type" do
|
307
349
|
assert_equal @datetime_value, @user_clone.datetime_value
|
308
350
|
assert @user.clone.datetime_value.kind_of?(DateTime)
|
309
351
|
end
|
310
352
|
|
311
|
-
|
353
|
+
it "coerce data type before save" do
|
312
354
|
now = Time.now
|
313
|
-
u
|
355
|
+
u = MongoMapperUser.new(datetime_value: now)
|
314
356
|
assert_equal now, u.datetime_value
|
315
357
|
assert u.datetime_value.kind_of?(DateTime)
|
316
358
|
end
|
317
359
|
|
318
|
-
|
360
|
+
it "permit replacing value with nil" do
|
319
361
|
@user_clone.datetime_value = nil
|
320
362
|
@user_clone.save!
|
321
363
|
|
@@ -324,8 +366,8 @@ begin
|
|
324
366
|
assert_nil @user.encrypted_datetime_value
|
325
367
|
end
|
326
368
|
|
327
|
-
|
328
|
-
new_datetime_value
|
369
|
+
it "permit replacing value" do
|
370
|
+
new_datetime_value = DateTime.new(1998, 10, 21, 8, 33, 28, "+5")
|
329
371
|
@user_clone.datetime_value = new_datetime_value
|
330
372
|
@user_clone.save!
|
331
373
|
|
@@ -334,20 +376,20 @@ begin
|
|
334
376
|
end
|
335
377
|
end
|
336
378
|
|
337
|
-
|
338
|
-
|
379
|
+
describe "time values" do
|
380
|
+
it "return correct data type" do
|
339
381
|
assert_equal @time_value, @user_clone.time_value
|
340
382
|
assert @user.clone.time_value.kind_of?(Time)
|
341
383
|
end
|
342
384
|
|
343
|
-
|
385
|
+
it "coerce data type before save" do
|
344
386
|
now = Time.now
|
345
|
-
u
|
387
|
+
u = MongoMapperUser.new(time_value: now)
|
346
388
|
assert_equal now, u.time_value
|
347
389
|
assert u.time_value.kind_of?(Time)
|
348
390
|
end
|
349
391
|
|
350
|
-
|
392
|
+
it "permit replacing value with nil" do
|
351
393
|
@user_clone.time_value = nil
|
352
394
|
@user_clone.save!
|
353
395
|
|
@@ -356,8 +398,8 @@ begin
|
|
356
398
|
assert_nil @user.encrypted_time_value
|
357
399
|
end
|
358
400
|
|
359
|
-
|
360
|
-
new_time_value
|
401
|
+
it "permit replacing value" do
|
402
|
+
new_time_value = Time.new(1998, 10, 21, 8, 33, 28, "+04:00")
|
361
403
|
@user_clone.time_value = new_time_value
|
362
404
|
@user_clone.save!
|
363
405
|
|
@@ -366,20 +408,20 @@ begin
|
|
366
408
|
end
|
367
409
|
end
|
368
410
|
|
369
|
-
|
370
|
-
|
411
|
+
describe "date values" do
|
412
|
+
it "return correct data type" do
|
371
413
|
assert_equal @date_value, @user_clone.date_value
|
372
414
|
assert @user.clone.date_value.kind_of?(Date)
|
373
415
|
end
|
374
416
|
|
375
|
-
|
417
|
+
it "coerce data type before save" do
|
376
418
|
now = Time.now
|
377
|
-
u
|
419
|
+
u = MongoMapperUser.new(date_value: now)
|
378
420
|
assert_equal now.to_date, u.date_value
|
379
421
|
assert u.date_value.kind_of?(Date)
|
380
422
|
end
|
381
423
|
|
382
|
-
|
424
|
+
it "permit replacing value with nil" do
|
383
425
|
@user_clone.date_value = nil
|
384
426
|
@user_clone.save!
|
385
427
|
|
@@ -388,8 +430,8 @@ begin
|
|
388
430
|
assert_nil @user.encrypted_date_value
|
389
431
|
end
|
390
432
|
|
391
|
-
|
392
|
-
new_date_value
|
433
|
+
it "permit replacing value" do
|
434
|
+
new_date_value = Date.new(1998, 10, 21)
|
393
435
|
@user_clone.date_value = new_date_value
|
394
436
|
@user_clone.save!
|
395
437
|
|
@@ -398,19 +440,19 @@ begin
|
|
398
440
|
end
|
399
441
|
end
|
400
442
|
|
401
|
-
|
402
|
-
|
443
|
+
describe "true values" do
|
444
|
+
it "return correct data type" do
|
403
445
|
assert_equal true, @user_clone.true_value
|
404
446
|
assert @user.clone.true_value.kind_of?(TrueClass)
|
405
447
|
end
|
406
448
|
|
407
|
-
|
449
|
+
it "coerce data type before save" do
|
408
450
|
u = MongoMapperUser.new(true_value: "1")
|
409
451
|
assert_equal true, u.true_value
|
410
452
|
assert u.true_value.kind_of?(TrueClass)
|
411
453
|
end
|
412
454
|
|
413
|
-
|
455
|
+
it "permit replacing value with nil" do
|
414
456
|
@user_clone.true_value = nil
|
415
457
|
@user_clone.save!
|
416
458
|
|
@@ -419,8 +461,8 @@ begin
|
|
419
461
|
assert_nil @user.encrypted_true_value
|
420
462
|
end
|
421
463
|
|
422
|
-
|
423
|
-
new_value
|
464
|
+
it "permit replacing value" do
|
465
|
+
new_value = false
|
424
466
|
@user_clone.true_value = new_value
|
425
467
|
@user_clone.save!
|
426
468
|
|
@@ -429,19 +471,19 @@ begin
|
|
429
471
|
end
|
430
472
|
end
|
431
473
|
|
432
|
-
|
433
|
-
|
474
|
+
describe "false values" do
|
475
|
+
it "return correct data type" do
|
434
476
|
assert_equal false, @user_clone.false_value
|
435
477
|
assert @user.clone.false_value.kind_of?(FalseClass)
|
436
478
|
end
|
437
479
|
|
438
|
-
|
480
|
+
it "coerce data type before save" do
|
439
481
|
u = MongoMapperUser.new(false_value: "0")
|
440
482
|
assert_equal false, u.false_value
|
441
483
|
assert u.false_value.kind_of?(FalseClass)
|
442
484
|
end
|
443
485
|
|
444
|
-
|
486
|
+
it "permit replacing value with nil" do
|
445
487
|
@user_clone.false_value = nil
|
446
488
|
@user_clone.save!
|
447
489
|
|
@@ -450,8 +492,8 @@ begin
|
|
450
492
|
assert_nil @user.encrypted_false_value
|
451
493
|
end
|
452
494
|
|
453
|
-
|
454
|
-
new_value
|
495
|
+
it "permit replacing value" do
|
496
|
+
new_value = true
|
455
497
|
@user_clone.false_value = new_value
|
456
498
|
@user_clone.save!
|
457
499
|
|
@@ -460,8 +502,8 @@ begin
|
|
460
502
|
end
|
461
503
|
end
|
462
504
|
|
463
|
-
|
464
|
-
|
505
|
+
describe "JSON Serialization" do
|
506
|
+
before do
|
465
507
|
# JSON Does not support symbols, so they will come back as strings
|
466
508
|
# Convert symbols to string in the test
|
467
509
|
@h.keys.each do |k|
|
@@ -470,18 +512,18 @@ begin
|
|
470
512
|
end
|
471
513
|
end
|
472
514
|
|
473
|
-
|
515
|
+
it "return correct data type" do
|
474
516
|
assert_equal @h, @user_clone.data_json
|
475
517
|
assert @user.clone.data_json.kind_of?(Hash)
|
476
518
|
end
|
477
519
|
|
478
|
-
|
520
|
+
it "not coerce data type (leaves as hash) before save" do
|
479
521
|
u = MongoMapperUser.new(data_json: @h)
|
480
522
|
assert_equal @h, u.data_json
|
481
523
|
assert u.data_json.kind_of?(Hash)
|
482
524
|
end
|
483
525
|
|
484
|
-
|
526
|
+
it "permit replacing value with nil" do
|
485
527
|
@user_clone.data_json = nil
|
486
528
|
@user_clone.save!
|
487
529
|
|
@@ -490,9 +532,9 @@ begin
|
|
490
532
|
assert_nil @user.encrypted_data_json
|
491
533
|
end
|
492
534
|
|
493
|
-
|
494
|
-
new_value
|
495
|
-
new_value['c']
|
535
|
+
it "permit replacing value" do
|
536
|
+
new_value = @h.clone
|
537
|
+
new_value['c'] = 'C'
|
496
538
|
@user_clone.data_json = new_value
|
497
539
|
@user_clone.save!
|
498
540
|
|
@@ -501,19 +543,19 @@ begin
|
|
501
543
|
end
|
502
544
|
end
|
503
545
|
|
504
|
-
|
505
|
-
|
546
|
+
describe "YAML Serialization" do
|
547
|
+
it "return correct data type" do
|
506
548
|
assert_equal @h, @user_clone.data_yaml
|
507
549
|
assert @user.clone.data_yaml.kind_of?(Hash)
|
508
550
|
end
|
509
551
|
|
510
|
-
|
552
|
+
it "not coerce data type (leaves as hash) before save" do
|
511
553
|
u = MongoMapperUser.new(data_yaml: @h)
|
512
554
|
assert_equal @h, u.data_yaml
|
513
555
|
assert u.data_yaml.kind_of?(Hash)
|
514
556
|
end
|
515
557
|
|
516
|
-
|
558
|
+
it "permit replacing value with nil" do
|
517
559
|
@user_clone.data_yaml = nil
|
518
560
|
@user_clone.save!
|
519
561
|
|
@@ -522,9 +564,9 @@ begin
|
|
522
564
|
assert_nil @user.encrypted_data_yaml
|
523
565
|
end
|
524
566
|
|
525
|
-
|
526
|
-
new_value
|
527
|
-
new_value[:c]
|
567
|
+
it "permit replacing value" do
|
568
|
+
new_value = @h.clone
|
569
|
+
new_value[:c] = 'C'
|
528
570
|
@user_clone.data_yaml = new_value
|
529
571
|
@user_clone.save!
|
530
572
|
|
@@ -535,8 +577,23 @@ begin
|
|
535
577
|
|
536
578
|
end
|
537
579
|
|
580
|
+
describe 'uniqueness' do
|
581
|
+
before do
|
582
|
+
MongoMapperUniqueUser.destroy_all
|
583
|
+
@email = 'whatever@not-unique.com'
|
584
|
+
@username = 'gibby007'
|
585
|
+
@user = MongoMapperUniqueUser.create!(email: @email)
|
586
|
+
end
|
587
|
+
|
588
|
+
it 'does not allow duplicate values' do
|
589
|
+
duplicate = MongoMapperUniqueUser.new(email: @email)
|
590
|
+
assert_equal false, duplicate.valid?
|
591
|
+
assert_equal 'has already been taken', duplicate.errors.messages[:encrypted_email].first
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
538
595
|
end
|
539
596
|
end
|
540
597
|
rescue LoadError
|
541
|
-
puts
|
598
|
+
puts 'Not running MongoMapper tests because mongo_mapper gem is not installed!!!'
|
542
599
|
end
|