defra_ruby_features 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +8 -0
  3. data/README.md +92 -0
  4. data/Rakefile +40 -0
  5. data/app/controllers/defra_ruby_features/application_controller.rb +7 -0
  6. data/app/controllers/defra_ruby_features/feature_toggles_controller.rb +58 -0
  7. data/app/helpers/defra_ruby_features/application_helper.rb +6 -0
  8. data/app/helpers/delete_link_helper.rb +16 -0
  9. data/app/views/defra_ruby_features/feature_toggles/index.html.erb +48 -0
  10. data/app/views/defra_ruby_features/feature_toggles/new.html.erb +35 -0
  11. data/app/views/shared/_back.html.erb +1 -0
  12. data/config/locales/defra_ruby_features.en.yml +24 -0
  13. data/config/routes.rb +5 -0
  14. data/lib/defra_ruby_features.rb +26 -0
  15. data/lib/defra_ruby_features/configuration.rb +7 -0
  16. data/lib/defra_ruby_features/engine.rb +13 -0
  17. data/lib/defra_ruby_features/version.rb +5 -0
  18. data/lib/tasks/changelog.rake +8 -0
  19. data/spec/dummy/Rakefile +8 -0
  20. data/spec/dummy/app/assets/config/manifest.js +3 -0
  21. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  22. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  23. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  25. data/spec/dummy/app/controllers/test_controller.rb +7 -0
  26. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  27. data/spec/dummy/app/javascript/packs/application.js +14 -0
  28. data/spec/dummy/app/jobs/application_job.rb +9 -0
  29. data/spec/dummy/app/models/ability.rb +9 -0
  30. data/spec/dummy/app/models/application_record.rb +5 -0
  31. data/spec/dummy/app/models/feature_toggle.rb +4 -0
  32. data/spec/dummy/app/models/user.rb +8 -0
  33. data/spec/dummy/app/views/layouts/application.html.erb +12 -0
  34. data/spec/dummy/bin/rails +4 -0
  35. data/spec/dummy/bin/rake +4 -0
  36. data/spec/dummy/bin/setup +25 -0
  37. data/spec/dummy/config.ru +7 -0
  38. data/spec/dummy/config/application.rb +29 -0
  39. data/spec/dummy/config/boot.rb +7 -0
  40. data/spec/dummy/config/database.yml +21 -0
  41. data/spec/dummy/config/environment.rb +7 -0
  42. data/spec/dummy/config/environments/development.rb +50 -0
  43. data/spec/dummy/config/environments/test.rb +41 -0
  44. data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
  45. data/spec/dummy/config/initializers/assets.rb +14 -0
  46. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  47. data/spec/dummy/config/initializers/content_security_policy.rb +30 -0
  48. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  49. data/spec/dummy/config/initializers/defra_ruby_features.rb +7 -0
  50. data/spec/dummy/config/initializers/devise.rb +311 -0
  51. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  52. data/spec/dummy/config/initializers/inflections.rb +18 -0
  53. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
  55. data/spec/dummy/config/locales/devise.en.yml +65 -0
  56. data/spec/dummy/config/locales/en.yml +33 -0
  57. data/spec/dummy/config/routes.rb +7 -0
  58. data/spec/dummy/db/migrate/20200623125321_create_feature_toggles.rb +12 -0
  59. data/spec/dummy/db/migrate/20200624115316_devise_create_users.rb +44 -0
  60. data/spec/dummy/db/schema.rb +34 -0
  61. data/spec/dummy/db/test.sqlite3 +0 -0
  62. data/spec/dummy/log/test.log +4579 -0
  63. data/spec/dummy/public/404.html +67 -0
  64. data/spec/dummy/public/422.html +67 -0
  65. data/spec/dummy/public/500.html +66 -0
  66. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  67. data/spec/dummy/public/apple-touch-icon.png +0 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/tmp/development_secret.txt +1 -0
  70. data/spec/examples.txt +13 -0
  71. data/spec/factories/feature_toggle.rb +8 -0
  72. data/spec/factories/user.rb +11 -0
  73. data/spec/lib/defra_ruby_mocks/configuration_spec.rb +13 -0
  74. data/spec/rails_helper.rb +54 -0
  75. data/spec/requests/defra_ruby_features/feature_toggles_spec.rb +145 -0
  76. data/spec/spec_helper.rb +83 -0
  77. data/spec/support/database_cleaner.rb +19 -0
  78. data/spec/support/devise.rb +5 -0
  79. data/spec/support/factory_bot.rb +8 -0
  80. data/spec/support/migrations.rb +10 -0
  81. data/spec/support/pry.rb +7 -0
  82. data/spec/support/rails_controller_testing.rb +5 -0
  83. data/spec/support/simplecov.rb +17 -0
  84. metadata +364 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
