letter_opener_web 1.3.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/brakeman-analysis.yml +46 -0
  3. data/.github/workflows/main.yml +34 -0
  4. data/.github/workflows/release-gem.yml +32 -0
  5. data/.gitignore +1 -0
  6. data/.rspec +1 -1
  7. data/.rubocop.yml +5 -16
  8. data/.rubocop_todo.yml +19 -0
  9. data/CHANGELOG.md +22 -1
  10. data/Gemfile +4 -0
  11. data/LICENSE.txt +1 -1
  12. data/README.md +33 -24
  13. data/app/controllers/letter_opener_web/application_controller.rb +1 -0
  14. data/app/controllers/letter_opener_web/letters_controller.rb +14 -7
  15. data/app/models/letter_opener_web/letter.rb +37 -5
  16. data/app/views/layouts/letter_opener_web/_javascripts.html.erb +31 -0
  17. data/app/views/layouts/letter_opener_web/_styles.html.erb +3 -0
  18. data/{vendor/assets/javascripts/letter_opener_web/favcount.js → app/views/layouts/letter_opener_web/js/_favcount.html.erb} +9 -7
  19. data/app/views/layouts/letter_opener_web/js/_jquery.html.erb +7 -0
  20. data/app/views/layouts/letter_opener_web/letters.html.erb +5 -3
  21. data/app/views/layouts/letter_opener_web/styles/_bootstrap.html.erb +9 -0
  22. data/app/views/layouts/letter_opener_web/styles/_icon.html.erb +2 -0
  23. data/app/views/layouts/letter_opener_web/styles/_letters.html.erb +70 -0
  24. data/app/views/letter_opener_web/letters/_item.html.erb +10 -0
  25. data/app/views/letter_opener_web/letters/index.html.erb +11 -46
  26. data/config/routes.rb +5 -5
  27. data/letter_opener_web.gemspec +19 -15
  28. data/lib/letter_opener_web/delivery_method.rb +1 -1
  29. data/lib/letter_opener_web/engine.rb +0 -10
  30. data/lib/letter_opener_web/version.rb +1 -1
  31. data/lib/letter_opener_web.rb +1 -0
  32. data/spec/controllers/letter_opener_web/letters_controller_spec.rb +22 -11
  33. data/spec/dummy/app/assets/config/manifest.js +0 -2
  34. data/spec/dummy/app/assets/stylesheets/application.css +0 -16
  35. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  36. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  37. data/spec/dummy/app/controllers/application_controller.rb +0 -1
  38. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +2 -0
  39. data/spec/dummy/app/jobs/application_job.rb +9 -0
  40. data/spec/dummy/app/models/application_record.rb +5 -0
  41. data/spec/dummy/app/models/concerns/.keep +0 -0
  42. data/spec/dummy/app/views/layouts/application.html.erb +4 -7
  43. data/spec/dummy/bin/rails +2 -4
  44. data/spec/dummy/bin/rake +2 -4
  45. data/spec/dummy/bin/setup +7 -10
  46. data/spec/dummy/config/application.rb +21 -7
  47. data/spec/dummy/config/environments/development.rb +44 -6
  48. data/spec/dummy/config/environments/production.rb +51 -14
  49. data/spec/dummy/config/environments/test.rb +30 -6
  50. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
  51. data/spec/dummy/config/initializers/assets.rb +5 -5
  52. data/spec/dummy/config/initializers/backtrace_silencers.rb +5 -3
  53. data/spec/dummy/config/initializers/content_security_policy.rb +29 -0
  54. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  55. data/spec/dummy/config/initializers/permissions_policy.rb +12 -0
  56. data/spec/dummy/config/locales/en.yml +11 -1
  57. data/spec/dummy/config/puma.rb +18 -22
  58. data/spec/dummy/config/routes.rb +1 -4
  59. data/spec/dummy/config.ru +1 -0
  60. data/spec/dummy/public/404.html +6 -6
  61. data/spec/dummy/public/422.html +6 -6
  62. data/spec/dummy/public/500.html +6 -6
  63. data/spec/dummy/storage/.keep +0 -0
  64. data/spec/letter_opener_web_spec.rb +2 -2
  65. data/spec/models/letter_opener_web/letter_spec.rb +62 -17
  66. data/spec/spec_helper.rb +8 -0
  67. metadata +91 -54
  68. data/.travis.yml +0 -26
  69. data/app/assets/javascripts/letter_opener_web/application.js +0 -30
  70. data/app/assets/stylesheets/letter_opener_web/application.css.erb +0 -54
  71. data/bin/rails +0 -11
  72. data/spec/dummy/app/controllers/home_controller.rb +0 -10
  73. data/spec/dummy/app/mailers/contact_mailer.rb +0 -14
  74. data/spec/dummy/app/views/contact_mailer/new_message.html.erb +0 -21
  75. data/spec/dummy/app/views/contact_mailer/new_message.text.erb +0 -3
  76. data/spec/dummy/app/views/home/index.html.erb +0 -50
  77. data/spec/dummy/bin/bundle +0 -5
  78. data/spec/dummy/bin/update +0 -31
  79. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
  80. data/spec/dummy/config/initializers/session_store.rb +0 -5
  81. data/spec/dummy/config/secrets.yml +0 -22
  82. data/spec/dummy/config/spring.rb +0 -8
  83. data/vendor/assets/images/letter_opener_web/blue-dot.ico +0 -0
  84. data/vendor/assets/images/letter_opener_web/glyphicons-halflings-white.png +0 -0
  85. data/vendor/assets/images/letter_opener_web/glyphicons-halflings.png +0 -0
  86. data/vendor/assets/javascripts/letter_opener_web/bootstrap.min.js +0 -6
  87. data/vendor/assets/javascripts/letter_opener_web/jquery-1.8.3.min.js +0 -2
  88. data/vendor/assets/javascripts/letter_opener_web/jquery_ujs.js +0 -429
  89. data/vendor/assets/stylesheets/letter_opener_web/bootstrap.min.css +0 -9
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  # Be sure to restart your server when you modify this file.
3
3
 
