change_manager 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +33 -0
  5. data/app/jobs/make_change.rb +9 -0
  6. data/app/mailers/change_manager/notification_mailer.rb +32 -0
  7. data/app/models/change_manager/change.rb +39 -0
  8. data/app/services/change_manager/manager.rb +43 -0
  9. data/app/views/change_manager/notification_mailer/construct_email.html.erb +20 -0
  10. data/config/change_types.yaml +71 -0
  11. data/db/migrate/20160420192850_create_change_manager_changes.rb +14 -0
  12. data/lib/change_manager/engine.rb +12 -0
  13. data/lib/change_manager/version.rb +3 -0
  14. data/lib/change_manager.rb +4 -0
  15. data/lib/tasks/change_manager_tasks.rake +4 -0
  16. data/lib/tasks/resque.rake +9 -0
  17. data/spec/factories/change_manager_changes.rb +11 -0
  18. data/spec/mailers/change_manager/notification_mailer_spec.rb +7 -0
  19. data/spec/models/change_manager/change_spec.rb +59 -0
  20. data/spec/services/change_manager/manager_spec.rb +79 -0
  21. data/spec/spec_helper.rb +18 -0
  22. data/spec/testapp/README.rdoc +28 -0
  23. data/spec/testapp/Rakefile +6 -0
  24. data/spec/testapp/app/assets/javascripts/application.js +13 -0
  25. data/spec/testapp/app/assets/stylesheets/application.css +13 -0
  26. data/spec/testapp/app/controllers/application_controller.rb +5 -0
  27. data/spec/testapp/app/helpers/application_helper.rb +2 -0
  28. data/spec/testapp/app/views/layouts/application.html.erb +14 -0
  29. data/spec/testapp/bin/bundle +3 -0
  30. data/spec/testapp/bin/rails +4 -0
  31. data/spec/testapp/bin/rake +4 -0
  32. data/spec/testapp/config/application.rb +28 -0
  33. data/spec/testapp/config/boot.rb +5 -0
  34. data/spec/testapp/config/database.yml +25 -0
  35. data/spec/testapp/config/environment.rb +5 -0
  36. data/spec/testapp/config/environments/development.rb +32 -0
  37. data/spec/testapp/config/environments/production.rb +80 -0
  38. data/spec/testapp/config/environments/test.rb +39 -0
  39. data/spec/testapp/config/initializers/backtrace_silencers.rb +7 -0
  40. data/spec/testapp/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/spec/testapp/config/initializers/inflections.rb +16 -0
  42. data/spec/testapp/config/initializers/mime_types.rb +5 -0
  43. data/spec/testapp/config/initializers/secret_token.rb +12 -0
  44. data/spec/testapp/config/initializers/session_store.rb +3 -0
  45. data/spec/testapp/config/initializers/wrap_parameters.rb +14 -0
  46. data/spec/testapp/config/locales/en.yml +23 -0
  47. data/spec/testapp/config/routes.rb +4 -0
  48. data/spec/testapp/config.ru +4 -0
  49. data/spec/testapp/db/development.sqlite3 +0 -0
  50. data/spec/testapp/db/schema.rb +27 -0
  51. data/spec/testapp/db/test.sqlite3 +0 -0
  52. data/spec/testapp/log/development.log +3740 -0
  53. data/spec/testapp/log/test.log +21241 -0
  54. data/spec/testapp/public/404.html +58 -0
  55. data/spec/testapp/public/422.html +58 -0
  56. data/spec/testapp/public/500.html +57 -0
  57. data/spec/testapp/public/favicon.ico +0 -0
  58. metadata +198 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed505bd1d903e923e9892dd686e0603bf242ffec