File without changes
@@ -0,0 +1 @@
1
+ de870cf75d90cdd8a81e14e5329a5b0af0d9eaf6a392f671a2a3a83e3f63c3d08c4962352f24ba997bea47ae7a8486d0c6afec591d778eeaee8a439b18a37315
@@ -0,0 +1,13 @@
1
+ example_id | status | run_time |
2
+ -------------------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/lib/defra_ruby_mocks/configuration_spec.rb[1:1] | passed | 0.00129 seconds |
4
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:1:1:1] | passed | 0.0486 seconds |
5
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:1:2:1] | passed | 0.00757 seconds |
6
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:2:1:1] | passed | 0.0139 seconds |
7
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:2:2:1] | passed | 0.00885 seconds |
8
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:3:1:1] | passed | 0.01473 seconds |
9
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:3:2:1] | passed | 0.01439 seconds |
10
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:4:1:1] | passed | 0.01741 seconds |
11
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:4:2:1] | passed | 0.00694 seconds |
12
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:5:1:1] | passed | 0.0902 seconds |
13
+ ./spec/requests/defra_ruby_features/feature_toggles_spec.rb[1:5:2:1] | passed | 0.04146 seconds |
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :feature_toggle do
5
+ key { "test-feature" }
6
+ active { false }
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :user do
5
+ sequence :email do |n|
6
+ "user#{n}@example.com"
7
+ end
8
+
9
+ password { "Secret123" }
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ module DefraRubyFeatures
6
+ RSpec.describe Configuration do
7
+ let(:subject) { described_class.new }
8
+
9
+ it "sets the appropriate default config settings" do
10
+ expect(subject.feature_toggle_model_name).to be_nil
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
4
+ require "spec_helper"
5
+ ENV["RAILS_ENV"] ||= "test"
6
+ require File.expand_path("dummy/config/environment", __dir__)
7
+
8
+ # Prevent database truncation if the environment is production
9
+ abort("The Rails environment is running in production mode!") if Rails.env.production?
10
+ require "rspec/rails"
11
+ # Add additional requires below this line. Rails is not loaded until this point!
12
+
13
+ # Requires supporting ruby files with custom matchers and macros, etc, in
14
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
15
+ # run as spec files by default. This means that files in spec/support that end
16
+ # in _spec.rb will both be required and run as specs, causing the specs to be
17
+ # run twice. It is recommended that you do not name files matching this glob to
18
+ # end with _spec.rb. You can configure this pattern with the --pattern
19
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
20
+ #
21
+ # We make an exception for simplecov because that will already have been
22
+ # required and run at the very top of spec_helper.rb
23
+ support_files = Dir["./spec/support/**/*.rb"].reject { |file| file == "./spec/support/simplecov.rb" }
24
+ support_files.each { |f| require f }
25
+
26
+ RSpec.configure do |config|
27
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
28
+ # examples within a transaction, remove the following line or assign false
29
+ # instead of true.
30
+ config.use_transactional_fixtures = true
31
+
32
+ # You can uncomment this line to turn off ActiveRecord support entirely.
33
+ # config.use_active_record = false
34
+
35
+ # RSpec Rails can automatically mix in different behaviours to your tests
36
+ # based on their file location, for example enabling you to call `get` and
37
+ # `post` in specs under `spec/controllers`.
38
+ #
39
+ # You can disable this behaviour by removing the line below, and instead
40
+ # explicitly tag your specs with their type, e.g.:
41
+ #
42
+ # RSpec.describe UsersController, type: :controller do
43
+ # # ...
44
+ # end
45
+ #
46
+ # The different available types are documented in the features, such as in
47
+ # https://relishapp.com/rspec/rspec-rails/docs
48
+ config.infer_spec_type_from_file_location!
49
+
50
+ # Filter lines from Rails gems in backtraces.
51
+ config.filter_rails_from_backtrace!
52
+ # arbitrary gems may also be filtered via:
53
+ # config.filter_gems_from_backtrace("gem name")
54
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ module DefraRubyFeatures
6
+ RSpec.describe "FeatureToggle", type: :request do
7
+ let(:user) { create(:user) }
8
+
9
+ context "GET /feature-toggles" do
10
+ context "when a user is authenticated" do
11
+ before(:each) do
12
+ sign_in(user)
13
+ end
14
+
15
+ it "returns a list of available feature toggles" do
16
+ key = "a_feature_toggle"
17
+ create(:feature_toggle, key: key)
18
+
19
+ get "/feature-toggles"
20
+
21
+ expect(response.body).to include(key)
22
+ expect(response).to have_http_status(200)
23
+ expect(response).to render_template(:index)
24
+ end
25
+ end
26
+
27
+ context "when there is no user authenticated" do
28
+ it "redirects away" do
29
+ get "/feature-toggles"
30
+
31
+ expect(response).to have_http_status(302)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "POST /feature-toggles" do
37
+ context "when a user is authenticated" do
38
+ before(:each) do
39
+ sign_in(user)
40
+ end
41
+
42
+ it "creates a new feature toggle with a given value and redirects to the index page" do
43
+ count = FeatureToggle.count
44
+
45
+ post "/feature-toggles", params: { feature_toggle: { key: "test", active: "1" } }
46
+
47
+ feature_toggle = FeatureToggle.last
48
+
49
+ expect(feature_toggle.key).to eq("test")
50
+ expect(feature_toggle).to be_active
51
+ expect(FeatureToggle.count).to eq(count + 1)
52
+ expect(response).to have_http_status(302)
53
+ expect(response).to redirect_to("/feature-toggles")
54
+ end
55
+ end
56
+
57
+ context "when there is no user authenticated" do
58
+ it "redirects away" do
59
+ post "/feature-toggles"
60
+
61
+ expect(response).to have_http_status(302)
62
+ end
63
+ end
64
+ end
65
+
66
+ context "PUT/PATCH /feature-toggles/:id" do
67
+ let(:feature_toggle) { create(:feature_toggle, active: false) }
68
+
69
+ context "when a user is authenticated" do
70
+ before(:each) do
71
+ sign_in(user)
72
+ end
73
+
74
+ it "updates a feature toggle with the given params and redirects to the index page" do
75
+ put "/feature-toggles/#{feature_toggle.id}", params: { feature_toggle: { active: "1" } }
76
+
77
+ feature_toggle.reload
78
+
79
+ expect(feature_toggle).to be_active
80
+ expect(response).to have_http_status(302)
81
+ expect(response).to redirect_to("/feature-toggles")
82
+ end
83
+ end
84
+
85
+ context "when there is no user authenticated" do
86
+ it "redirects away" do
87
+ put "/feature-toggles/#{feature_toggle.id}"
88
+
89
+ expect(response).to have_http_status(302)
90
+ end
91
+ end
92
+ end
93
+
94
+ context "GET /feature-toggles/new" do
95
+ context "when a user is authenticated" do
96
+ before(:each) do
97
+ sign_in(user)
98
+ end
99
+
100
+ it "renders a template to create a new feature toggle" do
101
+ get "/feature-toggles/new"
102
+
103
+ expect(response).to render_template(:new)
104
+ expect(response).to have_http_status(200)
105
+ end
106
+ end
107
+
108
+ context "when there is no user authenticated" do
109
+ it "redirects away" do
110
+ get "/feature-toggles/new"
111
+
112
+ expect(response).to have_http_status(302)
113
+ end
114
+ end
115
+ end
116
+
117
+ context "DELETE /feature-toggles/:id" do
118
+ let!(:feature_toggle) { create(:feature_toggle) }
119
+
120
+ context "when there is a user authenticated" do
121
+ before(:each) do
122
+ sign_in(user)
123
+ end
124
+
125
+ it "deletes a feature toggle and redirects to the index page" do
126
+ count = FeatureToggle.count
127
+
128
+ delete "/feature-toggles/#{feature_toggle.id}"
129
+
130
+ expect(FeatureToggle.count).to eq(count - 1)
131
+ expect(response).to have_http_status(302)
132
+ expect(response).to redirect_to("/feature-toggles")
133
+ end
134
+ end
135
+
136
+ context "when there is no user authenticated" do
137
+ it "redirects away" do
138
+ delete "/feature-toggles/#{feature_toggle.id}"
139
+
140
+ expect(response).to have_http_status(302)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end