4
- # ApplicationController.renderer.defaults.merge!(
5
- # http_host: 'example.org',
6
- # https: false
7
- # )
4
+ # ActiveSupport::Reloader.to_prepare do
5
+ # ApplicationController.renderer.defaults.merge!(
6
+ # http_host: 'example.org',
7
+ # https: false
8
+ # )
9
+ # end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  # Be sure to restart your server when you modify this file.
4
3
 
5
4
  # Version of your assets, change this if you want to expire all your assets.
6
- Rails.application.config.assets.version = '1.0'
5
+ # Rails.application.config.assets.version = '1.0'
7
6
 
8
- # Add additional assets to the asset load path
7
+ # Add additional assets to the asset load path.
9
8
  # Rails.application.config.assets.paths << Emoji.images_path
10
9
 
11
10
  # Precompile additional assets.
12
- # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
13
- # Rails.application.config.assets.precompile += %w( search.js )
11
+ # application.js, application.css, and all non-JS/CSS in the app/assets
12
+ # folder are already added.
13
+ # Rails.application.config.assets.precompile += %w( admin.js admin.css )
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Be sure to restart your server when you modify this file.
3
4
 
4
5
  # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
5
- # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
6
+ # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
6
7
 
7
- # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
8
- # Rails.backtrace_cleaner.remove_silencers!
8
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
9
+ # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
10
+ Rails.backtrace_cleaner.remove_silencers! if ENV['BACKTRACE']
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ # Be sure to restart your server when you modify this file.
3
+
4
+ # Define an application-wide content security policy
5
+ # For further information see the following documentation
6
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
7
+
8
+ # Rails.application.config.content_security_policy do |policy|
9
+ # policy.default_src :self, :https
10
+ # policy.font_src :self, :https, :data
11
+ # policy.img_src :self, :https, :data
12
+ # policy.object_src :none
13
+ # policy.script_src :self, :https
14
+ # policy.style_src :self, :https
15
+
16
+ # # Specify URI for violation reports
17
+ # # policy.report_uri "/csp-violation-report-endpoint"
18
+ # end
19
+
20
+ # If you are using UJS then enable automatic nonce generation
21
+ # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
22
+
23
+ # Set the nonce only to specific directives
24
+ # Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
25
+
26
+ # Report CSP violations to a specified URI
27
+ # For further information see the following documentation:
28
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
29
+ # Rails.application.config.content_security_policy_report_only = true
@@ -3,4 +3,6 @@
3
3
  # Be sure to restart your server when you modify this file.
