symmetric-encryption 3.7.2 → 3.8.0
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 +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
|