worth_saving 0.0.9
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 +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +90 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/worth_saving/application.js +15 -0
- data/app/assets/stylesheets/worth_saving/application.css +13 -0
- data/app/controllers/worth_saving/application_controller.rb +4 -0
- data/app/controllers/worth_saving/drafts_controller.rb +51 -0
- data/app/helpers/worth_saving/application_helper.rb +4 -0
- data/app/models/worth_saving/draft.rb +47 -0
- data/app/views/layouts/worth_saving/application.html.erb +14 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20130911055236_create_worth_saving_drafts.rb +16 -0
- data/lib/tasks/worth_saving_tasks.rake +4 -0
- data/lib/worth_saving.rb +12 -0
- data/lib/worth_saving/action_view_ext.rb +11 -0
- data/lib/worth_saving/active_record_ext.rb +39 -0
- data/lib/worth_saving/engine.rb +15 -0
- data/lib/worth_saving/form.rb +15 -0
- data/lib/worth_saving/form/base.rb +21 -0
- data/lib/worth_saving/form/record.rb +53 -0
- data/lib/worth_saving/form/rendering.rb +100 -0
- data/lib/worth_saving/form_builder.rb +57 -0
- data/lib/worth_saving/info.rb +102 -0
- data/lib/worth_saving/version.rb +3 -0
- data/spec/app/controllers/drafts_controller_spec.rb +13 -0
- data/spec/app/models/worth_saving/draft_spec.rb +156 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +24 -0
- data/spec/dummy/app/controllers/login_controller.rb +11 -0
- data/spec/dummy/app/controllers/pages_controller.rb +48 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/page.rb +12 -0
- data/spec/dummy/app/models/subpage.rb +7 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/pages/form.html.slim +53 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +66 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20130911060226_create_worth_saving_drafts.worth_saving.rb +17 -0
- data/spec/dummy/db/migrate/20130912071319_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20130912071446_create_pages.rb +9 -0
- data/spec/dummy/db/migrate/20130912145831_create_subpages.rb +10 -0
- data/spec/dummy/db/migrate/20130913060709_add_columns_to_subpages.rb +5 -0
- data/spec/dummy/db/migrate/20130913060847_add_columns_to_pages.rb +7 -0
- data/spec/dummy/db/schema.rb +52 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +17536 -0
- data/spec/dummy/log/test.log +76256 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/assets/CA6/7A0/sprockets%2Ff6723fb0918cb134f62480f155a0b364 +0 -0
- data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/CF8/AF0/sprockets%2F228f63c526665cc53d670799eece3b98 +0 -0
- data/spec/dummy/tmp/cache/assets/D09/190/sprockets%2F993fae97313ed7d42322c85e60b02bb1 +0 -0
- data/spec/dummy/tmp/cache/assets/D1C/CE0/sprockets%2F9a5f4484900982bd33f792ca06e7f5ea +0 -0
- data/spec/dummy/tmp/cache/assets/D31/620/sprockets%2F01f101ae68348ed1bb4e46d7f452a73a +0 -0
- data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/D3C/300/sprockets%2Ffb893496ed88af814fa985858f60ee66 +0 -0
- data/spec/dummy/tmp/cache/assets/D43/EB0/sprockets%2F43d74a38cb4f14de5087ea7f871ac166 +0 -0
- data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/D97/C50/sprockets%2F74b5c193fc06fb3cb3c4ac12ac7589a7 +0 -0
- data/spec/dummy/tmp/cache/assets/D9E/470/sprockets%2F36bde6f05aa955c51ab2cd97b59e742a +0 -0
- data/spec/dummy/tmp/cache/assets/DCF/000/sprockets%2Fcfbeb9f4e8b3b7d1ac752d93c64017d3 +0 -0
- data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/01f101ae68348ed1bb4e46d7f452a73a +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/228f63c526665cc53d670799eece3b98 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/36bde6f05aa955c51ab2cd97b59e742a +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/43d74a38cb4f14de5087ea7f871ac166 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/74b5c193fc06fb3cb3c4ac12ac7589a7 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/993fae97313ed7d42322c85e60b02bb1 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/9a5f4484900982bd33f792ca06e7f5ea +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cfbeb9f4e8b3b7d1ac752d93c64017d3 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f6723fb0918cb134f62480f155a0b364 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/fb893496ed88af814fa985858f60ee66 +0 -0
- data/spec/factories.rb +28 -0
- data/spec/features/worth_saving_features_spec.rb +60 -0
- data/spec/lib/active_record_ext_spec.rb +291 -0
- data/spec/lib/info_spec.rb +29 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/features.rb +8 -0
- data/spec/support/features/helpers.rb +96 -0
- data/vendor/assets/javascripts/worth_saving.js +10 -0
- data/vendor/assets/javascripts/worth_saving/form.js +64 -0
- data/vendor/assets/stylesheets/worth_saving.css +18 -0
- metadata +424 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/404.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/422.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/500.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
+
</div>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/spec/factories.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
FactoryGirl.define do
|
|
4
|
+
factory :user do
|
|
5
|
+
name 'John Doe'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
factory :page do
|
|
9
|
+
user
|
|
10
|
+
title 'My Big Fat Greek Page'
|
|
11
|
+
content <<-EOS
|
|
12
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
|
|
13
|
+
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
|
|
14
|
+
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
|
|
15
|
+
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
|
16
|
+
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
17
|
+
EOS
|
|
18
|
+
approved false
|
|
19
|
+
page_type 'Front'
|
|
20
|
+
position 'Left'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
factory :subpage do
|
|
24
|
+
page
|
|
25
|
+
subtitle 'My Not-so-big Subtitle'
|
|
26
|
+
content 'This is some content that goes in here. Not a lot.'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature 'WorthSaving' do
|
|
4
|
+
let(:fred) { given_user 'Fred Flintstone' }
|
|
5
|
+
let(:barney) { given_user 'Barney Rubble' }
|
|
6
|
+
|
|
7
|
+
scenario "A user begins work on a new page and sees recovery option when refreshing the page", js: true do
|
|
8
|
+
login fred
|
|
9
|
+
visit new_page_path
|
|
10
|
+
within '.worth-saving-standard-form-container .worth-saving-form-container' do
|
|
11
|
+
fill_in_form
|
|
12
|
+
end
|
|
13
|
+
chill_out_long_enough_to_draft
|
|
14
|
+
visit current_path
|
|
15
|
+
within '.worth-saving-header-message' do
|
|
16
|
+
expect(page).to have_content "It appears you were working on a draft that didn't get saved"
|
|
17
|
+
end
|
|
18
|
+
within '.worth-saving-recovery-form-container #new_page' do
|
|
19
|
+
verify_blank_form
|
|
20
|
+
end
|
|
21
|
+
within '.worth-saving-recovery-form-container #recovered_new_page' do
|
|
22
|
+
verify_form({}, true)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
scenario "As a user I start work on a new page, refresh and see draft, but another user can't see it", js: true do
|
|
27
|
+
login fred
|
|
28
|
+
visit new_page_path
|
|
29
|
+
within '.worth-saving-standard-form-container .worth-saving-form-container' do
|
|
30
|
+
fill_in_form
|
|
31
|
+
end
|
|
32
|
+
chill_out_long_enough_to_draft
|
|
33
|
+
visit current_path
|
|
34
|
+
within '.worth-saving-header-message' do
|
|
35
|
+
expect(page).to have_content "It appears you were working on a draft that didn't get saved"
|
|
36
|
+
end
|
|
37
|
+
login barney
|
|
38
|
+
visit new_page_path
|
|
39
|
+
page.should_not have_css '.worth-saving-header-message'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
scenario "One user creates a page. Another edits that page, and drafts do not get saved because of methods in ApplicationController", js: true do
|
|
43
|
+
login fred
|
|
44
|
+
visit new_page_path
|
|
45
|
+
within '.worth-saving-standard-form-container .worth-saving-form-container' do
|
|
46
|
+
fill_in_form
|
|
47
|
+
end
|
|
48
|
+
click_on 'Create Page'
|
|
49
|
+
path = current_path
|
|
50
|
+
login barney
|
|
51
|
+
visit path
|
|
52
|
+
within '.worth-saving-standard-form-container .worth-saving-form-container' do
|
|
53
|
+
fill_in 'Content', with: "Here is some new content that I will not expect to see"
|
|
54
|
+
end
|
|
55
|
+
chill_out_long_enough_to_draft
|
|
56
|
+
within '.worth-saving-form-message.error' do
|
|
57
|
+
page.should have_content "Not authorized to draft this Page"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe WorthSaving::ActiveRecordExt do
|
|
4
|
+
before do
|
|
5
|
+
Rails.application.config.stub(:filter_parameters).and_return [:redacted_field]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
with_model :WorthSavingDraft do
|
|
9
|
+
table do |t|
|
|
10
|
+
t.integer :recordable_id
|
|
11
|
+
t.string :recordable_type
|
|
12
|
+
t.integer :scopeable_id
|
|
13
|
+
t.string :scopeable_type
|
|
14
|
+
t.text :form_data
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
model do
|
|
18
|
+
belongs_to :recordable, polymorphic: true
|
|
19
|
+
belongs_to :scopeable, polymorphic: true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
with_model :ImportantThing do
|
|
24
|
+
table do |t|
|
|
25
|
+
t.string :stuff
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
model do
|
|
29
|
+
is_worth_saving
|
|
30
|
+
if Rails.version.match /^3/
|
|
31
|
+
attr_accessible :stuff
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
with_model :AnyThing do
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
before do
|
|
40
|
+
if Rails.version.match /^3/
|
|
41
|
+
class WorthSaving::Draft
|
|
42
|
+
attr_accessible :recordable_id, :recordable_type, :scopeable_id, :scopeable_type, :form_data, :scopeable
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe 'subclass that is worth_saving' do
|
|
48
|
+
describe 'associations' do
|
|
49
|
+
let(:record) { ImportantThing.new }
|
|
50
|
+
let(:draft) { record.build_worth_saving_draft }
|
|
51
|
+
|
|
52
|
+
context 'when record is persisted' do
|
|
53
|
+
it 'has a worth_saving draft' do
|
|
54
|
+
record.save
|
|
55
|
+
draft.save
|
|
56
|
+
record.worth_saving_draft.should eq draft
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'when record is not persisted' do
|
|
61
|
+
it 'has a worth_saving draft' do
|
|
62
|
+
draft.save
|
|
63
|
+
record.worth_saving_draft.should eq draft
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe 'knowing it is worth_saving' do
|
|
69
|
+
subject { ImportantThing.worth_saving? }
|
|
70
|
+
|
|
71
|
+
it { should be_true }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe 'instance knowing it is worth_saving' do
|
|
75
|
+
subject { ImportantThing.new.worth_saving? }
|
|
76
|
+
|
|
77
|
+
it { should eq true }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe 'normal(not-worth_saving) subclass' do
|
|
82
|
+
describe 'knowing it is NOT worth_saving' do
|
|
83
|
+
subject { AnyThing.worth_saving? }
|
|
84
|
+
|
|
85
|
+
it { should eq false }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe 'instance knowing it is NOT worth_saving' do
|
|
89
|
+
subject { AnyThing.new.worth_saving? }
|
|
90
|
+
|
|
91
|
+
it { should eq false }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'worth_saving subclass with excepted fields' do
|
|
96
|
+
with_model :ImportantThingButUnimportantAuthor do
|
|
97
|
+
table do |t|
|
|
98
|
+
t.string :title
|
|
99
|
+
t.string :author
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
model do
|
|
103
|
+
is_worth_saving except: :author
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when field is NOT in the exceptions list' do
|
|
108
|
+
describe 'knowing the field is worth_saving' do
|
|
109
|
+
subject { ImportantThingButUnimportantAuthor.worth_saving? :title }
|
|
110
|
+
|
|
111
|
+
it { should eq true }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe 'having an instance that knows the field is worth_saving' do
|
|
115
|
+
subject { ImportantThingButUnimportantAuthor.new.worth_saving? :title }
|
|
116
|
+
|
|
117
|
+
it { should eq true }
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context 'when a field IS in the exceptions list' do
|
|
122
|
+
describe 'knowing the field is NOT worth_saving' do
|
|
123
|
+
subject { ImportantThingButUnimportantAuthor.worth_saving? :author }
|
|
124
|
+
|
|
125
|
+
it { should eq false }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe 'having an instance that knows the field is NOT worth_saving' do
|
|
129
|
+
subject { ImportantThingButUnimportantAuthor.new.worth_saving? :author }
|
|
130
|
+
|
|
131
|
+
it { should eq false }
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context 'when multiple fields are in the exceptions list (array argument)' do
|
|
136
|
+
with_model :ImportantThingWithUnimportantFields do
|
|
137
|
+
table do |t|
|
|
138
|
+
t.string :title
|
|
139
|
+
t.string :author
|
|
140
|
+
t.string :content
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
model do
|
|
144
|
+
is_worth_saving except: [:author, :title]
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
describe 'knowing which fields are and are NOT worth_saving' do
|
|
149
|
+
it 'should be able to tell the difference' do
|
|
150
|
+
ImportantThingWithUnimportantFields.worth_saving?(:author).should eq false
|
|
151
|
+
ImportantThingWithUnimportantFields.worth_saving?(:title).should eq false
|
|
152
|
+
ImportantThingWithUnimportantFields.worth_saving?(:content).should eq true
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'Rails.application.filter_params' do
|
|
156
|
+
it 'should not consider these fields worth_saving' do
|
|
157
|
+
ImportantThingWithUnimportantFields.worth_saving?(:redacted_field).should eq false
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
describe 'scope option' do
|
|
165
|
+
with_model :User do
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
with_model :ScopedThing do
|
|
169
|
+
table do |t|
|
|
170
|
+
t.belongs_to :user
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
model do
|
|
174
|
+
if Rails.version.match /^3/
|
|
175
|
+
attr_accessible :user
|
|
176
|
+
end
|
|
177
|
+
belongs_to :user
|
|
178
|
+
is_worth_saving scope: :user
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe '.worth_saving_scope' do
|
|
183
|
+
it 'returns scope given in options' do
|
|
184
|
+
ScopedThing.worth_saving_info.scope.should eq :user
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
describe '.worth_saving_info.scope' do
|
|
189
|
+
it 'returns scope given in options' do
|
|
190
|
+
ScopedThing.worth_saving_info.scope.should eq :user
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe '#worth_saving_draft' do
|
|
195
|
+
let(:user) { User.create }
|
|
196
|
+
let(:user2) { User.create }
|
|
197
|
+
let(:thing) { ScopedThing.new user: user }
|
|
198
|
+
|
|
199
|
+
context 'an unsaved ScopedThing' do
|
|
200
|
+
it 'finds the draft by scope' do
|
|
201
|
+
draft = WorthSaving::Draft.create recordable_type: 'ScopedThing', scopeable_id: user.id, scopeable_type: 'User'
|
|
202
|
+
thing.worth_saving_draft.should eq draft
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it 'does not find the draft belonging to the wrong scoped object' do
|
|
206
|
+
draft = WorthSaving::Draft.create recordable_type: 'ScopedThing', scopeable_id: user.id, scopeable_type: 'User'
|
|
207
|
+
thing = ScopedThing.new user: user2
|
|
208
|
+
thing.worth_saving_draft.should be_nil
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it 'does not find the draft belonging to the wrong recordable' do
|
|
212
|
+
draft = WorthSaving::Draft.create recordable_type: 'ImportantThing', scopeable_id: user.id, scopeable_type: 'User'
|
|
213
|
+
thing = ScopedThing.new user: user
|
|
214
|
+
thing.worth_saving_draft.should be_nil
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
context 'a saved Scopedthing' do
|
|
219
|
+
it 'finds the draft through the has_one association' do
|
|
220
|
+
thing.save
|
|
221
|
+
draft = WorthSaving::Draft.create recordable_id: thing.id, recordable_type: 'ScopedThing'
|
|
222
|
+
thing.reload
|
|
223
|
+
thing.worth_saving_draft.should eq draft
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
context "an unsaved unscoped thing" do
|
|
228
|
+
subject { ImportantThing.new }
|
|
229
|
+
let(:thing) { ImportantThing.new }
|
|
230
|
+
let(:draft) { thing.build_worth_saving_draft }
|
|
231
|
+
|
|
232
|
+
before do
|
|
233
|
+
draft.save
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
its(:worth_saving_draft) { should eq draft }
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe '#build_worth_saving_draft' do
|
|
241
|
+
let(:user) { User.create }
|
|
242
|
+
let(:thing) { ScopedThing.new user: user }
|
|
243
|
+
|
|
244
|
+
context 'an unsaved ScopedThing' do
|
|
245
|
+
subject { thing.build_worth_saving_draft }
|
|
246
|
+
|
|
247
|
+
its(:recordable_type) { should eq 'ScopedThing' }
|
|
248
|
+
its(:recordable_id) { should be_nil }
|
|
249
|
+
its(:scopeable) { should eq user }
|
|
250
|
+
|
|
251
|
+
describe 'disallowed attribute override' do
|
|
252
|
+
subject { thing.build_worth_saving_draft recordable_type: 'WrongClass', scopeable_id: 4444 }
|
|
253
|
+
|
|
254
|
+
its(:recordable_type) { should eq 'ScopedThing' }
|
|
255
|
+
its(:scopeable) { should eq user }
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
context 'an unsaved ScopedThing' do
|
|
260
|
+
let(:thing) { ScopedThing.create user: user }
|
|
261
|
+
subject { thing.build_worth_saving_draft form_data: 'some info' }
|
|
262
|
+
|
|
263
|
+
its(:recordable) { should eq thing }
|
|
264
|
+
its(:form_data) { should eq 'some info' }
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe 'destruction of worth_saving_draft during save' do
|
|
269
|
+
let(:thing) { ImportantThing.new stuff: 'Something' }
|
|
270
|
+
|
|
271
|
+
context 'new record' do
|
|
272
|
+
it 'happens after but not before' do
|
|
273
|
+
draft = thing.create_worth_saving_draft
|
|
274
|
+
WorthSaving::Draft.find(draft.id).should eq draft
|
|
275
|
+
thing.save
|
|
276
|
+
-> { WorthSaving::Draft.find(draft.id).should }.should raise_error ActiveRecord::RecordNotFound
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context 'persisted record' do
|
|
281
|
+
it 'happens after but not before' do
|
|
282
|
+
thing.save
|
|
283
|
+
draft = thing.create_worth_saving_draft
|
|
284
|
+
WorthSaving::Draft.find(draft.id).should eq draft
|
|
285
|
+
thing.update_attributes stuff: 'Changed something'
|
|
286
|
+
-> { WorthSaving::Draft.find(draft.id).should }.should raise_error ActiveRecord::RecordNotFound
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|