4
4
 
5
5
  # Configure sensitive parameters which will be filtered from the log file.
6
- Rails.application.config.filter_parameters += [:password]
6
+ Rails.application.config.filter_parameters += %i[
7
+ passw secret token _key crypt salt certificate otp ssn
8
+ ]
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ # Define an application-wide HTTP permissions policy. For further
3
+ # information see https://developers.google.com/web/updates/2018/06/feature-policy
4
+ #
5
+ # Rails.application.config.permissions_policy do |f|
6
+ # f.camera :none
7
+ # f.gyroscope :none
8
+ # f.microphone :none
9
+ # f.usb :none
10
+ # f.fullscreen :self
11
+ # f.payment :self, "https://secure.example.com"
12
+ # end
@@ -16,8 +16,18 @@
16
16
  #
17
17
  # This would use the information in config/locales/es.yml.
18
18
  #
19
+ # The following keys must be escaped otherwise they will not be retrieved by
20
+ # the default I18n backend:
21
+ #
22
+ # true, false, on, off, yes, no
23
+ #
24
+ # Instead, surround them with single quotes.
25
+ #
26
+ # en:
27
+ # 'true': 'foo'
28
+ #
19
29
  # To learn more, please read the Rails Internationalization guide
20
- # available at http://guides.rubyonrails.org/i18n.html.
30
+ # available at https://guides.rubyonrails.org/i18n.html.
21
31
 
22
32
  en:
23
33
  hello: "Hello world"
@@ -1,24 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Puma can serve each request in a thread from an internal thread pool.
4
- # The `threads` method setting takes two numbers a minimum and maximum.
4
+ # The `threads` method setting takes two numbers: a minimum and maximum.
5
5
  # Any libraries that use thread pools should be configured to match
6
6
  # the maximum value specified for Puma. Default is set to 5 threads for minimum
7
- # and maximum, this matches the default thread size of Active Record.
7
+ # and maximum; this matches the default thread size of Active Record.
8
8
  #
9
- threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }.to_i
10
- threads threads_count, threads_count
9
+ max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
10
+ min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
11
+ threads min_threads_count, max_threads_count
11
12
 
12
- # Specifies the `port` that Puma will listen on to receive requests, default is 3000.
13
+ # Specifies the `worker_timeout` threshold that Puma will use to wait before
14
+ # terminating a worker in development environments.
13
15
  #
14
- port ENV.fetch('PORT') { 3000 }
16
+ worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'
17
+
18
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
19
+ #
20
+ port ENV.fetch('PORT', 3000)
15
21
 
16
22
  # Specifies the `environment` that Puma will run in.
17
23
  #
18
- environment ENV.fetch('RAILS_ENV') { 'development' }
24
+ environment ENV.fetch('RAILS_ENV', 'development')
25
+
26
+ # Specifies the `pidfile` that Puma will use.
27
+ pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
19
28
 
20
29
  # Specifies the number of `workers` to boot in clustered mode.
21
- # Workers are forked webserver processes. If using threads and workers together
30
+ # Workers are forked web server processes. If using threads and workers together
22
31
  # the concurrency of the application would be max `threads` * `workers`.
23
32
  # Workers do not work on JRuby or Windows (both of which do not support
24
33
  # processes).
@@ -28,22 +37,9 @@ environment ENV.fetch('RAILS_ENV') { 'development' }
28
37
  # Use the `preload_app!` method when specifying a `workers` number.
