Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[#582] Make .save work identically to ActiveRecord

* Calling .save on a content block will by default publish it now (it used to save a draft copy)
* Refactor tests to ensure create/create! work identically to ActiveRecord
* Add some custom matchers.

[#256] .publish now has consistent behavior.
* Changed the behavior of block.publish
* It will no longer save new records, but will return false and generate a deprecation warning.
* It will now only ever publish the latest draft, returning true if there was something to publish.
* Add additional coverage for publish/publish! on new blocks.
  • Loading branch information...
commit f1dd4ef39d090a9cc3e15d47cbaac17d7b208dd7 1 parent 2eb602f
@peakpg peakpg authored
Showing with 501 additions and 224 deletions.
  1. +8 −5 app/controllers/cms/content_block_controller.rb
  2. +1 −1  app/controllers/cms/pages_controller.rb
  3. +10 −6 app/models/cms/page.rb
  4. +14 −0 doc/release_notes.md
  5. +11 −0 features/content_blocks/manage_html_blocks.feature
  6. +15 −0 features/content_blocks/manage_pages.feature
  7. +18 −0 features/portlets/portlets.feature
  8. +23 −0 features/step_definitions/content_pages_steps.rb
  9. +3 −2 features/step_definitions/manage_content_blocks_steps.rb
  10. +26 −8 features/step_definitions/portlets_steps.rb
  11. +14 −0 features/support/capybara_rails_links.rb
  12. +3 −0  features/support/cms_api.rb
  13. +1 −1  lib/cms/behaviors/connecting.rb
  14. +44 −21 lib/cms/behaviors/publishing.rb
  15. +1 −10 lib/cms/behaviors/versioning.rb
  16. +0 −13 test/functional/cms/content_controller_test.rb
  17. +1 −13 test/functional/cms/html_blocks_controller_test.rb
  18. +9 −19 test/functional/cms/pages_controller_test.rb
  19. +10 −0 test/support/mini_test_matchers.rb
  20. +1 −1  test/unit/behaviors/publishable_test.rb
  21. +117 −0 test/unit/behaviors/publishing_mini_test.rb
  22. +1 −1  test/unit/behaviors/userstamping_test.rb
  23. +2 −2 test/unit/behaviors/versioning_test.rb
  24. +2 −2 test/unit/helpers/menu_helper_test.rb
  25. +32 −19 test/unit/lib/content_block_test.rb
  26. +1 −1  test/unit/models/connector_test.rb
  27. +5 −5 test/unit/models/html_block_test.rb
  28. +2 −2 test/unit/models/link_test.rb
  29. +89 −3 test/unit/models/page_mini_test.rb
  30. +37 −89 test/unit/models/page_test.rb
View
13 app/controllers/cms/content_block_controller.rb
@@ -175,13 +175,17 @@ def block_form
def build_block
- begin
- @block = model_class.new(params[model_form_name])
- ensure
- # Recover from an Exception thrown during binding of parameters to model class
+ if params[model_form_name]
+ defaults = {"publish_on_save" => false}
+ model_params = params[model_form_name]
+ model_params = defaults.merge(model_params)
+ @block = model_class.new(model_params)
+ logger.warn model_params
+ else
# Need to make sure @block exists for form helpers to correctly generate paths
@block = model_class.new unless @block
end
+
check_permissions
end
@@ -221,7 +225,6 @@ def after_update_on_error
end
-
# update related methods
def update_block
load_block
View
2  app/controllers/cms/pages_controller.rb
@@ -25,7 +25,7 @@ def show
def create
@page = Page.new(params[:page])
@page.section = @section
- if @page.save
+ if @page.save_draft
flash[:notice] = "Page was '#{@page.name}' created."
redirect_to @page
else
View
16 app/models/cms/page.rb
@@ -172,18 +172,21 @@ def copy_connectors(options={})
end
# Adds a Content block to this page.
+ #
# @param [ContentBlock] connectable The content block to be added
# @param [Symbol] container The container to add it in (default :main)
def add_content(connectable, container=:main)
transaction do
raise "Connectable is nil" unless connectable
raise "Container is required" if container.blank?
+ #should_publish = published? &&
+ # connectable.connected_page &&
+ # (connectable.class.publishable? ? connectable.published? : true)
+ should_publish = false
update_attributes(
:version_comment => "#{connectable} was added to the '#{container}' container",
- :publish_on_save => (
- published? &&
- connectable.connected_page &&
- (connectable.class.publishable? ? connectable.published? : true)))
+ :publish_on_save => should_publish
+ )
connectors.create(
:page_version => draft.version,
:connectable => connectable,
@@ -195,12 +198,13 @@ def add_content(connectable, container=:main)
# @deprecated
alias_method :create_connector, :add_content
+ # Moves a specific connector up or down within its container for a page.
def move_connector(connector, direction)
transaction do
raise "Connector is nil" unless connector
raise "Direction is nil" unless direction
orientation = direction[/_/] ? "#{direction.sub('_', ' the ')} of" : "#{direction} within"
- update_attributes(:version_comment => "#{connector.connectable} was moved #{orientation} the '#{connector.container}' container")
+ update_attributes(:version_comment => "#{connector.connectable} was moved #{orientation} the '#{connector.container}' container", :publish_on_save=>false)
connectors.for_page_version(draft.version).like(connector).first.send("move_#{direction}")
end
end
@@ -214,7 +218,7 @@ def move_connector(connector, direction)
def remove_connector(connector)
transaction do
raise "Connector is nil" unless connector
- update_attributes(:version_comment => "#{connector.connectable} was removed from the '#{connector.container}' container")
+ update_attributes(version_comment: "#{connector.connectable} was removed from the '#{connector.container}' container", publish_on_save: false)
#The logic of this is to go ahead and let the container get copied forward, then delete the new connector
if new_connector = connectors.for_page_version(draft.version).like(connector).first
View
14 doc/release_notes.md
@@ -5,6 +5,7 @@ This release includes the following features:
* User Interface Redesign
* True In Context Editing - Editors can directly edit Html content and page titles using CKEditor's inline capability.
+* Refined Content API
UI Redesign
----------
@@ -28,6 +29,19 @@ Users can now edit most HTML content directly in the page. Icons indicate the ar
1. Preview Page - Editors can now preview the page without a toolbar or editing controls.
1. Non-incontext Content - Not all content makes sense to be inline editable (for example portlets). For these content types, the previous move/remove/edit links now float in the upper right hand corner of the content block.
+Refined Content API
+-------------------
+
+1. .save now works identically between ActiveRecord and Content Blocks
+
+Previously, calling .save on a block would save a draft copy, rather then updating the record in place. This has been changed. To save a draft, you can do either:
+
+ @block.publish_on_save
+ @block.save
+ # or
+ @block.save_draft
+
+
Upgrading
--------
View
11 features/content_blocks/manage_html_blocks.feature
@@ -15,6 +15,17 @@ Feature: Manage Html Blocks
| Hello CMS |
| Include body? |
+ Scenario: Save but not publish a New Block
+ Given I request /cms/html_blocks/new
+ Then I should see a page titled "Add New Text"
+ When I fill in "Name" with "Hello World"
+ And I click on "Save"
+ Then I should see a page titled "Content Library / View Text"
+ And I should see the following content:
+ | draft |
+ | View Text 'Hello World' |
+ And the publish button should be enabled
+
Scenario: Publishing a New Block
Given I request /cms/html_blocks/new
Then I should see a page titled "Add New Text"
View
15 features/content_blocks/manage_pages.feature
@@ -0,0 +1,15 @@
+Feature: Manage Pages
+ As a content editor I should be able to create pages
+
+ Background:
+ Given I am logged in as a Content Editor
+
+ Scenario: Creating Page as unpublished
+ When I create a new page
+ Then that page should not be published
+
+ Scenario: Publishing a Page (which was unpublished)
+ When I create a new page
+ Then I publish that page
+ And that page should be published
+ And I should end up on that page
View
18 features/portlets/portlets.feature
@@ -91,6 +91,24 @@ Feature: Portlets
When I visit that page
Then I should see the CMS :forbidden page
+ Scenario: Portlet errors should not blow up the page
+ Given I am not logged in
+ And a portlet that throws an unexpected error exists
+ When I view that page
+ Then the page should show content but not the error
+
+# test "When portlets throw a generic error, the page should still render the other content." do
+# @page = create(:page, :section => root_section, :path => "/about", :name => "Test About", :template_file_name => "default.html.erb", :publish_on_save => true)
+# @portlet_render = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :template => '<p id="hi">hello</p>')
+# @portlet_raise_generic = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :code => 'raise')
+# reset(:page)
+#
+# get :show, :path => "about"
+#
+#
+# assert_select "#hi", "hello"
+#
+# end
Scenario: View Usages
Given portlet named "Hello World" has been added to a page
When I view that portlet
View
23 features/step_definitions/content_pages_steps.rb
@@ -186,3 +186,26 @@
assert page.has_content?(content)
end
+When /^I create a new page$/ do
+ visit '/cms/sections/1/pages/new'
+ fill_in "Name", with: "New Page"
+ fill_in "Path", with: "/new-page"
+ click_on 'Save'
+end
+
+Then /^that page should not be published$/ do
+ refute most_recently_created_page.published?, "The page should not be published."
+end
+
+Then /^I publish that page$/ do
+ visit most_recently_created_page.path
+ click_put_link "Publish"
+end
+
+Then /^that page should be published$/ do
+ assert most_recently_created_page.published?, "The page should be published."
+end
+
+Then /^I should end up on that page$/ do
+ should_see_a_page_titled(most_recently_created_page.title)
+end
View
5 features/step_definitions/manage_content_blocks_steps.rb
@@ -82,13 +82,14 @@ def register_content_type(type)
Given /^I have an Html block in draft mode$/ do
@block = create(:html_block, :content=>"Testing Modes")
- @block.update_attributes(:name => "Should be updated.")
- assert !@block.live?
+ @block.update_attributes(:name => "Should be updated.", :publish_on_save => false)
+ refute @block.live?, "Assumed: Block should not be published."
end
When /^I should see that block's content$/ do
assert page.has_content?(@block.content), "Expected to see #{@block.content} on the page."
end
+
When /^I should see it's draft mode$/ do
within(".block_published_status") do
assert page.has_content?('draft')
View
34 features/step_definitions/portlets_steps.rb
@@ -21,7 +21,7 @@
Given /^a page with a portlet that raises a Not Found exception exists$/ do
@last_page = create(:public_page)
- @raises_not_found = create(:portlet, :code => 'raise ActiveRecord::RecordNotFound', :template=>"I shouldn't be shown.'")
+ @raises_not_found = create(:portlet, :code => 'raise ActiveRecord::RecordNotFound', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_not_found)
@last_page.publish!
assert @last_page.published?
@@ -29,7 +29,7 @@
When /^a page with a portlet that raises an Access Denied exception exists$/ do
@last_page = create(:public_page)
- @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template=>"I shouldn't be shown.'")
+ @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_access_denied)
@last_page.publish!
assert @last_page.published?
@@ -37,7 +37,7 @@
When /^a page with a portlet that display "([^"]*)" exists$/ do |view|
@last_page = create(:public_page)
- portlet = create(:portlet, :template=>view)
+ portlet = create(:portlet, :template => view)
@last_page.add_content(portlet)
@last_page.publish!
assert @last_page.published?
@@ -45,9 +45,9 @@
When /^a page with a portlet that raises both a 404 and 403 error exists$/ do
@last_page = create(:public_page)
- @raises_not_found = create(:portlet, :code => 'raise ActiveRecord::RecordNotFound', :template=>"I shouldn't be shown.'")
+ @raises_not_found = create(:portlet, :code => 'raise ActiveRecord::RecordNotFound', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_not_found)
- @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template=>"I shouldn't be shown.'")
+ @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_access_denied)
@last_page.publish!
assert @last_page.published?
@@ -55,21 +55,32 @@
When /^a page with a portlet that raises both a 403 and any other error exists$/ do
@last_page = create(:public_page)
- @raises_not_found = create(:portlet, :code => 'raise "A Generic Error"', :template=>"I shouldn't be shown.'")
+ @raises_not_found = create(:portlet, :code => 'raise "A Generic Error"', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_not_found)
- @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template=>"I shouldn't be shown.'")
+ @raises_access_denied = create(:portlet, :code => 'raise Cms::Errors::AccessDenied', :template => "I shouldn't be shown.'")
@last_page.add_content(@raises_access_denied)
@last_page.publish!
assert @last_page.published?
end
+Given /^a portlet that throws an unexpected error exists$/ do
+ @page = create(:public_page)
+ @portlet_render = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :template => '<p id="hi">hello</p>')
+ @portlet_raise_generic = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :code => 'raise Exception')
+ @page.publish!
+end
Given /^there is a portlet that uses a helper$/ do
@page_path = "/with-helper"
@portlet = create(:portlet_with_helper, page_path: @page_path)
end
When /^I view that page$/ do
- visit @page_path
+ if (@page_path)
+ visit @page_path
+ else
+ visit most_recently_created_page.path
+ end
+
end
Then /^I should see the portlet helper rendered in the view$/ do
@@ -84,4 +95,11 @@
When /^a guest views that page$/ do
logout
visit @page_path
+end
+
+Then /^the page should show content but not the error$/ do
+ refute page.has_content?('Exception'), "Exception should not appear on the page"
+ refute page.has_content?('Error'), "The word 'Error' should not appear on the page"
+ assert page.has_content?('hello'), "Should see other content"
+ should_see_a_page_titled(most_recently_created_page.title)
end
View
14 features/support/capybara_rails_links.rb
@@ -0,0 +1,14 @@
+module Capybara
+ module RailsLinks
+
+ # Find a link that should be a PUT request and click it.
+ # Only works with RackTest driver, and works around the fact that Rails javascript PUT isn't updated by Javascript.
+ # @param [String] name_or_selector Same options as click_link(name_or_selector)
+ def click_put_link(name_or_selector)
+ link = find_link(name_or_selector)
+ page.driver.put link[:href]
+ end
+ end
+
+end
+World(Capybara::RailsLinks)
View
3  features/support/cms_api.rb
@@ -15,6 +15,9 @@ def logout
visit '/cms/logout'
end
+ def most_recently_created_page
+ Cms::Page.order("created_at DESC").first
+ end
end
end
World(Cms::WebApi)
View
2  lib/cms/behaviors/connecting.rb
@@ -105,7 +105,7 @@ def update_connected_pages
if p != updated_by_page
#This just creates a new version of the page
action = deleted? ? "Deleted" : "Edited"
- p.update_attributes(:version_comment => "#{self.class.name.demodulize} ##{id} was #{action}")
+ p.update_attributes(:version_comment => "#{self.class.name.demodulize} ##{id} was #{action}", :publish_on_save=>false)
#The previous step will copy over a connector pointing to the previous version of this connectable
#We need to change that to point at the new version of this connectable
View
65 lib/cms/behaviors/publishing.rb
@@ -21,9 +21,7 @@ def is_publishable(options={})
extend ClassMethods
include InstanceMethods
- attr_accessor :publish_on_save
attr_accessible :publish_on_save
-
after_save :publish_for_non_versioned
scope :published, :conditions => {:published => true}
@@ -44,6 +42,22 @@ def is_publishable(options={})
module ClassMethods
end
module InstanceMethods
+
+ # Whether or not this object will be published the next time '.save' is called.
+ # @return [Boolean] True unless explicitly set otherwise.
+ def publish_on_save
+ if @publish_on_save.nil?
+ @publish_on_save = true
+ end
+ @publish_on_save
+ end
+
+ # Set whether or not this object will be published next time '.save' is called.
+ # This status resets to true after calling '.save'
+ def publish_on_save=(publish)
+ @publish_on_save = publish
+ end
+
def publishable?
if self.class.connectable?
new_record? ? connect_to_page_id.blank? : connected_page_count < 1
@@ -60,34 +74,40 @@ def publish_for_non_versioned
end
end
end
-
+
+ def publish_if_needed
+ if publish_on_save
+ publish
+ else
+ self.publish_on_save = true
+ end
+ end
+
+ # Publishes the latest previously saved version of content as published. This will not create a new version,
+ # and will not persist changes made to a record.
+ #
+ # @return [Boolean] true if there was a draft record that was published, false otherwise.
def publish
publish!
- true
rescue Exception => e
logger.warn("Could not publish, #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}")
false
end
- # Force the publishing of this block.
- #
- # Warning: The behavior of calling the following on an existing block:
- # block.save_on_publish = true
- # block.save!
- #
- # Is different than calling:
- # block.publish!
- #
- # And it probably shouldn't be. Try to merge the 'else' with the 'Versioning#create_or_update' method to eliminate duplication.
- #
- # In addition, after_publish is NOT called if you do:
- # block.save_on_publish = true
- # block.save!
- # which will cause problems if blocks are updated via the method (like with the UI)
+ # Saves a draft copy of this content item. This will create a new record in the _versions table for this item, but
+ # will not update the existing published record.
+ def save_draft
+ self.publish_on_save = false
+ save
+ end
+
+ # Publishes the latest draft version of a block. See .publish for more documentation. Can throw errors if publishing failed for unexpected reasons.
+ # Note: Having separate .publish! and .publish methods is probably no longer necessary. In practice, only .publish is probably needed.
+ # @return [Boolean] true if the block had a draft that was published, false otherwise.
def publish!
+ did_publish = false
if new_record?
- self.publish_on_save = true
- save!
+ ActiveSupport::Deprecation.warn "Calling .publish! on a new record no longer saves the record. Call '.save' to persist and publish the record.", caller
else
# Do this for publishing existing blocks.
transaction do
@@ -115,6 +135,7 @@ def publish!
# Doing the SQL ourselves to avoid callbacks
self.class.unscoped.where(self.class.arel_table[self.class.primary_key].eq(id)).arel.update(quoted_attributes)
+ did_publish = true
end
else
connection.update(
@@ -123,11 +144,13 @@ def publish!
"WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
"#{self.class.name.demodulize} Publish"
)
+ did_publish = true
end
after_publish if respond_to?(:after_publish)
end
self.published = true
end
+ did_publish
end
def status
View
11 lib/cms/behaviors/versioning.rb
@@ -193,16 +193,6 @@ def default_version_comment
end
end
- def publish_if_needed
- #logger.debug { "#{self.class}#publish_if_needed. publish? = '#{!!@publish_on_save}'" }
-
- if @publish_on_save
- publish
- @publish_on_save = nil
- end
- end
-
-
#
#ActiveRecord 3.0.0 call chain
# ActiveRecord 3 now uses basic inheritence rather than alias_method_chain. The order in which ActiveRecord::Base
@@ -329,6 +319,7 @@ def revert_to_without_save(version, options)
self.after_revert(revert_to_version) if self.respond_to?(:after_revert)
self.version_comment = "Reverted to version #{version}"
+ self.publish_on_save = false
self
end
View
13 test/functional/cms/content_controller_test.rb
@@ -300,18 +300,5 @@ def test_cms_user_views_page_on_cms_site
assert_response :success
assert_select "title", "Test Page"
end
-
- test "When portlets throw a generic error, the page should still render the other content." do
- @page = create(:page, :section => root_section, :path => "/about", :name => "Test About", :template_file_name => "default.html.erb", :publish_on_save => true)
- @portlet_render = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :template => '<p id="hi">hello</p>')
- @portlet_raise_generic = DynamicPortlet.create!(:name => "Test", :connect_to_page_id => @page.id, :connect_to_container => "main", :code => 'raise')
- reset(:page)
-
- get :show, :path => "about"
-
-
- assert_select "#hi", "hello"
-
- end
end
end
View
14 test/functional/cms/html_blocks_controller_test.rb
@@ -72,18 +72,6 @@ def test_update
assert_equal "Html Block 'Test V2' was updated", flash[:notice]
end
- def test_publish
- @block.update_attributes(:content => "Something Different")
-
- assert !@block.live?
-
- put :publish, :id => @block.id
- reset(:block)
-
- assert_redirected_to @block
- assert @block.reload.live?
- end
-
def test_versions
get :versions, :id => @block.id
assert_response :success
@@ -91,7 +79,7 @@ def test_versions
end
def test_revert_to
- @block.update_attributes(:name => "Test V2")
+ @block.update_attributes(:name => "Test V2", :publish_on_save =>false)
reset(:block)
put :revert_to, :id => @block.id, :version => "1"
View
28 test/functional/cms/pages_controller_test.rb
@@ -45,20 +45,6 @@ def test_unhide
assert !@page.draft.hidden?
end
- def test_publish
- create_page
-
- assert !@page.published?
-
- put :publish, :id => @page.to_param
- reset(:page)
-
- assert @page.published?
- assert_equal "Page 'Test' was published", flash[:notice]
-
- assert_redirected_to @page.path
- end
-
def test_versions
create_page
@page.update_attributes(:name => "V2")
@@ -79,10 +65,7 @@ def test_version
end
def test_revert_to
- create_page
- @page.update_attributes(:name => "V2")
- @page.update_attributes(:name => "V3")
- reset(:page)
+ create_draft_page_with_multiple_edits
put :revert_to, :id => @page.to_param, :version => 1
reset(:page)
@@ -93,9 +76,16 @@ def test_revert_to
assert_equal 4, @page.draft.version
end
+ def create_draft_page_with_multiple_edits
+ create_page
+ @page.update_attributes(:name => "V2", :publish_on_save=>false)
+ @page.update_attributes(:name => "V3", :publish_on_save=>false)
+ reset(:page)
+ end
+
protected
def create_page
- @page = create(:page, :section => root_section, :name => "Test", :path => "test")
+ @page = create(:page, :section => root_section, :name => "Test", :path => "test", :publish_on_save=>false)
end
end
View
10 test/support/mini_test_matchers.rb
@@ -0,0 +1,10 @@
+require 'minitest/autorun'
+module MiniTest::Assertions
+ def assert_is_published(block)
+ assert block.published?, "Expected #{block} to be published."
+ klass = block.class
+ most_recent_entity = klass.find(block.id)
+ assert most_recent_entity.published?, "Expected most recent version '#{most_recent_entity}' to be published."
+ end
+end
+Cms::Behaviors::Publishing.infect_an_assertion :assert_is_published, :must_be_published, :only_one_argument
View
2  test/unit/behaviors/publishable_test.rb
@@ -45,7 +45,7 @@ def setup
test "#live? if there are draft versions" do
@object.name = "New Name"
- @object.save!
+ @object.save_draft
assert_equal false, @object.live?
assert_equal :draft, @object.status
View
117 test/unit/behaviors/publishing_mini_test.rb
@@ -0,0 +1,117 @@
+require "minitest_helper"
+
+describe 'Publishing' do
+ let (:block) do
+ b = Cms::HtmlBlock.create!(name: "Published Version")
+ b.publish!
+ b
+ end
+ let(:draft_block) { create(:html_block, publish_on_save: false)}
+ let(:invalid_params) { {} }
+ let(:valid_params) { {name: "Any Name"} }
+ describe '.publish_on_save' do
+ it "should be true for new objects" do
+ n = Cms::HtmlBlock.new
+ n.publish_on_save.must_equal true
+ end
+ end
+
+ describe '#create' do
+ it "should publish the content" do
+ block = Cms::HtmlBlock.create(valid_params)
+ block.must_be_published
+ end
+
+ it "should not save with invalid attributes" do
+ block = Cms::HtmlBlock.create(invalid_params)
+ block.persisted?.must_equal false
+ end
+ end
+
+ describe '#create!' do
+ it "should publish the content" do
+ b = Cms::HtmlBlock.create!(valid_params)
+ b.must_be_published
+ end
+
+ it "should throw an exception for invalid attributes" do
+ proc { Cms::HtmlBlock.create!(invalid_params) }.must_raise(ActiveRecord::RecordNotSaved)
+ end
+ end
+
+ describe '.publish' do
+ it "should not publish a new block" do
+ block = Cms::HtmlBlock.new(valid_params)
+ ActiveSupport::Deprecation.silence do
+ block.publish.must_equal false
+ end
+ block.persisted?.must_equal false
+ end
+
+ it "should publish a draft block, without creating a version" do
+ draft_block.publish.must_equal true
+ draft_block.must_be_published
+ draft_block.versions.size.must_equal 1
+ end
+
+ it "should return false if there was no draft copy to publish" do
+ block.publish.must_equal false
+ block.must_be_published
+ end
+
+ it "should not persist changes as a side effect" do
+ draft_block.name = "Another Name"
+ draft_block.publish
+ draft_block.changed?.must_equal true
+ draft_block.live_version.name.wont_equal "Another Name"
+ end
+ end
+
+ describe '.publish!' do
+ it "should not save new blocks." do
+ block = Cms::HtmlBlock.new(valid_params)
+ ActiveSupport::Deprecation.silence do
+ block.publish!.must_equal false
+ end
+ block.persisted?.must_equal false
+ end
+
+ describe "with an existing draft" do
+ it "should mark that draft as published" do
+ block = block_with_draft
+ block.publish!.must_equal true
+ block.versions.size.must_equal 2
+ block.must_be_published
+ end
+ end
+ end
+
+ describe '.save' do
+ it 'should save and publish the content' do
+ block.name = "Version 2"
+ block.save.must_equal true
+ find_latest_block.name.must_equal "Version 2"
+ find_latest_block.version.must_equal 2
+ end
+ end
+
+ describe '.save_draft' do
+ it "should save a draft of the content" do
+ block.name = "Draft Version"
+ block.save_draft
+ find_latest_block.name.must_equal "Published Version"
+ end
+ end
+
+ # Creates and returns a block with a single draft version.
+ def block_with_draft
+ block_with_draft = create(:html_block)
+ block_with_draft.update_attributes(name: "Draft Copy", publish_on_save: false)
+ block_with_draft.versions.size.must_equal 2
+ block_with_draft
+ end
+
+ def find_latest_block
+ Cms::HtmlBlock.find(block.id)
+ end
+end
View
2  test/unit/behaviors/userstamping_test.rb
@@ -19,7 +19,7 @@ def teardown
end
test "if no current user is false, then timestamp should be nil" do
- Cms::User.expects(:current).returns(false).twice
+ Cms::User.expects(:current).returns(false).at_least_once
block = Cms::HtmlBlock.create!(:name=>"A")
assert_nil block.created_by
assert_nil block.updated_by
View
4 test/unit/behaviors/versioning_test.rb
@@ -73,8 +73,8 @@ class ::Cms::SpecialBlock < ActiveRecord::Base
class HistoricalVersionsTest < ActiveSupport::TestCase
def setup
- @published_block = create(:html_block, :name => "Version 1", :publish_on_save => true)
- @published_block.update_attributes(:name => "Version 2")
+ @published_block = create(:html_block, :name => "Version 1")
+ @published_block.update_attributes(:name => "Version 2", :publish_on_save => false)
@published_block.reload
end
View
4 test/unit/helpers/menu_helper_test.rb
@@ -132,8 +132,8 @@ def test_render_menu_does_not_show_unpublished_pages
@page = create(:page, :section => @section, :name => "Overview", :path => "/test", :publish_on_save => true)
@draft_page = create(:page, :section => @section, :name => "Draft v1", :path => "/draft", :publish_on_save => true)
- @draft_page.update_attributes(:name => "Draft v2")
- @never_published = create(:page, :section => @section, :name => "Never Published", :path => "/never_published")
+ @draft_page.update_attributes(:name => "Draft v2", :publish_on_save => false)
+ @never_published = create(:page, :section => @section, :name => "Never Published", :path => "/never_published", :publish_on_save=>false)
expected = [
{:id => "cms_page_#{@page.id}", :name => "Overview", :url => "/test", :selected => true},
View
51 test/unit/lib/content_block_test.rb
@@ -2,7 +2,7 @@
class ContentBlockTest < ActiveSupport::TestCase
def setup
- @block = create(:html_block, :name => "Test")
+ @block = create(:html_block, :name => "Test", :publish_on_save => false)
end
def test_publishing
@@ -17,8 +17,8 @@ def test_publishing
assert @block.published?
- assert @block.update_attributes(:name => "Whatever")
-
+ assert @block.update_attributes(:name => "Whatever", :publish_on_save => false)
+
assert !@block.live?
@@ -38,7 +38,7 @@ def test_revision_comment_on_update
assert_equal 1, @block.version, "Block should keep itself at version 1"
assert_equal 1, @block.versions.size, "Should only have the one original version of the block"
assert_equal 'Created', @block.draft.version_comment
- assert result , "Update with same attributes should still return true"
+ assert result, "Update with same attributes should still return true"
end
def test_custom_revision_comment
@@ -46,7 +46,7 @@ def test_custom_revision_comment
assert_equal "Something Changed", @block.draft.version_comment
end
-
+
end
class SoftPublishingTest < ActiveSupport::TestCase
@@ -57,7 +57,7 @@ def setup
test "deleted? should return true for deleted records, false otherwise" do
assert_equal false, @block.deleted?
- @block.destroy
+ @block.destroy
assert_equal true, @block.deleted?
end
@@ -140,7 +140,7 @@ def setup
end
test "Getting a block as of a particular version shouldn't be considered a 'new record'." do
- @block.update_attributes(:name=>"Changed", :publish_on_save=>true)
+ @block.update_attributes(:name => "Changed", :publish_on_save => true)
@block.reload
@v1 = @block.as_of_version(1)
@@ -148,12 +148,12 @@ def setup
end
- test 'Calling publish_on_save should not be sufficent to publish the block'do
+ test 'Calling publish_on_save should not be sufficent to publish the block' do
@block.publish_on_save = true
@block.save
found = Cms::HtmlBlock.find(@block)
- assert_equal 1, found.version
+ assert_equal 1, found.version
end
test "Setting the 'publish' flag on a block, along with any other change, and saving it should mark that block as published." do
@@ -167,7 +167,7 @@ def setup
def test_edit
old_name = "Versioned Content Block"
- new_name = "New version of content block"
+ new_name = "New version of content block"
@block.publish!
@block.reload
assert_equal @block.draft.name, old_name
@@ -183,7 +183,7 @@ def test_edit
def test_revert
old_name = "Versioned Content Block"
- new_name = "New version of content block"
+ new_name = "New version of content block"
@block.publish!
@block.reload
assert_equal @block.draft.name, old_name
@@ -201,28 +201,41 @@ def test_revert
class VersionedContentBlockConnectedToAPageTest < ActiveSupport::TestCase
def setup
- @page = create(:page, :section => root_section)
+ @page = create(:page, :section => root_section, :publish_on_save => false)
@block = create(:html_block, :name => "Versioned Content Block")
@page.create_connector(@block, "main")
reset(:page, :block)
+
+
end
- def test_editing_connected_to_an_unpublished_page
- page_version_count = Cms::Page::Version.count
+ test "Adding a block to page" do
+ refute @page.published?, "The page should not be published yet."
assert_equal 2, @page.versions.size, "Should be two versions of the page"
- assert !@page.published?, "The page should not be published yet."
-
pages = Cms::Page.connected_to(:connectable => @block, :version => @block.version).all
assert_equal [@page], pages, "The block should be connected to page"
+ end
- assert @block.update_attributes(:name => "something different")
+ test "updating block should not skip_callbacks" do
+ assert @block.update_attributes(:name => "something different", :publish_on_save => false)
assert_equal false, @block.skip_callbacks
+ end
+
+ test "updating block should put page into draft mode" do
+ @block.update_attributes(:name => "something different", :publish_on_save => false)
+ reset(:page)
+ refute @page.published?, "Updating a block should put any connected pages into draft mode"
+ end
+
+ def test_editing_connected_to_an_unpublished_page
+ page_version_count = Cms::Page::Version.count
+
+ assert @block.update_attributes(:name => "something different", :publish_on_save => false)
assert_equal 2, @block.versions.size, "should be two versions of this block"
reset(:page)
- assert !@page.published?
assert_equal 3, @page.versions.size, "Should be three versions of the page."
assert_equal 3, @page.draft.version, "Draft version of page should be updated to v3 since its connected to the updated block."
assert_incremented page_version_count, Cms::Page::Version.count
@@ -266,7 +279,7 @@ def test_deleting_when_connected_to_page
class NonVersionedContentBlockConnectedToAPageTest < ActiveSupport::TestCase
def setup
- @page = create(:page, :section => root_section)
+ @page = create(:page, :section => root_section, :publish_on_save => false)
@block = create(:non_versioned_block, :name => "Non-Versioned Non-Publishable Content Block")
@page.create_connector(@block, "main")
reset(:page, :block)
View
2  test/unit/models/connector_test.rb
@@ -142,7 +142,7 @@ def test_connector_with_file_block_status
assert @file.live?
assert @page.connectors.last.live?
- @file.update_attributes(:name => "Something Else")
+ @file.update_attributes(:name => "Something Else", :publish_on_save => false)
@page.reload
assert !@file.live?
View
10 test/unit/models/html_block_test.rb
@@ -70,7 +70,7 @@ def test_reverting
v1.save
# Make a new version
- @html_block.update_attributes(:name => "Version Two")
+ @html_block.update_attributes(:name => "Version Two", :publish_on_save => false)
@v2_created_at = @html_block.versions.last.created_at
assert_equal "Version Two", @html_block.name
@@ -103,7 +103,7 @@ def test_reverting
def test_previous_version
@html_block = create(:html_block, :name => "V1")
- @html_block.update_attributes(:name => "V2")
+ @html_block.update_attributes(:name => "V2", :publish_on_save => false)
@version = @html_block.as_of_version 1
assert_equal Cms::HtmlBlock, @version.class
@@ -112,9 +112,9 @@ def test_previous_version
assert_equal @html_block.id, @version.id
# We can't freeze the version because we need to be able to load assocations
- assert !@version.frozen?
- assert !@version.live?
- assert !@html_block.live?
+ refute @version.frozen?
+ refute @version.live?
+ refute @html_block.live?
end
end
View
4 test/unit/models/link_test.rb
@@ -19,7 +19,7 @@ def test_create
test "#update increments the latest_version" do
@link.name = "New"
- @link.save!
+ @link.save_draft
@link.reload
assert_equal 1, @link.version
@@ -33,7 +33,7 @@ def test_create
end
test "updating makes it not live" do
- @link.update_attributes(:name => "New")
+ @link.update_attributes(:name => "New", :publish_on_save => false)
@link.reload
refute @link.live?
View
92 test/unit/models/page_mini_test.rb
@@ -1,11 +1,10 @@
require "minitest_helper"
describe Cms::Page do
+ let(:block) { create(:html_block, :name => "Hello, World!") }
+ let(:page) { create(:page) }
describe ".find_draft" do
-
- let(:page) { create(:page) }
-
it "should return the latest draft of the page" do
page.name = "Version 2"
page.save
@@ -15,4 +14,91 @@
found.name.must_equal page.name
end
end
+
+ describe '.move_connector' do
+ it "should not publish the page" do
+ page.add_content(block)
+ page.move_connector(first_connector_for(block), :up)
+
+ page.live_version.version.must_equal 1
+ end
+ end
+
+ describe '.remove_connector' do
+ it "should not publish the page" do
+ page.add_content(block)
+ page.remove_connector(first_connector_for(block))
+
+ page.live_version.version.must_equal 1
+ end
+ end
+
+ describe '.revert_to' do
+ it "should not publish the page" do
+ page.add_content(block)
+ page.revert_to 1
+
+ page.live_version.version.must_equal 1
+ end
+ end
+
+ describe 'revision comments' do
+ let(:page) { create(:page, :section => root_section, :name => "V1") }
+ it "should start with a 'Created' comment" do
+ page.live_version.version_comment.must_equal 'Created'
+ end
+
+ it "should not create a comment when no changes occurred during saving" do
+ page.save
+ page.live_version.version_comment.must_equal 'Created'
+ page.as_of_version(page.version).live_version.version_comment.must_equal 'Created'
+ end
+
+ it "should create update comment for draft" do
+ page.update_attributes(name: "V2", publish_on_save: false)
+ assert_equal 'Changed name', page.draft.version_comment
+ assert_equal 'Created', page.live_version.version_comment
+ end
+
+ it "should record when content is added to pages" do
+ page.create_connector(block, "main")
+ assert_equal "Html Block 'Hello, World!' was added to the 'main' container",
+ page.draft.version_comment
+ assert_equal 'Created', page.live_version.version_comment
+ assert_equal 2, page.draft.version
+ end
+
+ it "should record when content is moved up within pages" do
+ page.add_content(block)
+ page.add_content(create(:html_block, :name => "Another block"))
+
+ page.move_connector_down(first_connector_for(block))
+
+ assert_equal "Html Block 'Hello, World!' was moved down within the 'main' container",
+ page.draft.version_comment
+ assert_equal 'Created', page.live_version.version_comment
+ end
+
+ it "should record when content is removed from a page" do
+ page.add_content(block)
+ page.remove_connector(first_connector_for(block))
+ assert_equal "Html Block 'Hello, World!' was removed from the 'main' container",
+ page.draft.version_comment
+ assert_equal 'Created', page.live_version.version_comment
+ end
+
+ it "should record when a page is reverted" do
+ page.add_content(block)
+ page.revert_to(1)
+ assert_equal "Reverted to version 1",
+ page.reload.draft.version_comment
+ assert_equal 'Created', page.live_version.version_comment
+ assert_equal "Reverted to version 1", page.draft.version_comment
+ end
+
+ end
+
+ def first_connector_for(content)
+ page.connectors.for_page_version(page.draft.version).for_connectable(content).first
+ end
end
View
126 test/unit/models/page_test.rb
@@ -11,18 +11,16 @@ def test_creating_a_page_and_updating_the_attributes
@page = Cms::Page.new(
:name => "Test",
:path => "test",
- :section => root_section,
- :publish_on_save => true)
+ :section => root_section
+ )
assert @page.save
assert_path_is_unique
- @page.update_attributes(:name => "Test v2")
+ @page.update_attributes(name: "Test v2", publish_on_save: false)
page = Cms::Page.find_live_by_path("/test")
assert_equal "Test", page.name
-
assert_equal 1, page.version
-
end
test "Creating a page builds a section node" do
@@ -64,7 +62,7 @@ def setup
test "#latest_version is incremented when page#update occurs" do
@page.name = "New"
- @page.save!
+ @page.save_draft
@page.reload
assert_equal 1, @page.version
@@ -76,7 +74,7 @@ def setup
test "live? using latest version" do
assert @page.live?
- @page.update_attributes(:name => "New")
+ @page.update_attributes(:name => "New", :publish_on_save => false)
@page.reload
refute @page.live?
@@ -152,20 +150,22 @@ def test_creating_page_with_trailing_slash
assert_equal @page.path, "/slashed/loooong/path"
end
- def test_find_live_by_path
- @page = build(:page, :path => '/foo')
- assert_nil Cms::Page.find_live_by_path('/foo')
-
- @page.publish!
- reset(:page)
+ test "#find_live_by_path should find published page" do
+ @page = create(:page, :path => '/foo')
assert_equal @page, Cms::Page.find_live_by_path('/foo')
+ end
- @page.update_attributes(:path => '/bar')
+ test "#find_live_by_path should not find draft with given path" do
+ @page = create(:page, :path => '/foo')
+ @page.update_attributes(:path => '/bar', :publish_on_save => false)
assert_equal @page, Cms::Page.find_live_by_path('/foo')
assert_nil Cms::Page.find_live_by_path('/bar')
+ end
+
+ test "#find_live_by_path should not find draft with old path" do
+ @page = create(:page, :path => '/foo', :publish_on_save => false)
+ @page.update_attributes(:path => '/bar')
- @page.publish!
- reset(:page)
assert_nil Cms::Page.find_live_by_path('/foo')
assert_equal @page, Cms::Page.find_live_by_path('/bar')
end
@@ -181,17 +181,14 @@ def test_find_live_by_path
end
test "Find by live path should not located deleted blocks, even if they share paths with live ones" do
- @page = build(:page, :path => '/foo')
- @page.publish!
- reset(:page)
-
+ @page = create(:page, :path => '/foo')
@page.mark_as_deleted!
assert_nil Cms::Page.find_live_by_path('/foo')
@new_page = build(:page, :path => '/foo')
assert_nil Cms::Page.find_live_by_path('/foo')
- @new_page.publish!
+ @new_page.save!
reset(:new_page)
assert_equal @new_page, Cms::Page.find_live_by_path('/foo')
assert_not_equal @page, @new_page
@@ -207,62 +204,12 @@ def test_path_normalization
assert_equal "/foo/bar", page.path
end
- def test_revision_comments
- page = create(:page, :section => root_section, :name => "V1")
-
- assert_equal 'Created', page.live_version.version_comment
-
- assert page.reload.save
- assert_equal 'Created', page.reload.live_version.version_comment
- assert_equal page.live_version.version_comment,
- page.as_of_version(page.version).live_version.version_comment
-
- page.update_attributes(:name => "V2")
- assert_equal 'Changed name', page.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
-
- block = create(:html_block, :name => "Hello, World!")
- page.create_connector(block, "main")
- assert_equal "Html Block 'Hello, World!' was added to the 'main' container",
- page.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
- assert_equal 3, page.reload.draft.version
-
- page.create_connector(create(:html_block, :name => "Whatever"), "main")
- assert_equal 4, page.reload.draft.version
-
- page.move_connector_down(page.connectors.for_page_version(page.reload.draft.version).for_connectable(block).first)
- assert_equal "Html Block 'Hello, World!' was moved down within the 'main' container",
- page.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
-
- page.move_connector_up(page.connectors.for_page_version(page.reload.draft.version).for_connectable(block).first)
- assert_equal "Html Block 'Hello, World!' was moved up within the 'main' container",
- page.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
-
- page.remove_connector(page.connectors.for_page_version(page.reload.draft.version).for_connectable(block).first)
- assert_equal "Html Block 'Hello, World!' was removed from the 'main' container",
- page.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
-
- page.revert_to(1)
- assert_equal "Reverted to version 1",
- page.reload.draft.version_comment
- assert_equal 'Created', page.live_version.version_comment
-
- assert_equal "Created", page.as_of_version(1).current_version.version_comment
- assert_equal "Changed name", page.as_of_version(2).current_version.version_comment
- assert_equal "Reverted to version 1", page.draft.version_comment
-
- end
-
def test_container_live
page = create(:page)
- published = create(:html_block, :publish_on_save => true)
- unpublished = create(:html_block)
- page.create_connector(published, "main")
- page.create_connector(unpublished, "main")
+ published = create(:html_block)
+ unpublished = create(:html_block, publish_on_save: false)
+ page.add_content(published, "main")
+ page.add_content(unpublished, "main")
assert !page.container_published?("main")
assert unpublished.publish
assert page.container_published?("main")
@@ -302,17 +249,17 @@ def test_adding_a_block_to_a_page_puts_page_in_draft_mode
reset(:page, :block)
assert @page.published?
assert @block.published?
- @page.create_connector(@block, "main")
+ @page.add_content(@block, "main")
reset(:page, :block)
- assert !@page.live?
+ refute @page.live?, "Page should be unpublished after adding content"
end
def test_reverting_and_then_publishing_a_page
@page = create(:page, :section => root_section, :publish_on_save => true)
@block = create(:html_block,
- :connect_to_page_id => @page.id,
- :connect_to_container => "main")
+ :connect_to_page_id => @page.id,
+ :connect_to_container => "main")
@page.publish
reset(:page, :block)
@@ -366,7 +313,7 @@ def test_user_stamps_are_applied_to_versions
Cms::User.current = @new_guy
- page.update_attributes(:name => "Something Different")
+ page.update_attributes(:name => "Something Different", :publish_on_save => false)
assert_equal "Something Different", page.draft.name
assert_equal "Original Value", page.reload.name
@@ -407,7 +354,7 @@ def setup
end
test "#top_level_section works for page in root section" do
- page = create(:public_page, :parent=>root_section)
+ page = create(:public_page, :parent => root_section)
assert_equal root_section, page.top_level_section
end
@@ -441,7 +388,7 @@ def test_updating_the_page_with_changes
connector_count = Cms::Connector.count
page_version = @page.version
- @page.update_attributes(:name => "Foo")
+ @page.update_attributes(name: "Foo", publish_on_save: false)
assert_incremented connector_count, Cms::Connector.count
assert_equal page_version, @page.version
@@ -492,6 +439,7 @@ def setup
reset(:page, :block)
end
+
test "Adding a block to a page without publishing" do
assert_equal 1, @page.version, "The unpublished page should still be version 1"
assert_equal 2, @connector.page_version, "The connector should point to version 2 of the page"
@@ -672,8 +620,9 @@ def test_removing_and_reverting_to_version_with_both_connectors
end
def test_updating_one_of_the_blocks_and_reverting_to_version_before_the_update
+
target_version = @page.draft.version
- @foo_block.update_attributes!(:name => "Foo V2")
+ @foo_block.update_attributes!(:name => "Foo V2", :publish_on_save => false)
@page.reload
page_version = @page.draft.version
@@ -683,7 +632,7 @@ def test_updating_one_of_the_blocks_and_reverting_to_version_before_the_update
assert_incremented page_version, @page.draft.version
assert_incremented foo_block_version, @foo_block.draft.version
- assert_equal "Foo Block", @page.connectors.for_page_version(@page.draft.version).reload.first.connectable.name
+ assert_equal "Foo Block", @page.connectors.for_page_version(@page.draft.version).reload.first.connectable.name, "This might be correct now. When you revert"
end
protected
@@ -822,7 +771,6 @@ def test_publishing_the_page
class RevertingABlockThatIsOnMultiplePagesTest < ActiveSupport::TestCase
def test_that_it_reverts_both_pages
- Cms::Page.delete_all
# 1. Create a new page (Page 1, v1)
@page1 = create(:page, :name => "Page 1")
@@ -833,7 +781,7 @@ def test_that_it_reverts_both_pages
# 3. Add a new html block to Page 1. Save, don't publish. (Page 1, v2)
@block = create(:html_block, :name => "Block v1",
- :connect_to_page_id => @page1.id, :connect_to_container => "main")
+ :connect_to_page_id => @page1.id, :connect_to_container => "main")
reset(:page1, :page2, :block)
assert_equal 2, @page1.draft.version
assert_equal 1, @page2.draft.version
@@ -845,7 +793,7 @@ def test_that_it_reverts_both_pages
assert_equal 2, @page2.draft.version
# 5. Edit the block (Page 1, v3, Page 2, v3, Block v2)
- @block.update_attributes!(:name => "Block v2")
+ @block.update_attributes!(:name => "Block v2", :publish_on_save => false)
reset(:page1, :page2, :block)
assert_equal 3, @page1.draft.version
assert_equal 3, @page2.draft.version
@@ -885,7 +833,7 @@ def test_that_it_shows_the_correct_version_of_the_blocks_it_is_connected_to
assert_equal 1, @block.draft.version
# 4. Edit Block A (Page A v4, Block A v3)
- @block.update_attributes!(:name => "Block 2")
+ @block.update_attributes!(:name => "Block 2", :publish_on_save => false)
reset(:page, :block)
assert_equal 2, @page.version
assert_equal 3, @page.draft.version
@@ -917,4 +865,4 @@ def test_connectors_with_portlets_should_correctly_be_copied
assert @page.reload.connectors.for_page_version(@page.draft.version).empty?, "Verify that all connectors for the latest page are removed."
end
end
-end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.