ronin-exploits 1.0.0.beta2 → 1.0.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -0
  3. data/README.md +29 -13
  4. data/gemspec.yml +10 -8
  5. data/lib/ronin/exploits/cli/commands/new.rb +1 -1
  6. data/lib/ronin/exploits/cli/commands/run.rb +55 -5
  7. data/lib/ronin/exploits/exploit.rb +7 -5
  8. data/lib/ronin/exploits/lfi.rb +1 -1
  9. data/lib/ronin/exploits/metadata/arch.rb +1 -1
  10. data/lib/ronin/exploits/metadata/default_filename.rb +1 -1
  11. data/lib/ronin/exploits/metadata/default_port.rb +1 -1
  12. data/lib/ronin/exploits/mixins/file_builder.rb +2 -2
  13. data/lib/ronin/exploits/mixins/nops.rb +1 -1
  14. data/lib/ronin/exploits/params/base_url.rb +1 -1
  15. data/lib/ronin/exploits/version.rb +1 -1
  16. data/ronin-exploits.gemspec +2 -1
  17. metadata +24 -129
  18. data/spec/advisory_spec.rb +0 -71
  19. data/spec/cli/exploit_command_spec.rb +0 -68
  20. data/spec/cli/exploit_methods_spec.rb +0 -208
  21. data/spec/cli/ruby_shell_spec.rb +0 -14
  22. data/spec/client_side_web_vuln_spec.rb +0 -117
  23. data/spec/exploit_spec.rb +0 -538
  24. data/spec/exploits_spec.rb +0 -8
  25. data/spec/heap_overflow_spec.rb +0 -14
  26. data/spec/lfi_spec.rb +0 -162
  27. data/spec/loot/file_spec.rb +0 -131
  28. data/spec/loot_spec.rb +0 -138
  29. data/spec/memory_corruption_spec.rb +0 -22
  30. data/spec/metadata/arch_spec.rb +0 -82
  31. data/spec/metadata/cookie_param_spec.rb +0 -67
  32. data/spec/metadata/default_filename_spec.rb +0 -62
  33. data/spec/metadata/default_port_spec.rb +0 -62
  34. data/spec/metadata/header_name_spec.rb +0 -67
  35. data/spec/metadata/os_spec.rb +0 -164
  36. data/spec/metadata/shouts_spec.rb +0 -100
  37. data/spec/metadata/url_path_spec.rb +0 -67
  38. data/spec/metadata/url_query_param_spec.rb +0 -67
  39. data/spec/mixins/binary_spec.rb +0 -129
  40. data/spec/mixins/build_dir.rb +0 -66
  41. data/spec/mixins/file_builder_spec.rb +0 -67
  42. data/spec/mixins/format_string_spec.rb +0 -44
  43. data/spec/mixins/has_payload_spec.rb +0 -333
  44. data/spec/mixins/has_targets_spec.rb +0 -434
  45. data/spec/mixins/html_spec.rb +0 -772
  46. data/spec/mixins/http_spec.rb +0 -1227
  47. data/spec/mixins/loot_spec.rb +0 -20
  48. data/spec/mixins/nops_spec.rb +0 -165
  49. data/spec/mixins/remote_tcp_spec.rb +0 -217
  50. data/spec/mixins/remote_udp_spec.rb +0 -217
  51. data/spec/mixins/seh_spec.rb +0 -89
  52. data/spec/mixins/stack_overflow_spec.rb +0 -87
  53. data/spec/mixins/text_spec.rb +0 -43
  54. data/spec/open_redirect_spec.rb +0 -71
  55. data/spec/params/base_url_spec.rb +0 -71
  56. data/spec/params/bind_host_spec.rb +0 -34
  57. data/spec/params/bind_port_spec.rb +0 -35
  58. data/spec/params/filename_spec.rb +0 -77
  59. data/spec/params/host_spec.rb +0 -34
  60. data/spec/params/port_spec.rb +0 -77
  61. data/spec/rfi_spec.rb +0 -107
  62. data/spec/seh_overflow_spec.rb +0 -18
  63. data/spec/spec_helper.rb +0 -8
  64. data/spec/sqli_spec.rb +0 -306
  65. data/spec/ssti_spec.rb +0 -121
  66. data/spec/stack_overflow_spec.rb +0 -18
  67. data/spec/target_spec.rb +0 -92
  68. data/spec/test_result_spec.rb +0 -32
  69. data/spec/use_after_free_spec.rb +0 -14
  70. data/spec/web_spec.rb +0 -12
  71. data/spec/web_vuln_spec.rb +0 -854
  72. data/spec/xss_spec.rb +0 -69