29
38
  # This directive tells Puma to first boot the application and load code
30
39
  # before forking the application. This takes advantage of Copy On Write
31
- # process behavior so workers use less memory. If you use this option
32
- # you need to make sure to reconnect any threads in the `on_worker_boot`
33
- # block.
40
+ # process behavior so workers use less memory.
34
41
  #
35
42
  # preload_app!
36
43
 
37
- # The code in the `on_worker_boot` will be called if you are using
38
- # clustered mode by specifying a number of `workers`. After each worker
39
- # process is booted this block will be run, if you are using `preload_app!`
40
- # option you will want to use this block to reconnect to any threads
41
- # or connections that may have been created at application boot, Ruby
42
- # cannot share connections between processes.
43
- #
44
- # on_worker_boot do
45
- # ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
46
- # end
47
-
48
44
  # Allow puma to be restarted by `rails restart` command.
49
45
  plugin :tmp_restart
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.routes.draw do
4
- mount LetterOpenerWeb::Engine => '/letter_opener'
5
-
6
- root to: 'home#index'
7
- post '/', to: 'home#create'
4
+ mount LetterOpenerWeb::Engine => '/letter_opener_web'
8
5
  end
data/spec/dummy/config.ru CHANGED
@@ -5,3 +5,4 @@
5
5
  require_relative 'config/environment'
6
6
 
7
7
  run Rails.application
8
+ Rails.application.load_server
@@ -4,7 +4,7 @@
4
4
  <title>The page you were looking for doesn't exist (404)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/404.html -->
59
59
  <div class="dialog">
60
60
  <div>
@@ -4,7 +4,7 @@
4
4
  <title>The change you wanted was rejected (422)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/422.html -->
59
59
  <div class="dialog">
60
60
  <div>
@@ -4,7 +4,7 @@
4
4
  <title>We're sorry, but something went wrong (500)</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <style>