4
+ data.tar.gz: 9f31243477193f69e645c1fddaedc5a2caa96911
5
+ SHA512:
6
+ metadata.gz: 42acce9e36ad9d556187f9f71d14183ae1bc458c8ca142db0fdaf986b8d6f044ed6ccf4bf5cc83a24c98e28db45fbdb4c0846adfbc9cb31acbc33577f6afefb4
7
+ data.tar.gz: 46c7e0a4be5e7a6302482f108519c8f840224dbc057f18d867b7faa8ab83290b008e4716c623528ef688e27d7f963e92f1131d2e010ab44009fe2fcfe959469a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = ChangeManager
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'resque/tasks'
8
+ require 'rdoc/task'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'ChangeManager'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ APP_RAKEFILE = File.expand_path("../spec/testapp/Rakefile", __FILE__)
19
+ load 'rails/tasks/engine.rake'
20
+
21
+
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
25
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
26
+
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+
30
+ desc "Run all specs in spec directory (excluding plugin specs)"
31
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
32
+
33
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ class MakeChange
2
+ def self.queue
3
+ :change
4
+ end
5
+
6
+ def self.perform(change_id)
7
+ ChangeManager::Manager.notify(change_id)
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module ChangeManager
2
+ class NotificationMailer < ActionMailer::Base
3
+
4
+ def construct_email(changes)
5
+ @body = prepare_body(changes)
6
+ mail(
7
+ to: changes.first.target,
8
+ from: changes.first.owner,
9
+ subject: 'Updates from Scholar@UC',
10
+ )
11
+ end
12
+
13
+ def send_email(constructed_email)
14
+ constructed_email.deliver
15
+ end
16
+
17
+ def prepare_body(changes)
18
+ header = '<table><th><td>Change Owner</td><td>Change Context</td><td>Change</td><td>Time</td></th>'
19
+ body = ''
20
+ footer = '</table>'
21
+ changes.each do |change|
22
+ #may need a look up method from curate here
23
+ body += '<tr><td>' +
24
+ change.owner + '</td><td>' +
25
+ change.context + '</td><td>' +
26
+ change.change_type + '</td><td>' +
27
+ change.created_at.to_s + '</td></tr>'
28
+ end
29
+ content = header + body + footer
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require 'yaml'
2
+
3
+ module ChangeManager
4
+ class Change < ActiveRecord::Base
5
+ validates :change_type, :owner, :target, :context, presence: true
6
+
7
+ def self.new_change(owner, change_type, context, target, cancelled = false)
8
+ # needs a spec
9
+ # create object in db
10
+ # return object id
11
+ foo = self.create({
12
+ owner: owner,
13
+ change_type: change_type,
14
+ context: context,
15
+ target: target,
16
+ cancelled: cancelled
17
+ })
18
+ foo.id
19
+ end
20
+
21
+ def cancel
22
+ self.cancelled = true
23
+ self.save
24
+ end
25
+
26
+ def cancelled?
27
+ self.cancelled
28
+ end
29
+
30
+ def inverse_of?(possible_inverse_change)
31
+ is_inverse = false
32
+ @change_types ||= YAML.load_file(File.join(ChangeManager::Engine.root, 'config/change_types.yaml'))
33
+ if self.change_type == @change_types[possible_inverse_change.change_type]['inverse']
34
+ is_inverse = true
35
+ end
36
+ return is_inverse
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ module ChangeManager
2
+ class Manager
3
+ def self.queue_change(owner, change_type, context, target)
4
+ change_id = Change.new_change(owner, change_type, context, target)
5
+ Resque.enqueue(MakeChange, change_id)
6
+ # Resque.enqueue_in(
7
+ # 30.seconds,
8
+ # MakeChange,
9
+ # change_id
10
+ # )
11
+ end
12
+
13
+ def self.notify(change_id)
14
+ unless Change.find(change_id).cancelled?
15
+ change = Change.find(change_id)
16
+ similar_changes = group_similar_changes(change.owner, change.target)
17
+ mailer = ChangeManager::NotificationMailer
18
+ mailer.send_email(mailer.construct_email(similar_changes))
19
+ end
20
+ end
21
+
22
+ def self.group_similar_changes(owner, target)
23
+ similar_changes = Change.where(owner: owner, target: target, cancelled: false)
24
+ if similar_changes.length > 1
25
+ cancel_inverse_changes(similar_changes)
26
+ end
27
+ return similar_changes
28
+ end
29
+
30
+ def self.cancel_inverse_changes(similar_changes)
31
+ similar_changes.each do |change|
32
+ similar_changes.each do |next_change|
33
+ if change.inverse_of?(next_change)
34
+ change.cancel
35
+ next_change.cancel
36
+ similar_changes.delete_if { |change| change.cancelled? }
37
+ end
38
+ end
39
+ end
40
+ return similar_changes
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ <!-- mailer template here -->
2
+ <div>
3
+ Dear Scholar@UC User,
4
+ </div>
5
+ <br>
6
+ This email is to inform you that the following changes have been made to your account:
7
+ <br><br>
8
+ <%= @body.html_safe %>
9
+
10
+ Changes can include:
11
+ <br>
12
+ <ul>
13
+ <li>Being added/removed as another contributor's delegate</li>
14
+ <li>Being added/removed as an editor of a work</li>
15
+ <li>Being added/removed to a group</li>
16
+ </ul>
17
+
18
+
19
+ Thanks,
20
+ The Scholar@UC team
@@ -0,0 +1,71 @@
1
+ added_as_delegate:
2
+ print: added_as_delegate
3
+ inverse: removed_as_delegate
4
+ human_readable: Added as a delegate
5
+ removed_as_delegate:
6
+ print: removed_as_delegate
7
+ inverse: added_as_delegate
8
+ human_readable: Removed as a delegate
9
+ added_as_editor:
10
+ print: added_as_editor
11
+ inverse: removed_as_editor
12
+ human_readable: Added as an editor
13
+ removed_as_editor:
14
+ print: removed_as_editor
15
+ inverse: added_as_editor
16
+ human_readable: Removed as an editor
17
+ added_to_group:
18
+ print: added_to_group
19
+ inverse: removed_from_group
20
+ human_readable: Added to a group
21
+ removed_from_group:
22
+ print: removed_from_group
23
+ inverse: added_to_group
24
+ human_readable: Removed from a group
25
+
26
+ # added_as_delegate:
27
+ # - added_as_delegate
28
+ # - inverse: removed_as_delegate
29
+ # - Added as a delegate
30
+ # removed_as_delegate:
31
+ # - removed_as_delegate
32
+ # - inverse: added_as_delegate
33
+ # - Removed as a delegate
34
+ # added_as_editor:
35
+ # - added_as_editor
36
+ # - inverse: removed_as_editor
37
+ # - Added as an editor
38
+ # removed_as_editor:
39
+ # - removed_as_editor
40
+ # - inverse: added_as_editor
41
+ # - Removed as an editor
42
+ # added_to_group:
43
+ # - added_to_group
44
+ # - inverse: removed_from_group
45
+ # - Added to a group
46
+ # removed_from_group:
47
+ # - removed_from_group
48
+ # - inverse: added_to_group
49
+ # - Removed from a group
50
+
51
+
52
+
53
+
54
+ # - added_as_delegate
55
+ # - removed_as_delegate
56
+ # - added_as_editor
57
+ # - removed_as_editor
58
+ # - added_to_group
59
+ # - removed_from_group
60
+
61
+
62
+
63
+ # delegates:
64
+ # - added_as_delegate
65
+ # - removed_as_delegate
66
+ # editors:
67
+ # - added_as_editor
68
+ # - removed_as_delegate
69
+ # groups:
70
+ # - added_to_group
71
+ # - removed_from_group
@@ -0,0 +1,14 @@
1
+ class CreateChangeManageChanges < ActiveRecord::Migration
2
+ def change
3
+ create_table :change_manager_changes do |t|
4
+ t.string :change_type
5
+ t.boolean :change_cancelled
6
+ t.datetime :change_notified
7
+ t.string :change_owner
8
+ t.string :change_target
9
+ t.string :change_context
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module ChangeManager
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ChangeManager
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec, :fixture => false
7
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
8
+ g.assets false
9
+ g.helper false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module ChangeManager
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "change_manager/engine"
2
+
3
+ module ChangeManager
4
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :change_manager do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,9 @@
1
+ # Resque tasks
2
+ require 'resque/tasks'
3
+ require 'resque/scheduler/tasks'
4
+
5
+ # Rails.application.initialize!
6
+
7
+ namespace :resque do
8
+ task ":setup" => :environment
9
+ end
@@ -0,0 +1,11 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :change, :class => 'ChangeManager::Change' do
5
+ owner "email@test.com"
6
+ change_type "added_as_delegate"
7
+ context "1"
8
+ target "spec@test.com"
9
+ cancelled false
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ module ChangeManager
4
+ describe NotificationMailer do
5
+ pending "add some examples to (or delete) #{__FILE__}"
6
+ end
7
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ module ChangeManager
4
+ describe Change do
5
+
6
+ it 'has a valid factory' do
7
+ FactoryGirl.create(:change).should be_valid
8
+ end
9
+
10
+ it 'should have a change_owner' do
11
+ FactoryGirl.build(:change, owner: nil).should_not be_valid
12
+ end
13
+
14
+ it 'should have a change_target' do
15
+ FactoryGirl.build(:change, target: nil).should_not be_valid
16
+ end
17
+
18
+ it 'should have a change_type' do
19
+ FactoryGirl.build(:change, change_type: nil).should_not be_valid
20
+ end
21
+
22
+ it 'should be initialized as false' do
23
+ FactoryGirl.build(:change).cancelled.should be_false
24
+ end
25
+
26
+ # seperate describe blocks, wrap in context
27
+ context 'instance method' do
28
+ let(:cancelled_change) { FactoryGirl.build(:change, cancelled: true) }
29
+ let(:change) { FactoryGirl.build(:change) }
30
+ describe '#cancel' do
31
+ after { change.cancelled = false }
32
+ it 'should cancel a notification' do
33
+ change.cancel
34
+ change.cancelled.should be_true
35
+ end
36
+ end
37
+
38
+ describe '#cancelled?' do
39
+ it 'should return whether a notification is cancelled' do
40
+ change.cancelled.should be_false
41
+ cancelled_change.cancelled?.should be_true
42
+ end
43
+ end
44
+
45
+ describe '#inverse_of?' do
46
+ let(:inverse_change) { FactoryGirl.build(:change, change_type: 'removed_as_delegate')}
47
+ let(:noninverse_change) { FactoryGirl.build(:change, change_type: 'added_as_editor')}
48
+
49
+ it 'should accurately detect inverse changes' do
50
+ change.inverse_of?(inverse_change).should be_true
51
+ end
52
+
53
+ it 'should not detect non-inverse changes' do
54
+ change.inverse_of?(noninverse_change).should be_false
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ module ChangeManager
4
+ describe Manager do
5
+ describe '#queue_change' do
6
+ let(:queued_change) { Manager.queue_change('test', 'removed_as_delegate', 'work_id1', 'testemail@gmail.com') }
7
+ it 'should spawn a background worker' do
8
+ queued_change.should be_true
9
+ end
10
+ end
11
+ describe '#notify' do
12
+ let(:cancelled_change) { FactoryGirl.create(:change, cancelled: true)}
13
+ let(:change) { FactoryGirl.create(:change) }
14
+ it 'should do nothing if initial change is cancelled' do
15
+ Manager.notify(cancelled_change.id).should be_nil
16
+ end
17
+ it 'should execute if initial change isn\'t cancelled' do
18
+ Manager.notify(change.id).should_not be_nil
19
+ end
20
+ end
21
+ describe '#group_similar_changes:' do
22
+ let!(:initial_change) { Change.find(Change.new_change('owner', 'added_as_editor', 'work_id1', 'target'))}
23
+ let(:possible_similar_changes) { Manager.group_similar_changes(initial_change.owner, initial_change.target) }
24
+ # describe the different changes
25
+ # unrelated changes (owner and target aren't the same as initial - cancelled doesnt matter)
26
+ context 'unrelated changes' do
27
+ # same owner & target
28
+ let!(:related_change) { Change.find(Change.new_change('owner', 'added_as_delegate', 'work_id1', 'target')) }
29
+ # same owner, different target
30
+ let!(:so_change) { Change.find(Change.new_change('owner', 'added_to_group', 'work_id2', 'target2')) }
31
+ # different owner, same target
32
+ let!(:st_change) { Change.find(Change.new_change('owner1', 'added_to_group', 'work_id2', 'target')) }
33
+ # load everything into array, give length for comparison (there should only be 2: initial change and related_notification)
34
+
35
+ it 'should not be loaded into the array' do
36
+ expect(possible_similar_changes).to include(initial_change)
37
+ expect(possible_similar_changes).to include(related_change)
38
+ expect(possible_similar_changes).not_to include(so_change)
39
+ expect(possible_similar_changes).not_to include(st_change)
40
+ end
41
+ end
42
+
43
+ # cancelled related changes (owner and target are the same as initial - shouldn't be loaded into similar_changes)
44
+ context 'cancelled related changes' do
45
+ let!(:cancelled_change) { Change.find(Change.new_change('owner', 'added_to_group', 'work_id4', 'target')) }
46
+ let!(:noncancelled_change) { Change.find(Change.new_change('owner', 'added_as_delegate', 'work_id1', 'target')) }
47
+ before { cancelled_change.cancel }
48
+ it 'should not be loaded into the array' do
49
+ expect(possible_similar_changes).to include(initial_change)
50
+ expect(possible_similar_changes).to include(noncancelled_change)
51
+ expect(possible_similar_changes).not_to include(cancelled_change)
52
+ end
53
+ end
54
+ # non-cancelled (related) inverse changes (neither should be loaded into similar changes)
55
+ context 'inverse changes' do
56
+ let!(:initial_change) { Change.find(Change.new_change('owner', 'added_to_group', 'work_id1', 'target'))}
57
+ let!(:noninverse_change) { Change.find(Change.new_change('owner', 'added_to_group', 'work_id4', 'target')) }
58
+ let!(:first_inverse_change) { Change.find(Change.new_change('owner', 'added_as_delegate', 'work_id1', 'target')) }
59
+ let!(:next_inverse_change) { Change.find(Change.new_change('owner', 'removed_as_delegate', 'work_id1', 'target')) }
60
+ after {
61
+ first_inverse_change.cancelled = false
62
+ next_inverse_change.cancelled = false
63
+ }
64
+ it 'should not be loaded into the array' do
65
+ expect(possible_similar_changes).to include(initial_change)
66
+ expect(possible_similar_changes).to include(noninverse_change)
67
+ expect(possible_similar_changes).not_to include(first_inverse_change)
68
+ expect(possible_similar_changes).not_to include(next_inverse_change)
69
+ end
70
+ context 'with three or more inverse changes' do
71
+ let!(:third_inverse_change) { Change.find(Change.new_change('owner', 'added_as_delegate', 'work_id1', 'target')) }
72
+ it 'should only remove n - 1 changes' do
73
+ expect(possible_similar_changes).to include(third_inverse_change)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,18 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path("../testapp/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+ require 'factory_girl_rails'
7
+
8
+ Rails.backtrace_cleaner.remove_silencers!
9
+
10
+ # Load support files
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
12
+
13
+ RSpec.configure do |config|
14
+ config.mock_with :rspec
15
+ config.use_transactional_fixtures = true
16
+ config.infer_base_class_for_anonymous_controllers = false
17
+ config.order = "random"
18
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Testapp::Application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Testapp</title>
5
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ # Pick the frameworks you want:
4
+ require "active_record/railtie"
5
+ require "action_controller/railtie"
6
+ require "action_mailer/railtie"
7
+ require "sprockets/railtie"
8
+ # require "rails/test_unit/railtie"
9
+
10
+ Bundler.require(*Rails.groups)
11
+ require "change_manager"
12
+
13
+ module Testapp
14
+ class Application < Rails::Application
15
+ # Settings in config/environments/* take precedence over those specified here.
16
+ # Application configuration should go into files in config/initializers
17
+ # -- all .rb files in that directory are automatically loaded.
18
+
19
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
20
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
21
+ # config.time_zone = 'Central Time (US & Canada)'
22
+
23
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
24
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
25
+ # config.i18n.default_locale = :de
26
+ end
27
+ end
28
+