data/spec/lfi_spec.rb DELETED
@@ -1,162 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/lfi'
3
-
4
- describe Ronin::Exploits::LFI do
5
- module TestLFI
6
- class TestExploit < Ronin::Exploits::LFI
7
- base_path '/Templatize.asp'
8
- query_param 'item'
9
- end
10
- end
11
-
12
- let(:exploit_class) { TestLFI::TestExploit }
13
- let(:base_url) { 'http://testasp.vulnweb.com/' }
14
- let(:query) { 'item=html/about.html' }
15
- let(:query_param) { 'item' }
16
-
17
- subject do
18
- exploit_class.new(
19
- params: {
20
- base_url: base_url
21
- }
22
- )
23
- end
24
-
25
- describe ".depth" do
26
- subject { exploit_class }
27
-
28
- context "and when depth is not set in the class" do
29
- module TestLFI
30
- class WithNoDepthSet < Ronin::Exploits::LFI
31
- end
32
- end
33
-
34
- let(:exploit_class) { TestLFI::WithNoDepthSet }
35
-
36
- it "must default to Ronin::Vulns::LFI::DEFAULT_DEPTH" do
37
- expect(subject.depth).to be(Ronin::Vulns::LFI::DEFAULT_DEPTH)
38
- end
39
- end
40
-
41
- context "and when depth is set in the class" do
42
- module TestLFI
43
- class WithDepthSet < Ronin::Exploits::LFI
44
- depth 5
45
- end
46
- end
47
-
48
- let(:exploit_class) { TestLFI::WithDepthSet }
49
-
50
- it "must return the set depth" do
51
- expect(subject.depth).to eq(5)
52
- end
53
- end
54
-
55
- context "but when the depth was set in the superclass" do
56
- module TestLFI
57
- class InheritsItsDepth < WithDepthSet
58
- end
59
- end
60
-
61
- let(:exploit_class) { TestLFI::InheritsItsDepth }
62
-
63
- it "must return the depth set in the superclass" do
64
- expect(subject.depth).to eq(5)
65
- end
66
-
67
- context "but the depth is overridden in the sub-class" do
68
- module TestLFI
69
- class OverridesItsInheritedDepth < WithDepthSet
70
- depth 7
71
- end
72
- end
73
-
74
- let(:exploit_class) do
75
- TestLFI::OverridesItsInheritedDepth
76
- end
77
-
78
- it "must return the depth set in the sub-class" do
79
- expect(subject.depth).to eq(7)
80
- end
81
- end
82
- end
83
- end
84
-
85
- describe ".exploit_type" do
86
- subject { described_class }
87
-
88
- it { expect(subject.exploit_type).to eq(:lfi) }
89
- end
90
-
91
- describe "#vuln" do
92
- it "must return a Ronin::Vulns::LFI object" do
93
- expect(subject.vuln).to be_kind_of(Ronin::Vulns::LFI)
94
- end
95
-
96
- it "must set the #url attribute of the LFI vuln object" do
97
- expect(subject.vuln.url).to eq(subject.url)
98
- end
99
-
100
- it "must default the #os attribute of the LFI vuln object to :unix" do
101
- expect(subject.vuln.os).to be(:unix)
102
- end
103
-
104
- context "when the 'os' param is set" do
105
- let(:os) { :windows }
106
-
107
- subject do
108
- exploit_class.new(
109
- params: {
110
- base_url: base_url,
111
- os: os
112
- }
113
- )
114
- end
115
-
116
- it "must set the #os attribute of the LFI vuln object to the 'os' param" do
117
- expect(subject.vuln.os).to eq(os)
118
- end
119
- end
120
-
121
- it "must default the #depth attribute of the LFI vuln object to Ronin::Vulns::DEFAULT_DEPTH" do
122
- expect(subject.vuln.depth).to be(Ronin::Vulns::LFI::DEFAULT_DEPTH)
123
- end
124
-
125
- context "when the exploit class defines a custom depth" do
126
- module TestLFI
127
- class TestExploitWithDepth < Ronin::Exploits::LFI
128
- base_path '/Templatize.asp'
129
- query_param 'item'
130
- depth 10
131
- end
132
- end
133
-
134
- let(:exploit_class) { TestLFI::TestExploitWithDepth }
135
-
136
- it "must set the #depth attribute of the LFI vuln object to the exploit class'es depth" do
137
- expect(subject.vuln.depth).to eq(exploit_class.depth)
138
- end
139
- end
140
-
141
- it "must not set the #filter_bypass attribute of the LFI vuln object by default" do
142
- expect(subject.vuln.filter_bypass).to be(nil)
143
- end
144
-
145
- context "when the 'filter_bypass' param is set" do
146
- let(:filter_bypass) { :base64 }
147
-
148
- subject do
149
- exploit_class.new(
150
- params: {
151
- base_url: base_url,
152
- filter_bypass: filter_bypass
153
- }
154
- )
155
- end
156
-
157
- it "must set the #filter_bypass attribute of the LFI vuln object to the 'filter_bypass' param" do
158
- expect(subject.vuln.filter_bypass).to eq(filter_bypass)
159
- end
160
- end
161
- end
162
- end
@@ -1,131 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/loot/file'
3
-
4
- require 'tmpdir'
5
-
6
- describe Ronin::Exploits::Loot::File do
7
- let(:path) { 'test.txt' }
8
- let(:contents) { 'this is a test' }
9
-
10
- subject { described_class.new(path,contents) }
11
-
12
- describe "#initialize" do
13
- it "must set #path" do
14
- expect(subject.path).to eq(path)
15
- end
16
-
17
- it "must set #contents" do
18
- expect(subject.contents).to eq(contents)
19
- end
20
-
21
- it "must default #format to nil" do
22
- expect(subject.format).to be(nil)
23
- end
24
-
25
- context "when given the format: keyword argument" do
26
- let(:format) { :json }
27
-
28
- subject { described_class.new(path,contents, format: format) }
29
-
30
- it "must set #format" do
31
- expect(subject.format).to be(format)
32
- end
33
- end
34
- end
35
-
36
- describe "#to_s" do
37
- context "when #format is nil" do
38
- it "must return the #contents" do
39
- expect(subject.contents).to eq(contents)
40
- end
41
-
42
- context "when #contents is not a String" do
43
- let(:contents) { 42 }
44
-
45
- it "must call #to_s on #contents" do
46
- expect(subject.to_s).to eq(contents.to_s)
47
- end
48
- end
49
- end
50
-
51
- context "when #format is :json" do
52
- let(:contents) do
53
- [true, 42, 1.0, [], {}]
54
- end
55
- let(:format) { :json }
56
-
57
- subject { described_class.new(path,contents, format: format) }
58
-
59
- it "must convert #contents to pretty JSON" do
60
- expect(subject.to_s).to eq(JSON.pretty_generate(contents))
61
- end
62
- end
63
-
64
- context "when #format is :yaml" do
65
- let(:contents) do
66
- {foo: true, bar: {baz: 42}}
67
- end
68
- let(:format) { :yaml }
69
-
70
- subject { described_class.new(path,contents, format: format) }
71
-
72
- it "must convert #contents to YAML" do
73
- expect(subject.to_s).to eq(YAML.dump(contents))
74
- end
75
- end
76
-
77
- context "when #format is :csv" do
78
- let(:contents) do
79
- [
80
- %w[A B C ],
81
- %w[foo bar baz]
82
- ]
83
- end
84
- let(:format) { :csv }
85
-
86
- subject { described_class.new(path,contents, format: format) }
87
-
88
- it "must convert #contents to CSV" do
89
- expect(subject.to_s).to eq(
90
- contents.map(&:to_csv).join
91
- )
92
- end
93
- end
94
-
95
- context "when #format is an unknown value" do
96
- let(:format) { :foo }
97
-
98
- subject { described_class.new(path,contents, format: format) }
99
-
100
- it do
101
- expect {
102
- subject.to_s
103
- }.to raise_error(NotImplementedError,"unsupported loot format: #{format.inspect}")
104
- end
105
- end
106
- end
107
-
108
- describe "#save" do
109
- let(:output_dir) { Dir.mktmpdir('ronin-exploits-loot') }
110
-
111
- before { subject.save(output_dir) }
112
-
113
- it "must write the #contents to the #path within the output directory" do
114
- expect(File.read(File.join(output_dir,path))).to eq(contents)
115
- end
116
-
117
- context "when the path is a multi-directory relative path" do
118
- let(:path) { 'path/to/test.txt' }
119
-
120
- it "must create the parent directories" do
121
- parent_dir = File.dirname(File.join(output_dir,path))
122
-
123
- expect(File.directory?(parent_dir)).to be(true)
124
- end
125
-
126
- it "must write the #contents to the #path within the output directory" do
127
- expect(File.read(File.join(output_dir,path))).to eq(contents)
128
- end
129
- end
130
- end
131
- end
data/spec/loot_spec.rb DELETED
@@ -1,138 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/loot'
3
-
4
- require 'tmpdir'
5
-
6
- describe Ronin::Exploits::Loot do
7
- describe "#initialize" do
8
- it "must initialize the loot store to being empty" do
9
- expect(subject).to be_empty
10
- end
11
- end
12
-
13
- describe "#add" do
14
- let(:path) { 'test.txt' }
15
- let(:contents) { 'this is a set' }
16
-
17
- it "must add a File to the loot store with the given path and contents" do
18
- subject.add(path,contents)
19
-
20
- expect(subject[path]).to be_kind_of(described_class::File)
21
- expect(subject[path].contents).to eq(contents)
22
- end
23
-
24
- context "when the format: keyword argument is given" do
25
- let(:format) { :json }
26
-
27
- it "must set the #format of the loot file" do
28
- subject.add(path,contents, format: format)
29
-
30
- expect(subject[path]).to be_kind_of(described_class::File)
31
- expect(subject[path].format).to be(format)
32
- end
33
- end
34
- end
35
-
36
- describe "#[]" do
37
- context "when given a path of a previously added loot file" do
38
- let(:path) { 'test.txt' }
39
- let(:contents) { 'this is a set' }
40
-
41
- before { subject.add(path,contents) }
42
-
43
- it "must return the #{described_class}::File object for the given path" do
44
- expect(subject[path]).to be_kind_of(described_class::File)
45
- expect(subject[path].contents).to eq(contents)
46
- end
47
- end
48
-
49
- context "when the given path does not map to a loot file in the loot store" do
50
- let(:path) { 'foo' }
51
-
52
- it "must return nil" do
53
- expect(subject[path]).to be(nil)
54
- end
55
- end
56
- end
57
-
58
- describe "#each" do
59
- let(:path1) { 'test1.txt' }
60
- let(:contents1) { 'test 1' }
61
-
62
- let(:path2) { 'test2.txt' }
63
- let(:contents2) { 'test 2' }
64
-
65
- before do
66
- subject.add(path1,contents1)
67
- subject.add(path2,contents2)
68
- end
69
-
70
- context "when given a block" do
71
- it "must yield every #{described_class}::File in the loot store" do
72
- expect { |b|
73
- subject.each(&b)
74
- }.to yield_successive_args(subject[path1], subject[path2])
75
- end
76
- end
77
-
78
- context "when no block is given" do
79
- it "must return an Enumerator for #each" do
80
- expect(subject.each.to_a).to eq([subject[path1], subject[path2]])
81
- end
82
- end
83
- end
84
-
85
- describe "#empty?" do
86
- context "when the loot store contains loot files" do
87
- let(:path) { 'test.txt' }
88
- let(:contents) { 'this is a set' }
89
-
90
- before { subject.add(path,contents) }
91
-
92
- it "must return false" do
93
- expect(subject.empty?).to be(false)
94
- end
95
- end
96
-
97
- context "when the loot store does not contain loot files" do
98
- it "must return true" do
99
- expect(subject.empty?).to be(true)
100
- end
101
- end
102
- end
103
-
104
- describe "#save" do
105
- context "when the loot store contains loot files" do
106
- let(:path1) { 'test1.txt' }
107
- let(:contents1) { 'test 1' }
108
-
109
- let(:path2) { 'test2.txt' }
110
- let(:contents2) { 'test 2' }
111
-
112
- let(:output_dir) { Dir.mktmpdir('ronin-exploits-loot') }
113
-
114
- before do
115
- subject.add(path1,contents1)
116
- subject.add(path2,contents2)
117
- subject.save(output_dir)
118
- end
119
-
120
- it "must save each loot file into the output directory" do
121
- expect(File.read(File.join(output_dir,path1))).to eq(contents1)
122
- expect(File.read(File.join(output_dir,path2))).to eq(contents2)
123
- end
124
- end
125
-
126
- context "when the loot store is empty" do
127
- let(:output_dir) do
128
- File.join(Dir.mktmpdir('ronin-exploits-loot'),'new_dir')
129
- end
130
-
131
- before { subject.save(output_dir) }
132
-
133
- it "must still create the output directory" do
134
- expect(File.directory?(output_dir)).to be(true)
135
- end
136
- end
137
- end
138
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/memory_corruption'
3
-
4
- describe Ronin::Exploits::MemoryCorruption do
5
- it "must inherit from Ronin::Exploits::Exploit" do
6
- expect(described_class).to be < Ronin::Exploits::Exploit
7
- end
8
-
9
- it "must include Ronin::Exploits::Metadata::Arch" do
10
- expect(described_class).to include(Ronin::Exploits::Metadata::Arch)
11
- end
12
-
13
- it "must include Ronin::Exploits::Metadata::OS" do
14
- expect(described_class).to include(Ronin::Exploits::Metadata::OS)
15
- end
16
-
17
- describe ".exploit_type" do
18
- subject { described_class }
19
-
20
- it { expect(subject.exploit_type).to eq(:memory_corruption) }
21
- end
22
- end
@@ -1,82 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/metadata/arch'
3
-
4
- describe Ronin::Exploits::Metadata::Arch do
5
- module TestMetadataArch
6
- class WithNoArchSet
7
- include Ronin::Exploits::Metadata::Arch
8
- end
9
-
10
- class WithArchSet
11
- include Ronin::Exploits::Metadata::Arch
12
-
13
- arch :x86_64
14
- end
15
-
16
- class InheritsItsArch < WithArchSet
17
- include Ronin::Exploits::Metadata::Arch
18
- end
19
-
20
- class OverridesItsInheritedArch < WithArchSet
21
- include Ronin::Exploits::Metadata::Arch
22
-
23
- arch :armbe
24
- end
25
- end
26
-
27
- describe ".arch" do
28
- subject { test_class }
29
-
30
- context "and when arch is not set in the class" do
31
- let(:test_class) { TestMetadataArch::WithNoArchSet }
32
-
33
- it "must default to nil" do
34
- expect(subject.arch).to be(nil)
35
- end
36
- end
37
-
38
- context "and when arch is set in the class" do
39
- let(:test_class) { TestMetadataArch::WithArchSet }
40
-
41
- it "must return the set arch" do
42
- expect(subject.arch).to eq(:x86_64)
43
- end
44
- end
45
-
46
- context "but when the arch was set in the superclass" do
47
- let(:test_class) { TestMetadataArch::InheritsItsArch }
48
-
49
- it "must return the arch set in the superclass" do
50
- expect(subject.arch).to eq(:x86_64)
51
- end
52
-
53
- context "but the arch is overridden in the sub-class" do
54
- let(:test_class) { TestMetadataArch::OverridesItsInheritedArch }
55
-
56
- it "must return the arch set in the sub-class" do
57
- expect(subject.arch).to eq(:armbe)
58
- end
59
- end
60
- end
61
- end
62
-
63
- describe "#arch" do
64
- subject { test_class.new }
65
-
66
- context "when the Exploit class has .arch set" do
67
- let(:test_class) { TestMetadataArch::WithArchSet }
68
-
69
- it "must return the Exploit class'es .arch" do
70
- expect(subject.arch).to eq(test_class.arch)
71
- end
72
- end
73
-
74
- context "when the Exploit class does not have .arch set" do
75
- let(:test_class) { TestMetadataArch::WithNoArchSet }
76
-
77
- it "must return nil" do
78
- expect(subject.arch).to be(nil)
79
- end
80
- end
81
- end
82
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/metadata/cookie_param'
3
-
4
- describe Ronin::Exploits::Metadata::CookieParam do
5
- describe ".cookie_param" do
6
- subject { test_class }
7
-
8
- context "and when cookie_param is not set in the class" do
9
- module TestMetadataCookieParam
10
- class WithNoCookieParamSet
11
- include Ronin::Exploits::Metadata::CookieParam
12
- end
13
- end
14
-
15
- let(:test_class) { TestMetadataCookieParam::WithNoCookieParamSet }
16
-
17
- it "must default to nil" do
18
- expect(subject.cookie_param).to be(nil)
19
- end
20
- end
21
-
22
- context "and when cookie_param is set in the class" do
23
- module TestMetadataCookieParam
24
- class WithCookieParamSet
25
- include Ronin::Exploits::Metadata::CookieParam
26
-
27
- cookie_param 'test'
28
- end
29
- end
30
-
31
- let(:test_class) { TestMetadataCookieParam::WithCookieParamSet }
32
-
33
- it "must return the set cookie_param" do
34
- expect(subject.cookie_param).to eq("test")
35
- end
36
- end
37
-
38
- context "but when the cookie_param was set in the superclass" do
39
- module TestMetadataCookieParam
40
- class InheritsItsCookieParam < WithCookieParamSet
41
- end
42
- end
43
-
44
- let(:test_class) { TestMetadataCookieParam::InheritsItsCookieParam }
45
-
46
- it "must return the cookie_param set in the superclass" do
47
- expect(subject.cookie_param).to eq("test")
48
- end
49
-
50
- context "but the cookie_param is overridden in the sub-class" do
51
- module TestMetadataCookieParam
52
- class OverridesItsInheritedCookieParam < WithCookieParamSet
53
- cookie_param "test2"
54
- end
55
- end
56
-
57
- let(:test_class) do
58
- TestMetadataCookieParam::OverridesItsInheritedCookieParam
59
- end
60
-
61
- it "must return the cookie_param set in the sub-class" do
62
- expect(subject.cookie_param).to eq("test2")
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,62 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/exploits/metadata/default_filename'
3
-
4
- describe Ronin::Exploits::Metadata::DefaultFilename do
5
- module TestMetadataDefaultFilename
6
- class WithNoDefaultFilenameSet
7
- include Ronin::Exploits::Metadata::DefaultFilename
8
- end
9
-
10
- class WithDefaultFilenameSet
11
- include Ronin::Exploits::Metadata::DefaultFilename
12
-
13
- default_filename 'exploit.docx'
14
- end
15
-
16
- class InheritsItsDefaultFilename < WithDefaultFilenameSet
17
- include Ronin::Exploits::Metadata::DefaultFilename
18
- end
19
-
20
- class OverridesItsInheritedDefaultFilename < WithDefaultFilenameSet
21
- include Ronin::Exploits::Metadata::DefaultFilename
22
-
23
- default_filename 'exploit2.docx'
24
- end
25
- end
26
-
27
- describe ".default_filename" do
28
- subject { test_class }
29
-
30
- context "and when default filename is not set in the class" do
31
- let(:test_class) { TestMetadataDefaultFilename::WithNoDefaultFilenameSet }
32
-
33
- it "must default to nil" do
34
- expect(subject.default_filename).to be(nil)
35
- end
36
- end
37
-
38
- context "and when default filename is set in the class" do
39
- let(:test_class) { TestMetadataDefaultFilename::WithDefaultFilenameSet }
40
-
41
- it "must return the set default_filename" do
42
- expect(subject.default_filename).to eq('exploit.docx')
43
- end
44
- end
45
-
46
- context "but when the default filename was set in the superclass" do
47
- let(:test_class) { TestMetadataDefaultFilename::InheritsItsDefaultFilename }
48
-
49
- it "must return the default filename set in the superclass" do
50
- expect(subject.default_filename).to eq('exploit.docx')
51
- end
52
-
53
- context "but the default filename is overridden in the sub-class" do
54
- let(:test_class) { TestMetadataDefaultFilename::OverridesItsInheritedDefaultFilename }
55
-
56
- it "must return the default filename set in the sub-class" do
57
- expect(subject.default_filename).to eq('exploit2.docx')
58
- end
59
- end
60
- end
61
- end
62
- end