7
- body {
7
+ .rails-default-error-page {
8
8
  background-color: #EFEFEF;
9
9
  color: #2E2F30;
10
10
  text-align: center;
@@ -12,13 +12,13 @@
12
12
  margin: 0;
13
13
  }
14
14
 
15
- div.dialog {
15
+ .rails-default-error-page div.dialog {
16
16
  width: 95%;
17
17
  max-width: 33em;
18
18
  margin: 4em auto 0;
19
19
  }
20
20
 
21
- div.dialog > div {
21
+ .rails-default-error-page div.dialog > div {
22
22
  border: 1px solid #CCC;
23
23
  border-right-color: #999;
24
24
  border-left-color: #999;
@@ -31,13 +31,13 @@
31
31
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
32
  }
33
33
 
34
- h1 {
34
+ .rails-default-error-page h1 {
35
35
  font-size: 100%;
36
36
  color: #730E15;
37
37
  line-height: 1.5em;
38
38
  }
39
39
 
40
- div.dialog > p {
40
+ .rails-default-error-page div.dialog > p {
41
41
  margin: 0 0 1em;
42
42
  padding: 1em;
43
43
  background-color: #F7F7F7;
@@ -54,7 +54,7 @@
54
54
  </style>
55
55
  </head>
56
56
 
57
- <body>
57
+ <body class="rails-default-error-page">
58
58
  <!-- This file lives in public/500.html -->
59
59
  <div class="dialog">
60
60
  <div>
File without changes
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require 'rails_helper'
4
4
 
5
- describe LetterOpenerWeb do
5
+ RSpec.describe LetterOpenerWeb do
6
6
  subject { described_class }
7
7
  after(:each) { described_class.reset! }
8
8
 
@@ -1,20 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- describe LetterOpenerWeb::Letter do
4
- let(:location) { File.expand_path('../../tmp', __dir__) }
3
+ RSpec.describe LetterOpenerWeb::Letter do
4
+ let(:location) { Pathname.new(__dir__).join('..', '..', 'tmp').cleanpath }
5
5
 
6
6
  def rich_text(mail_id)
7
- <<-MAIL
8
- Rich text for #{mail_id}
9
- <!DOCTYPE html>
10
- <a href='a-link.html'>
11
- <img src='an-image.jpg'>
12
- Link text
13
- </a>
14
- <a href='fooo.html'>Bar</a>
15
- <a href="example.html" class="blank"></a>
16
- <address><a href="inside-address.html">inside address</a></address>
17
- MAIL
7
+ <<~MAIL
8
+ Rich text for #{mail_id}
9
+ <!DOCTYPE html>
10
+ <body>
11
+ <div id="container">
12
+ <div id="message_headers">
13
+ <dl>
14
+ <dt>From:</dt>
15
+ <dd>noreply@example.com</dd>
16
+ </dl>
17
+ </div>
18
+
19
+ <a href='a-link.html'>
20
+ <img src='an-image.jpg'>
21
+ Link text
22
+ </a>
23
+ <a href='fooo.html'>Bar</a>
24
+ <a href="example.html" class="blank"></a>
25
+ <address><a href="inside-address.html">inside address</a></address>
26
+ </div>
27
+ </body>
28
+ MAIL
18
29
  end
19
30
 
20
31
  before :each do
@@ -36,6 +47,28 @@ MAIL
36
47
  FileUtils.rm_rf(location)
37
48
  end
38
49
 
50
+ describe 'rich text headers' do
51
+ let(:id) { '1111_1111' }
52
+ subject { described_class.new(id: id).headers }
53
+
54
+ before do
55
+ FileUtils.rm_rf("#{location}/#{id}/plain.html")
56
+ end
57
+
58
+ it { is_expected.to match(%r{<dl>\s*<dt>From:</dt>\s*<dd>noreply@example\.com</dd>}m) }
59
+ end
60
+
61
+ describe 'plain text headers' do
62
+ let(:id) { '1111_1111' }
63
+ subject { described_class.new(id: id).headers }
64
+
65
+ before do
66
+ FileUtils.rm_rf("#{location}/#{id}/rich.html")
67
+ end
68
+
69
+ it { is_expected.to eq('UNABLE TO PARSE HEADERS') }
70
+ end
71
+
39
72
  describe 'rich text version' do
40
73
  let(:id) { '1111_1111' }
41
74
  subject { described_class.new(id: id).rich_text }
@@ -45,9 +78,10 @@ MAIL
45
78
  it 'changes links to show up on a new window' do
46
79
  link_html = [
47
80
  "<a href='a-link.html' target='_blank'>",
48
- "<img src='an-image.jpg'/>",
49
- "Link text\n</a>"
50
- ].join("\n ")
81
+ " <img src='an-image.jpg'/>",
82
+ ' Link text',
83
+ '</a>'
84
+ ].join("\n ")
51
85
 
52
86
  expect(subject).to include(link_html)
53
87
  end
@@ -128,13 +162,24 @@ MAIL
128
162
 
129
163
  describe '#delete' do
130
164
  let(:id) { '1111_1111' }
165
+
131
166
  subject { described_class.new(id: id).delete }
132
167
 
133
- it'removes the letter with given id' do
168
+ it 'removes the letter with given id' do
134
169
  subject
135
170
  directories = Dir["#{location}/*"]
136
171
  expect(directories.count).to eql(1)
137
172
  expect(directories.first).not_to match(id)
138
173
  end
174
+
175
+ context 'when the id is outside of the letters base path' do
176
+ let(:id) { '../3333_3333' }
177
+
178
+ it 'does not remove the letter' do
179
+ expect(FileUtils).not_to receive(:rm_rf).with(location.join(id).cleanpath.to_s)
180
+
181
+ expect(subject).to be_nil
182
+ end
183
+ end
139
184
  end
140
185
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ if ENV.fetch('CI', '') == 'true'
7
+ require 'codecov'
8
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
9
+ end
10
+
3
11
  require 'shoulda-matchers'
4
12
 
5
13
  RSpec.configure do |config|