metasploit-credential 0.14.5 → 0.14.6
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/lib/metasploit/credential/exporter/core.rb +2 -2
- data/lib/metasploit/credential/exporter/pwdump.rb +2 -2
- data/lib/metasploit/credential/migrator.rb +1 -1
- data/lib/metasploit/credential/version.rb +1 -3
- data/spec/dummy/config/database.yml +13 -11
- data/spec/dummy/db/structure.sql +1 -0
- data/spec/lib/metasploit/credential/creation_spec.rb +6 -8
- data/spec/lib/metasploit/credential/exporter/core_spec.rb +100 -85
- data/spec/lib/metasploit/credential/exporter/pwdump_spec.rb +14 -16
- data/spec/lib/metasploit/credential/importer/core_spec.rb +10 -12
- data/spec/lib/metasploit/credential/importer/multi_spec.rb +4 -6
- data/spec/lib/metasploit/credential/importer/pwdump_spec.rb +11 -13
- data/spec/lib/metasploit/credential/importer/zip_spec.rb +5 -7
- data/spec/lib/metasploit/credential/migrator_spec.rb +13 -13
- data/spec/lib/metasploit/credential/version_spec.rb +3 -5
- data/spec/lib/metasploit/credential_spec.rb +1 -3
- data/spec/models/mdm/service_spec.rb +3 -5
- data/spec/models/mdm/session_spec.rb +2 -4
- data/spec/models/mdm/task_spec.rb +4 -6
- data/spec/models/mdm/user_spec.rb +2 -4
- data/spec/models/mdm/workspace_spec.rb +2 -4
- data/spec/models/metasploit/credential/blank_username_spec.rb +5 -7
- data/spec/models/metasploit/credential/core_spec.rb +43 -45
- data/spec/models/metasploit/credential/login/status_spec.rb +19 -21
- data/spec/models/metasploit/credential/login_spec.rb +36 -38
- data/spec/models/metasploit/credential/nonreplayable_hash_spec.rb +3 -5
- data/spec/models/metasploit/credential/ntlm_hash_spec.rb +13 -15
- data/spec/models/metasploit/credential/origin/cracked_password_spec.rb +5 -7
- data/spec/models/metasploit/credential/origin/import_spec.rb +8 -10
- data/spec/models/metasploit/credential/origin/manual_spec.rb +7 -9
- data/spec/models/metasploit/credential/origin/service_spec.rb +10 -12
- data/spec/models/metasploit/credential/origin/session_spec.rb +11 -13
- data/spec/models/metasploit/credential/password_hash_spec.rb +4 -6
- data/spec/models/metasploit/credential/password_spec.rb +3 -5
- data/spec/models/metasploit/credential/postgres_md5_spec.rb +4 -6
- data/spec/models/metasploit/credential/private_spec.rb +8 -10
- data/spec/models/metasploit/credential/public_spec.rb +5 -7
- data/spec/models/metasploit/credential/realm_spec.rb +14 -16
- data/spec/models/metasploit/credential/replayable_hash_spec.rb +3 -5
- data/spec/models/metasploit/credential/ssh_key_spec.rb +15 -17
- data/spec/models/metasploit/credential/username_spec.rb +6 -8
- data/spec/models/metasploit_data_models/search/visitor/relation_spec.rb +1 -3
- data/spec/spec_helper.rb +83 -18
- data/spec/support/shared/contexts/mdm/workspace.rb +1 -1
- data/spec/support/shared/examples/core_validations.rb +117 -42
- data/spec/support/shared/examples/single_table_inheritance_database_columns.rb +2 -2
- data/spec/support/shared/examples/timestamp_database_column.rb +2 -2
- metadata +9 -9
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::Login do
|
1
|
+
RSpec.describe Metasploit::Credential::Login, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
4
|
context 'associations' do
|
7
|
-
it {
|
8
|
-
it {
|
9
|
-
it {
|
5
|
+
it { is_expected.to belong_to(:core).class_name('Metasploit::Credential::Core') }
|
6
|
+
it { is_expected.to have_one(:host).class_name('Mdm::Host') }
|
7
|
+
it { is_expected.to belong_to(:service).class_name('Mdm::Service')}
|
10
8
|
end
|
11
9
|
|
12
10
|
context 'callbacks' do
|
@@ -39,7 +37,7 @@ describe Metasploit::Credential::Login do
|
|
39
37
|
''
|
40
38
|
end
|
41
39
|
|
42
|
-
it {
|
40
|
+
it { is_expected.to be_nil }
|
43
41
|
end
|
44
42
|
|
45
43
|
context 'with nil' do
|
@@ -47,7 +45,7 @@ describe Metasploit::Credential::Login do
|
|
47
45
|
nil
|
48
46
|
end
|
49
47
|
|
50
|
-
it {
|
48
|
+
it { is_expected.to be_nil }
|
51
49
|
end
|
52
50
|
|
53
51
|
context 'with present' do
|
@@ -66,21 +64,21 @@ describe Metasploit::Credential::Login do
|
|
66
64
|
|
67
65
|
context 'database' do
|
68
66
|
context 'columns' do
|
69
|
-
it {
|
70
|
-
it {
|
71
|
-
it {
|
67
|
+
it { is_expected.to have_db_column(:access_level).of_type(:string).with_options(null: true) }
|
68
|
+
it { is_expected.to have_db_column(:last_attempted_at).of_type(:datetime).with_options(null: true) }
|
69
|
+
it { is_expected.to have_db_column(:status).of_type(:string).with_options(null: false) }
|
72
70
|
|
73
71
|
it_should_behave_like 'timestamp database columns'
|
74
72
|
|
75
73
|
context 'foreign keys' do
|
76
|
-
it {
|
77
|
-
it {
|
74
|
+
it { is_expected.to have_db_column(:core_id).of_type(:integer).with_options(null: false) }
|
75
|
+
it { is_expected.to have_db_column(:service_id).of_type(:integer).with_options(null: false) }
|
78
76
|
end
|
79
77
|
end
|
80
78
|
|
81
79
|
context 'indices' do
|
82
|
-
it {
|
83
|
-
it {
|
80
|
+
it { is_expected.to have_db_index([:core_id, :service_id]).unique(true) }
|
81
|
+
it { is_expected.to have_db_index([:service_id, :core_id]).unique(true) }
|
84
82
|
end
|
85
83
|
end
|
86
84
|
|
@@ -92,7 +90,7 @@ describe Metasploit::Credential::Login do
|
|
92
90
|
FactoryGirl.build(:metasploit_credential_login)
|
93
91
|
end
|
94
92
|
|
95
|
-
it {
|
93
|
+
it { is_expected.to be_valid }
|
96
94
|
|
97
95
|
context '#status' do
|
98
96
|
subject(:metasploit_credential_login) do
|
@@ -107,7 +105,7 @@ describe Metasploit::Credential::Login do
|
|
107
105
|
Metasploit::Model::Login::Status::DENIED_ACCESS
|
108
106
|
end
|
109
107
|
|
110
|
-
it {
|
108
|
+
it { is_expected.to be_valid }
|
111
109
|
end
|
112
110
|
|
113
111
|
context 'with Metasploit::Model::Login::Status::DISABLED' do
|
@@ -115,7 +113,7 @@ describe Metasploit::Credential::Login do
|
|
115
113
|
Metasploit::Model::Login::Status::DISABLED
|
116
114
|
end
|
117
115
|
|
118
|
-
it {
|
116
|
+
it { is_expected.to be_valid }
|
119
117
|
end
|
120
118
|
|
121
119
|
context 'with Metasploit::Model::Login::Status::LOCKED_OUT' do
|
@@ -123,7 +121,7 @@ describe Metasploit::Credential::Login do
|
|
123
121
|
Metasploit::Model::Login::Status::LOCKED_OUT
|
124
122
|
end
|
125
123
|
|
126
|
-
it {
|
124
|
+
it { is_expected.to be_valid }
|
127
125
|
end
|
128
126
|
|
129
127
|
context 'with Metasploit::Model::Login::Status::SUCCESSFUL' do
|
@@ -131,7 +129,7 @@ describe Metasploit::Credential::Login do
|
|
131
129
|
Metasploit::Model::Login::Status::SUCCESSFUL
|
132
130
|
end
|
133
131
|
|
134
|
-
it {
|
132
|
+
it { is_expected.to be_valid }
|
135
133
|
end
|
136
134
|
|
137
135
|
context 'with Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
@@ -139,7 +137,7 @@ describe Metasploit::Credential::Login do
|
|
139
137
|
Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
140
138
|
end
|
141
139
|
|
142
|
-
it {
|
140
|
+
it { is_expected.to be_valid }
|
143
141
|
end
|
144
142
|
|
145
143
|
context 'with Metasploit::Model::Login::Status::UNTRIED' do
|
@@ -147,21 +145,21 @@ describe Metasploit::Credential::Login do
|
|
147
145
|
Metasploit::Model::Login::Status::UNTRIED
|
148
146
|
end
|
149
147
|
|
150
|
-
it {
|
148
|
+
it { is_expected.to be_valid }
|
151
149
|
end
|
152
150
|
end
|
153
151
|
end
|
154
152
|
end
|
155
153
|
|
156
154
|
context 'mass assignment security' do
|
157
|
-
it {
|
155
|
+
it { is_expected.to allow_mass_assignment_of(:access_level) }
|
158
156
|
it { should_not allow_mass_assignment_of(:core) }
|
159
157
|
it { should_not allow_mass_assignment_of(:core_id) }
|
160
158
|
it { should_not allow_mass_assignment_of(:created_at) }
|
161
|
-
it {
|
159
|
+
it { is_expected.to allow_mass_assignment_of(:last_attempted_at) }
|
162
160
|
it { should_not allow_mass_assignment_of(:service) }
|
163
161
|
it { should_not allow_mass_assignment_of(:service_id) }
|
164
|
-
it {
|
162
|
+
it { is_expected.to allow_mass_assignment_of(:status) }
|
165
163
|
it { should_not allow_mass_assignment_of(:updated_at) }
|
166
164
|
end
|
167
165
|
|
@@ -191,7 +189,7 @@ describe Metasploit::Credential::Login do
|
|
191
189
|
end
|
192
190
|
|
193
191
|
context 'validations' do
|
194
|
-
it {
|
192
|
+
it { is_expected.to validate_presence_of :core }
|
195
193
|
|
196
194
|
context 'with existent Metasploit::Credential::Login' do
|
197
195
|
include_context 'Mdm::Workspace'
|
@@ -204,11 +202,11 @@ describe Metasploit::Credential::Login do
|
|
204
202
|
)
|
205
203
|
end
|
206
204
|
|
207
|
-
it {
|
205
|
+
it { is_expected.to validate_uniqueness_of(:core_id).scoped_to(:service_id) }
|
208
206
|
end
|
209
207
|
|
210
|
-
it {
|
211
|
-
it {
|
208
|
+
it { is_expected.to validate_presence_of :service }
|
209
|
+
it { is_expected.to ensure_inclusion_of(:status).in_array(Metasploit::Model::Login::Status::ALL) }
|
212
210
|
|
213
211
|
context '#consistent_last_attempted_at' do
|
214
212
|
include_context 'Mdm::Workspace'
|
@@ -252,7 +250,7 @@ describe Metasploit::Credential::Login do
|
|
252
250
|
DateTime.now.utc
|
253
251
|
end
|
254
252
|
|
255
|
-
it {
|
253
|
+
it { is_expected.to include(error) }
|
256
254
|
end
|
257
255
|
|
258
256
|
context 'without #last_attempted' do
|
@@ -290,7 +288,7 @@ describe Metasploit::Credential::Login do
|
|
290
288
|
nil
|
291
289
|
end
|
292
290
|
|
293
|
-
it {
|
291
|
+
it { is_expected.to include(error) }
|
294
292
|
end
|
295
293
|
end
|
296
294
|
end
|
@@ -363,7 +361,7 @@ describe Metasploit::Credential::Login do
|
|
363
361
|
FactoryGirl.build(:mdm_workspace)
|
364
362
|
end
|
365
363
|
|
366
|
-
it {
|
364
|
+
it { is_expected.to include(error) }
|
367
365
|
end
|
368
366
|
end
|
369
367
|
|
@@ -372,7 +370,7 @@ describe Metasploit::Credential::Login do
|
|
372
370
|
nil
|
373
371
|
end
|
374
372
|
|
375
|
-
it {
|
373
|
+
it { is_expected.to include(error) }
|
376
374
|
end
|
377
375
|
end
|
378
376
|
|
@@ -381,7 +379,7 @@ describe Metasploit::Credential::Login do
|
|
381
379
|
nil
|
382
380
|
end
|
383
381
|
|
384
|
-
it {
|
382
|
+
it { is_expected.to include(error) }
|
385
383
|
end
|
386
384
|
end
|
387
385
|
|
@@ -390,7 +388,7 @@ describe Metasploit::Credential::Login do
|
|
390
388
|
nil
|
391
389
|
end
|
392
390
|
|
393
|
-
it {
|
391
|
+
it { is_expected.to include(error) }
|
394
392
|
end
|
395
393
|
end
|
396
394
|
|
@@ -422,7 +420,7 @@ describe Metasploit::Credential::Login do
|
|
422
420
|
FactoryGirl.build(:mdm_workspace)
|
423
421
|
end
|
424
422
|
|
425
|
-
it {
|
423
|
+
it { is_expected.to include(error) }
|
426
424
|
end
|
427
425
|
|
428
426
|
context 'without Mdm::Host#workspace' do
|
@@ -479,7 +477,7 @@ describe Metasploit::Credential::Login do
|
|
479
477
|
FactoryGirl.build(:mdm_workspace)
|
480
478
|
end
|
481
479
|
|
482
|
-
it {
|
480
|
+
it { is_expected.to include(error) }
|
483
481
|
end
|
484
482
|
|
485
483
|
context 'without Mdm::Host#workspace' do
|
@@ -522,7 +520,7 @@ describe Metasploit::Credential::Login do
|
|
522
520
|
subject(:login){ FactoryGirl.create :metasploit_credential_login, core: core}
|
523
521
|
|
524
522
|
it 'should find the right objects' do
|
525
|
-
Metasploit::Credential::Login.in_workspace_including_hosts_and_services(service.host.workspace).
|
523
|
+
expect(Metasploit::Credential::Login.in_workspace_including_hosts_and_services(service.host.workspace)).to include(login)
|
526
524
|
end
|
527
525
|
end
|
528
526
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::NonreplayableHash do
|
1
|
+
RSpec.describe Metasploit::Credential::NonreplayableHash, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
|
-
it {
|
4
|
+
it { is_expected.to be_a Metasploit::Credential::PasswordHash }
|
7
5
|
|
8
6
|
context 'factories' do
|
9
7
|
context 'metasploit_credential_nonreplayable_hash' do
|
@@ -11,7 +9,7 @@ describe Metasploit::Credential::NonreplayableHash do
|
|
11
9
|
FactoryGirl.build(:metasploit_credential_nonreplayable_hash)
|
12
10
|
end
|
13
11
|
|
14
|
-
it {
|
12
|
+
it { is_expected.to be_valid }
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::NTLMHash do
|
1
|
+
RSpec.describe Metasploit::Credential::NTLMHash, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
|
-
it {
|
4
|
+
it { is_expected.to be_a Metasploit::Credential::ReplayableHash }
|
7
5
|
|
8
6
|
context 'CONSTANTS' do
|
9
7
|
context 'DATA_REGEXP' do
|
@@ -38,7 +36,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
38
36
|
described_class::LAN_MANAGER_MAX_CHARACTERS
|
39
37
|
end
|
40
38
|
|
41
|
-
it {
|
39
|
+
it { is_expected.to eq 14 }
|
42
40
|
end
|
43
41
|
|
44
42
|
context 'LAN_MANAGER_HEX_DIGEST_REGEXP' do
|
@@ -101,7 +99,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
101
99
|
nil
|
102
100
|
end
|
103
101
|
|
104
|
-
it {
|
102
|
+
it { is_expected.to be_nil }
|
105
103
|
end
|
106
104
|
|
107
105
|
context 'with upper case characters' do
|
@@ -133,7 +131,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
133
131
|
FactoryGirl.build(:metasploit_credential_ntlm_hash)
|
134
132
|
end
|
135
133
|
|
136
|
-
it {
|
134
|
+
it { is_expected.to be_valid }
|
137
135
|
end
|
138
136
|
end
|
139
137
|
|
@@ -191,7 +189,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
191
189
|
super().gsub(':', '')
|
192
190
|
end
|
193
191
|
|
194
|
-
it {
|
192
|
+
it { is_expected.to include(error) }
|
195
193
|
end
|
196
194
|
|
197
195
|
context 'without LAN Manager hex_digest' do
|
@@ -199,7 +197,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
199
197
|
":#{nt_lan_manager_hex_digest}"
|
200
198
|
end
|
201
199
|
|
202
|
-
it {
|
200
|
+
it { is_expected.to include(error) }
|
203
201
|
end
|
204
202
|
|
205
203
|
context 'with incorrect hash length(s)' do
|
@@ -207,7 +205,7 @@ describe Metasploit::Credential::NTLMHash do
|
|
207
205
|
"123456:abcdef"
|
208
206
|
end
|
209
207
|
|
210
|
-
it {
|
208
|
+
it { is_expected.to include(error) }
|
211
209
|
end
|
212
210
|
end
|
213
211
|
end
|
@@ -375,26 +373,26 @@ describe Metasploit::Credential::NTLMHash do
|
|
375
373
|
context 'blank_password?' do
|
376
374
|
|
377
375
|
it 'returns true if the hash is for a blank password' do
|
378
|
-
expect(blank_password_hash.blank_password?).to
|
376
|
+
expect(blank_password_hash.blank_password?).to eq(true)
|
379
377
|
end
|
380
378
|
|
381
379
|
it 'returns false if the hash is not for a blank password' do
|
382
|
-
expect(non_blank_password.blank_password?).to
|
380
|
+
expect(non_blank_password.blank_password?).to eq(false)
|
383
381
|
end
|
384
382
|
|
385
383
|
it 'returns false if the nt hash is not blank but the lm hash is' do
|
386
|
-
expect(no_lm_hash.blank_password?).to
|
384
|
+
expect(no_lm_hash.blank_password?).to eq(false)
|
387
385
|
end
|
388
386
|
end
|
389
387
|
|
390
388
|
context 'lm_hash_present?' do
|
391
389
|
|
392
390
|
it 'returns false if the lm_hash is blank' do
|
393
|
-
expect(no_lm_hash.lm_hash_present?).to
|
391
|
+
expect(no_lm_hash.lm_hash_present?).to eq(false)
|
394
392
|
end
|
395
393
|
|
396
394
|
it 'returns true if the lm_hash is not blank' do
|
397
|
-
expect(non_blank_password.lm_hash_present?).to
|
395
|
+
expect(non_blank_password.lm_hash_present?).to eq(true)
|
398
396
|
end
|
399
397
|
end
|
400
398
|
end
|
@@ -1,11 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::Origin::CrackedPassword do
|
1
|
+
RSpec.describe Metasploit::Credential::Origin::CrackedPassword, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
4
|
context 'associations' do
|
7
|
-
it {
|
8
|
-
it {
|
5
|
+
it { is_expected.to have_many(:cores).class_name('Metasploit::Credential::Core').dependent(:destroy) }
|
6
|
+
it { is_expected.to belong_to(:originating_core).class_name('Metasploit::Credential::Core') }
|
9
7
|
end
|
10
8
|
|
11
9
|
context 'database' do
|
@@ -13,13 +11,13 @@ describe Metasploit::Credential::Origin::CrackedPassword do
|
|
13
11
|
it_should_behave_like 'timestamp database columns'
|
14
12
|
|
15
13
|
context 'foreign keys' do
|
16
|
-
it {
|
14
|
+
it { is_expected.to have_db_column(:metasploit_credential_core_id).of_type(:integer).with_options(null: false) }
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
18
|
context 'indices' do
|
21
19
|
context 'foreign keys' do
|
22
|
-
it {
|
20
|
+
it { is_expected.to have_db_index(:metasploit_credential_core_id) }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -1,27 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::Origin::Import do
|
1
|
+
RSpec.describe Metasploit::Credential::Origin::Import, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
4
|
context 'associations' do
|
7
|
-
it {
|
8
|
-
it {
|
5
|
+
it { is_expected.to have_many(:cores).class_name('Metasploit::Credential::Core').dependent(:destroy) }
|
6
|
+
it { is_expected.to belong_to(:task).class_name('Mdm::Task') }
|
9
7
|
end
|
10
8
|
|
11
9
|
context 'database' do
|
12
10
|
context 'columns' do
|
13
|
-
it {
|
11
|
+
it { is_expected.to have_db_column(:filename).of_type(:text).with_options(null: false) }
|
14
12
|
|
15
13
|
it_should_behave_like 'timestamp database columns'
|
16
14
|
|
17
15
|
context 'foreign keys' do
|
18
|
-
it {
|
16
|
+
it { is_expected.to have_db_column(:task_id).of_type(:integer) }
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
22
20
|
context 'indices' do
|
23
21
|
context 'foreign keys' do
|
24
|
-
it {
|
22
|
+
it { is_expected.to have_db_index(:task_id) }
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -33,12 +31,12 @@ describe Metasploit::Credential::Origin::Import do
|
|
33
31
|
FactoryGirl.build(:metasploit_credential_origin_import)
|
34
32
|
end
|
35
33
|
|
36
|
-
it {
|
34
|
+
it { is_expected.to be_valid }
|
37
35
|
end
|
38
36
|
|
39
37
|
context 'mass assignment security' do
|
40
38
|
it { should_not allow_mass_assignment_of :created_at }
|
41
|
-
it {
|
39
|
+
it { is_expected.to allow_mass_assignment_of :filename }
|
42
40
|
it { should_not allow_mass_assignment_of :task }
|
43
41
|
it { should_not allow_mass_assignment_of :task_id }
|
44
42
|
it { should_not allow_mass_assignment_of :updated_at }
|
@@ -1,17 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Metasploit::Credential::Origin::Manual do
|
1
|
+
RSpec.describe Metasploit::Credential::Origin::Manual, type: :model do
|
4
2
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
3
|
|
6
4
|
context 'associations' do
|
7
|
-
it {
|
8
|
-
it {
|
5
|
+
it { is_expected.to have_many(:cores).class_name('Metasploit::Credential::Core').dependent(:destroy) }
|
6
|
+
it { is_expected.to belong_to(:user).class_name('Mdm::User') }
|
9
7
|
end
|
10
8
|
|
11
9
|
context 'database' do
|
12
10
|
context 'columns' do
|
13
11
|
context 'foreign keys' do
|
14
|
-
it {
|
12
|
+
it { is_expected.to have_db_column(:user_id).of_type(:integer).with_options(null: false) }
|
15
13
|
end
|
16
14
|
|
17
15
|
it_should_behave_like 'timestamp database columns'
|
@@ -19,7 +17,7 @@ describe Metasploit::Credential::Origin::Manual do
|
|
19
17
|
|
20
18
|
context 'indices' do
|
21
19
|
context 'foreign keys' do
|
22
|
-
it {
|
20
|
+
it { is_expected.to have_db_index(:user_id) }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -30,11 +28,11 @@ describe Metasploit::Credential::Origin::Manual do
|
|
30
28
|
FactoryGirl.build(:metasploit_credential_origin_manual)
|
31
29
|
end
|
32
30
|
|
33
|
-
it {
|
31
|
+
it { is_expected.to be_valid }
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
35
|
context 'validations' do
|
38
|
-
it {
|
36
|
+
it { is_expected.to validate_presence_of :user }
|
39
37
|
end
|
40
38
|
end
|