From 416a5be0d8e0b350c0295fe56c210999915e6c0f Mon Sep 17 00:00:00 2001 From: AntonioTerceiro Date: Wed, 16 Jan 2008 22:50:12 +0000 Subject: [PATCH] ActionItem152: removed design plugin; adding a home-made block manager --- app/controllers/admin/admin_panel_controller.rb | 4 +++- app/controllers/admin/edit_template_controller.rb | 3 ++- app/controllers/application.rb | 9 ++++++++- app/controllers/box_organizer_controller.rb | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ app/controllers/my_profile/cms_controller.rb | 5 ++++- app/controllers/my_profile/profile_design_controller.rb | 14 ++++++++++++++ app/controllers/my_profile/profile_editor_controller.rb | 3 ++- app/controllers/public/account_controller.rb | 2 -- app/controllers/public/category_controller.rb | 4 +++- app/controllers/public/home_controller.rb | 2 -- app/helpers/application_helper.rb | 34 ++++++++++++++++++++-------------- app/helpers/boxes_helper.rb | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/models/block.rb | 13 +++++++++++++ app/models/box.rb | 5 +++++ app/models/environment.rb | 9 ++++++++- app/models/link_block.rb | 2 +- app/models/main_block.rb | 7 +++++++ app/models/profile.rb | 9 ++++++++- app/models/recent_documents_block.rb | 2 +- app/views/box_organizer/index.rhtml | 3 +++ app/views/box_organizer/move_block.rjs | 8 ++++++++ app/views/layouts/application.rhtml | 18 ++++++++++++++---- app/views/profile_design | 1 + config/environment.rb | 1 + db/migrate/001_add_design_support.rb | 19 +++++++++++-------- lib/acts_as_having_boxes.rb | 36 ++++++++++++++++++++++++++++++++++++ lib/needs_profile.rb | 4 +++- public/designs/icons/default/README | 2 ++ public/designs/icons/default/gtk-go-down.png | Bin 0 -> 1029 bytes public/designs/icons/default/gtk-go-up.png | Bin 1031 -> 0 bytes public/designs/icons/default/style.css | 2 ++ public/stylesheets/blocks.css | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/application_controller_test.rb | 4 ++-- test/functional/profile_design_controller_test.rb | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/region_validators_controller_test.rb | 2 +- test/integration/routing_test.rb | 11 ++++++----- test/unit/acts_as_having_boxes.rb | 16 ++++++++++++++++ test/unit/environment_test.rb | 19 +++++++++++++++---- test/unit/profile_test.rb | 23 ++++++++++++++++++----- 39 files changed, 592 insertions(+), 58 deletions(-) create mode 100644 app/controllers/box_organizer_controller.rb create mode 100644 app/controllers/my_profile/profile_design_controller.rb create mode 100644 app/helpers/boxes_helper.rb create mode 100644 app/models/block.rb create mode 100644 app/models/box.rb create mode 100644 app/models/main_block.rb create mode 100644 app/views/box_organizer/index.rhtml create mode 100644 app/views/box_organizer/move_block.rjs create mode 120000 app/views/profile_design create mode 100644 lib/acts_as_having_boxes.rb create mode 100644 public/designs/icons/default/gtk-go-down.png create mode 100644 public/stylesheets/blocks.css create mode 100644 test/functional/profile_design_controller_test.rb create mode 100644 test/unit/acts_as_having_boxes.rb diff --git a/app/controllers/admin/admin_panel_controller.rb b/app/controllers/admin/admin_panel_controller.rb index 4d8814d..0281196 100644 --- a/app/controllers/admin/admin_panel_controller.rb +++ b/app/controllers/admin/admin_panel_controller.rb @@ -8,7 +8,9 @@ class AdminPanelController < AdminController # as the default holder before_filter :load_default_enviroment - design :holder => 'environment' + def boxes_holder + environment + end protected diff --git a/app/controllers/admin/edit_template_controller.rb b/app/controllers/admin/edit_template_controller.rb index f130b10..bab016b 100644 --- a/app/controllers/admin/edit_template_controller.rb +++ b/app/controllers/admin/edit_template_controller.rb @@ -1,6 +1,7 @@ class EditTemplateController < AdminController - design_editor :holder => 'environment', :autosave => true, :block_types => :block_types + #FIXME + #design_editor :holder => 'environment', :autosave => true, :block_types => :block_types def block_types %w[ diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 953b55f..d2e67da 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -5,7 +5,14 @@ class ApplicationController < ActionController::Base helper :document helper :language - design :holder => 'environment' + def boxes_holder + environment + end + + def boxes_editor? + false + end + protected :boxes_editor? def self.no_design_blocks @no_design_blocks = true diff --git a/app/controllers/box_organizer_controller.rb b/app/controllers/box_organizer_controller.rb new file mode 100644 index 0000000..df7cdb5 --- /dev/null +++ b/app/controllers/box_organizer_controller.rb @@ -0,0 +1,52 @@ +class BoxOrganizerController < ApplicationController + + def move_block + @block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) + + @source_box = @block.box + + target_position = nil + + if (params[:target] =~ /before-block-([0-9]+)/) + block_before = boxes_holder.blocks.find($1) + target_position = block_before.position + + @target_box = block_before.box + else + (params[:target] =~ /end-of-box-([0-9])+/) + + @target_box = boxes_holder.boxes.find($1) + end + + if (@source_box != @target_box) + @block.remove_from_list + @block.box = @target_box + end + + if target_position.nil? + # insert in the end of the box + @block.insert_at(@target_box.blocks.size + 1) + @block.move_to_bottom + else + # insert the block in the given position + @block.insert_at(@block.position && @block.position < target_position ? target_position - 1 : target_position) + end + + @block.save! + + @target_box.reload + end + + def move_block_down + @block = boxes_holder.blocks.find(params[:id]) + @block.move_lower + redirect_to :back + end + + def move_block_up + @block = boxes_holder.blocks.find(params[:id]) + @block.move_higher + redirect_to :back + end + +end diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index 3de455d..b6156fe 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -2,7 +2,9 @@ class CmsController < MyProfileController protect 'post_content', :profile, :only => [:edit, :new, :reorder, :delete] - design :holder => :profile + def boxes_holder + profile + end include CmsHelper @@ -11,6 +13,7 @@ class CmsController < MyProfileController TextileArticle, RssFeed, UploadedFile, + ImageGallery, ] def view diff --git a/app/controllers/my_profile/profile_design_controller.rb b/app/controllers/my_profile/profile_design_controller.rb new file mode 100644 index 0000000..7b32e4a --- /dev/null +++ b/app/controllers/my_profile/profile_design_controller.rb @@ -0,0 +1,14 @@ +class ProfileDesignController < BoxOrganizerController + + needs_profile + + def index + render :text => '...', :layout => true + end + + def boxes_editor? + true + end + protected :boxes_editor? + +end diff --git a/app/controllers/my_profile/profile_editor_controller.rb b/app/controllers/my_profile/profile_editor_controller.rb index beac8a5..eee08ba 100644 --- a/app/controllers/my_profile/profile_editor_controller.rb +++ b/app/controllers/my_profile/profile_editor_controller.rb @@ -4,7 +4,8 @@ class ProfileEditorController < MyProfileController helper :profile - design_editor :holder => 'profile',:autosave => true, :block_types => :block_types + # FIXME + #design_editor :holder => 'profile',:autosave => true, :block_types => :block_types def block_types diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb index f8c4a8c..e128bcc 100644 --- a/app/controllers/public/account_controller.rb +++ b/app/controllers/public/account_controller.rb @@ -2,8 +2,6 @@ class AccountController < PublicController before_filter :load_default_environment - design :holder => 'environment' - # say something nice, you goof! something sweet. def index unless logged_in? diff --git a/app/controllers/public/category_controller.rb b/app/controllers/public/category_controller.rb index 802a926..e7f23cc 100644 --- a/app/controllers/public/category_controller.rb +++ b/app/controllers/public/category_controller.rb @@ -5,7 +5,9 @@ class CategoryController < ApplicationController #FIXME This is not necessary because the application controller define the envrioment # as the default holder - design :holder => 'environment' + def boxes_holder + environment + end def load_default_enviroment @environment = Environment.default diff --git a/app/controllers/public/home_controller.rb b/app/controllers/public/home_controller.rb index 931409d..2968a0b 100644 --- a/app/controllers/public/home_controller.rb +++ b/app/controllers/public/home_controller.rb @@ -1,7 +1,5 @@ class HomeController < PublicController - design :holder => 'environment' - def index @articles = TextArticle.recent(nil, 10) end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6cd3d7e..9bc107f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -5,6 +5,8 @@ module ApplicationHelper include PermissionName include LightboxHelper + + include BoxesHelper # Displays context help. You can pass the content of the help message as the # first parameter or using template code inside a block passed to this @@ -144,14 +146,6 @@ module ApplicationHelper end end - def search_box - [form_tag({:controller => 'search', :action => 'index'}, :method => 'get'), - design_display_button_submit('find', '', :title => _('Search')), - text_field_tag( 'query', _('your search here'), :id => "input_search", :onfocus => 'javascript: if (this.value == %s) { this.value = ""; }' % _('your search here').inspect, :onblur => "javascript: if (this.value == '') { this.value = %s}" % _('your search here').inspect), - '', - ].join("\n") - end - def footer # FIXME: add some information from the environment [ @@ -267,7 +261,11 @@ module ApplicationHelper end def button(type, label, url, html_options = {}) - design_display_button(type, label, url, { :class => 'with_text' }.merge(html_options)) + the_class = "button #{type}" + if html_options.has_key?(:class) + the_class << ' ' << html_options[:class] + end + link_to(content_tag('span', label), url, html_options.merge(:class => the_class )) end def submit_button(type, label, html_options = {}) @@ -275,20 +273,28 @@ module ApplicationHelper html_options[:class] = [html_options[:class], 'submit'].compact.join(' ') - bt_submit = design_display_button_submit(type, label, { :class => 'with_text' }.merge(html_options)) - content_tag('p', bt_submit + bt_cancel, :class => 'submitline') + the_class = "button with_text #{type}" + if html_options.has_key?(:class) + the_class << ' ' << html_options[:class] + end + + bt_submit = submit_tag(label, html_options.merge(:class => the_class)) + content_tag('p', bt_submit + bt_cancel, :class => 'submitline') end def button_to_function(type, label, js_code, html_options = {}) - #design_display_function_button(type, label, js_code, { :class => 'with_text' }.merge(html_options)) html_options[:class] = "" unless html_options[:class] html_options[:class] << " button #{type}" link_to_function(label, js_code, html_options) end - def icon(icon_name) - design_display_icon(icon_name) + def icon(icon_name, html_options = {}) + the_class = "button #{icon_name}" + if html_options.has_key?(:class) + the_class << ' ' << html_options[:class] + end + content_tag('div', '', html_options.merge(:class => the_class)) end def button_bar(options = {}, &block) diff --git a/app/helpers/boxes_helper.rb b/app/helpers/boxes_helper.rb new file mode 100644 index 0000000..4217295 --- /dev/null +++ b/app/helpers/boxes_helper.rb @@ -0,0 +1,109 @@ +module BoxesHelper + + def box_decorator + @box_decorator || DontMoveBlocks + end + + def with_box_decorator(dec, &block) + @box_decorator = dec + result = block.call + @box_decorator = DontMoveBlocks + + result + end + + def display_boxes_editor(holder) + with_box_decorator self do + content_tag('div', display_boxes(holder, '<' + _('Main content') + '>'), :id => 'box-organizer') + end + end + + def display_boxes(holder, main_content) + boxes = holder.boxes.first(holder.boxes_limit) + content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") + content = main_content if (content.blank?) + content_tag('div', content, :class => 'boxes', :id => 'boxes' ) + end + + def display_box(box, main_content) + content_tag('div', content_tag('div', display_box_content(box, main_content), :class => 'blocks'), :class => 'box', :id => "box-#{box.position}" ) + end + + def display_updated_box(box) + with_box_decorator self do + display_box_content(box, '<' + _('Main content') + '>') + end + end + + def display_box_content(box, main_content) + box.blocks.map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) + end + + def display_block(block, main_content = nil) + content = block.content(main_content) + result = + case content + when Hash + content_tag('iframe', '', :src => url_for(content)) + when String + if content =~ /^https?:\/\// + content_tag('iframe', '', :src => content) + else + content + end + end + + classes = ['block', block.class.name.underscore.gsub('_', '-') ].uniq.join(' ') + + box_decorator.block_target(block.box, block) + content_tag('div', result + box_decorator.block_move_buttons(block), :class => classes, :id => "block-#{block.id}") + box_decorator.block_handle(block) + end + + module DontMoveBlocks + # does nothing + def self.block_target(box, block = nil) + '' + end + # does nothing + def self.block_handle(block) + '' + end + def self.block_move_buttons(block) + '' + end + end + + # generates a place where you can drop a block and get the block moved to + # there. + # + # If +block+ is not nil, then it means "place the dropped block before this + # one.". Otherwise, it means "place the dropped block at the end of the + # list" + # + # +box+ is always needed + def block_target(box, block = nil) + id = + if block.nil? + "end-of-box-#{box.id}" + else + "before-block-#{block.id}" + end + + content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => 'block', :hoverclass => 'block-target-hover') + end + + # makes the given block draggable so it can be moved away. + def block_handle(block) + draggable_element("block-#{block.id}", :revert => true) + end + + def block_move_buttons(block) + buttons = [] + + # FIXME hardcoded paths !!! + buttons << link_to(image_tag('/designs/icons/default/gtk-go-up.png', :alt => _('Move block up')), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) unless block.first? + buttons << link_to(image_tag('/designs/icons/default/gtk-go-down.png', :alt => _('Move block down')), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) unless block.last? + + content_tag('div', buttons.join("\n"), :class => 'block-move-buttons') + end + +end diff --git a/app/models/block.rb b/app/models/block.rb new file mode 100644 index 0000000..7140b89 --- /dev/null +++ b/app/models/block.rb @@ -0,0 +1,13 @@ +class Block < ActiveRecord::Base + acts_as_list :scope => :box + belongs_to :box + + def content(main_content = nil) + "This is block number %d" % self.id + end + + def editor + { :controller => 'block_editor', :id => self.id } + end + +end diff --git a/app/models/box.rb b/app/models/box.rb new file mode 100644 index 0000000..d293529 --- /dev/null +++ b/app/models/box.rb @@ -0,0 +1,5 @@ +class Box < ActiveRecord::Base + belongs_to :owner, :polymorphic => true + acts_as_list :scope => 'owner_id = #{owner_id} and owner_type = \'#{owner_type}\'' + has_many :blocks, :dependent => :destroy, :order => 'position' +end diff --git a/app/models/environment.rb b/app/models/environment.rb index d839d61..fd9c5c1 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -25,7 +25,14 @@ class Environment < ActiveRecord::Base # Relationships and applied behaviour # ################################################# - acts_as_design + acts_as_having_boxes + + after_create do |env| + 3.times do + env.boxes << Box.new + end + env.boxes.first.blocks << MainBlock.new + end # One Environment can be reached by many domains has_many :domains, :as => :owner diff --git a/app/models/link_block.rb b/app/models/link_block.rb index 96ed9a7..cca0c6a 100644 --- a/app/models/link_block.rb +++ b/app/models/link_block.rb @@ -1,4 +1,4 @@ -class LinkBlock < Design::Block +class LinkBlock < Block def content Profile.find(:all).map{|p| p.name} diff --git a/app/models/main_block.rb b/app/models/main_block.rb new file mode 100644 index 0000000..d4ed3d3 --- /dev/null +++ b/app/models/main_block.rb @@ -0,0 +1,7 @@ +class MainBlock < Block + + def content(main_content = nil) + main_content + end + +end diff --git a/app/models/profile.rb b/app/models/profile.rb index 2fb6409..83963ec 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -14,7 +14,7 @@ class Profile < ActiveRecord::Base acts_as_accessible - acts_as_design + acts_as_having_boxes acts_as_searchable :fields => [ :name, :identifier ] @@ -81,6 +81,13 @@ class Profile < ActiveRecord::Base self.environment ||= Environment.default end + after_create do |profile| + 3.times do + profile.boxes << Box.new + end + profile.boxes.first.blocks << MainBlock.new + end + # Returns information about the profile's owner that was made public by # him/her. # diff --git a/app/models/recent_documents_block.rb b/app/models/recent_documents_block.rb index 6884794..3d21627 100644 --- a/app/models/recent_documents_block.rb +++ b/app/models/recent_documents_block.rb @@ -1,4 +1,4 @@ -class RecentDocumentsBlock < Design::Block +class RecentDocumentsBlock < Block def content lambda do diff --git a/app/views/box_organizer/index.rhtml b/app/views/box_organizer/index.rhtml new file mode 100644 index 0000000..a7f937f --- /dev/null +++ b/app/views/box_organizer/index.rhtml @@ -0,0 +1,3 @@ +

testing

+ +This is a test ... and this is a sample text. diff --git a/app/views/box_organizer/move_block.rjs b/app/views/box_organizer/move_block.rjs new file mode 100644 index 0000000..86c00ec --- /dev/null +++ b/app/views/box_organizer/move_block.rjs @@ -0,0 +1,8 @@ +from = "box-#{@source_box.position}" +to = "box-#{@target_box.position}" + +page.replace_html(from, display_updated_box(@source_box)) +page.replace_html(to, display_updated_box(@target_box)) + +page.visual_effect(:highlight, from) +page.visual_effect(:highlight, to) unless (from == to) diff --git a/app/views/layouts/application.rhtml b/app/views/layouts/application.rhtml index 08ded08..0b18e33 100644 --- a/app/views/layouts/application.rhtml +++ b/app/views/layouts/application.rhtml @@ -10,12 +10,17 @@ - <%= design_all_header_tags %> <%= stylesheet_link_tag 'common' %> <%= stylesheet_link_tag 'help' %> <%= stylesheet_link_tag 'menu' %> <%= stylesheet_link_tag 'button' %> <%= stylesheet_link_tag 'search' %> + <%= stylesheet_link_tag 'blocks' %> + + <%# FIXME %> + <%= stylesheet_link_tag '/designs/templates/default/stylesheets/style.css' %> + + <%= javascript_include_tag(:defaults) %> <%= javascript_include_tag 'menu' %> <%= include_lightbox_header %> <%# cms stuff %> @@ -70,10 +75,15 @@
- <% if uses_design_blocks? %> - <%= design_display(yield) %> - <% else %> + <% if @controller.send(:boxes_editor?) %> <%= yield %> + <%= display_boxes_editor(@controller.boxes_holder) %> + <% else %> + <% if uses_design_blocks? %> + <%= display_boxes(@controller.boxes_holder, yield) %> + <% else %> + <%= yield %> + <% end %> <% end %> diff --git a/app/views/profile_design b/app/views/profile_design new file mode 120000 index 0000000..1b8d625 --- /dev/null +++ b/app/views/profile_design @@ -0,0 +1 @@ +box_organizer/ \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb index 949293c..811afed 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -80,6 +80,7 @@ require 'noosfero/transliterations' require 'acts_as_filesystem' require 'acts_as_searchable' +require 'acts_as_having_boxes' # to the hell, I want all my models loaded before the application run anything Dir.glob("#{RAILS_ROOT}/app/models/*.rb").each do |model| diff --git a/db/migrate/001_add_design_support.rb b/db/migrate/001_add_design_support.rb index bb4f4b0..a2c1ebc 100644 --- a/db/migrate/001_add_design_support.rb +++ b/db/migrate/001_add_design_support.rb @@ -1,26 +1,29 @@ class AddDesignSupport < ActiveRecord::Migration def self.up - create_table :design_boxes do |t| - t.column :name, :string - t.column :title, :string - t.column :number, :integer + + create_table :boxes do |t| t.column :owner_type, :string t.column :owner_id, :integer + + # acts_as_list + t.column :position, :integer end - create_table :design_blocks do |t| + create_table :blocks do |t| t.column :title, :string t.column :box_id, :integer - t.column :position, :integer t.column :type, :string t.column :settings, :text + + # acts_as_list + t.column :position, :integer end end def self.down - drop_table :design_boxes - drop_table :design_blocks + drop_table :boxes + drop_table :blocks end end diff --git a/lib/acts_as_having_boxes.rb b/lib/acts_as_having_boxes.rb new file mode 100644 index 0000000..8c020bd --- /dev/null +++ b/lib/acts_as_having_boxes.rb @@ -0,0 +1,36 @@ +module ActsAsHavingBoxes + + module ClassMethods + def acts_as_having_boxes + has_many :boxes, :as => :owner, :dependent => :destroy, :order => 'position' + self.send(:include, ActsAsHavingBoxes) + end + end + + module BlockArray + def find(id) + select { |item| item.id == id.to_i }.first + end + end + + def blocks(reload = false) + if (reload) + @blocks = nil + end + if @blocks.nil? + @blocks = boxes.inject([]) do |acc,obj| + acc.concat(obj.blocks) + end + @blocks.send(:extend, BlockArray) + end + @blocks + end + + # returns 3 unless the class table has a boxes_limit column. In that case + # return the value of the column. + def boxes_limit + self[:boxes_limit] || 3 + end +end + +ActiveRecord::Base.extend(ActsAsHavingBoxes::ClassMethods) diff --git a/lib/needs_profile.rb b/lib/needs_profile.rb index 4b2708c..0c0d658 100644 --- a/lib/needs_profile.rb +++ b/lib/needs_profile.rb @@ -3,7 +3,9 @@ module NeedsProfile module ClassMethods def needs_profile before_filter :load_profile - design :holder => 'profile' + def boxes_holder + profile + end end end diff --git a/public/designs/icons/default/README b/public/designs/icons/default/README index 43c04fe..bb7b884 100644 --- a/public/designs/icons/default/README +++ b/public/designs/icons/default/README @@ -34,6 +34,8 @@ gtk-find.png Nuovo stock/ gtk-go-back-ltr.png Nuovo stock/ gtk-media-next-ltr.png Nuovo stock/ gtk-add.png Nuovo stock/ +gtk-go-up.png Nuovo stock/ +gtk-go-down.png Nuovo stock/ ### END OF ICONS LISTING ### Licensing of GNOME themes diff --git a/public/designs/icons/default/gtk-go-down.png b/public/designs/icons/default/gtk-go-down.png new file mode 100644 index 0000000..286600f Binary files /dev/null and b/public/designs/icons/default/gtk-go-down.png differ diff --git a/public/designs/icons/default/gtk-go-up.png b/public/designs/icons/default/gtk-go-up.png index 4c4a7fe..6ddb634 100644 Binary files a/public/designs/icons/default/gtk-go-up.png and b/public/designs/icons/default/gtk-go-up.png differ diff --git a/public/designs/icons/default/style.css b/public/designs/icons/default/style.css index 2379d7a..c42a0e9 100644 --- a/public/designs/icons/default/style.css +++ b/public/designs/icons/default/style.css @@ -14,3 +14,5 @@ .button.back { background-image: url(gtk-go-back-ltr.png); } .button.next { background-image: url(gtk-media-next-ltr.png); } .button.add { background-image: url(gtk-add.png); } +.button.up { background-image: url(gtk-go-up.png); } +.button.down { background-image: url(gtk-go-down.png); } diff --git a/public/stylesheets/blocks.css b/public/stylesheets/blocks.css new file mode 100644 index 0000000..0993881 --- /dev/null +++ b/public/stylesheets/blocks.css @@ -0,0 +1,58 @@ + +/* main box */ +#box-1 { + margin-left: 210px; + margin-right: 210px; +} + +#box-2 { + float: left; + width: 200px; +} + +#box-3 { + float: right; + width: 200px; +} + + +.block { + margin: 5px; + padding: 5px; +} + +.block-target { + margin: 5px; + height: 2px; + height: 15px; + border: 1px dashed #e0e0e0; +} + +.block-target-hover { + background: #ffd; + border: 1px solid red; + height: 30px; +} + +.block iframe { + width: 100%; + border: none; +} + +/*********************************************************** + * put borders around boxes and blocks when organizing boxes + ***********************************************************/ + +#box-organizer .box { + border: 1px solid #ccc; +} + +#box-organizer #box-1 .block { + border: 2px dashed green; +} +#box-organizer #box-2 .block { + border: 2px dashed red; +} +#box-organizer #box-3 .block { + border: 2px dashed blue; +} diff --git a/test/functional/application_controller_test.rb b/test/functional/application_controller_test.rb index 033d3f5..94fafd5 100644 --- a/test/functional/application_controller_test.rb +++ b/test/functional/application_controller_test.rb @@ -107,7 +107,7 @@ class ApplicationControllerTest < Test::Unit::TestCase should 'use design plugin to generate blocks' do get :index - assert_tag :tag => 'div', :attributes => { :id => 'boxes', :class => 'design_boxes' } + assert_tag :tag => 'div', :attributes => { :id => 'boxes', :class => 'boxes' } end should 'not use design plugin when tells so' do @@ -116,6 +116,6 @@ class ApplicationControllerTest < Test::Unit::TestCase end @controller = NoDesignBlocksTestController.new get :index - assert_no_tag :tag => 'div', :attributes => { :id => 'boxes', :class => 'design_boxes' } + assert_no_tag :tag => 'div', :attributes => { :id => 'boxes', :class => 'boxes' } end end diff --git a/test/functional/profile_design_controller_test.rb b/test/functional/profile_design_controller_test.rb new file mode 100644 index 0000000..4c6c581 --- /dev/null +++ b/test/functional/profile_design_controller_test.rb @@ -0,0 +1,135 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'profile_design_controller' + +class ProfileDesignController; def rescue_action(e) raise e end; end + +class ProfileDesignControllerTest < Test::Unit::TestCase + + def setup + @controller = ProfileDesignController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + holder = create_user('designtestuser').person + holder.save! + + @box1 = Box.new + @box2 = Box.new + @box3 = Box.new + + holder.boxes << @box1 + holder.boxes << @box2 + holder.boxes << @box3 + + ###### BOX 1 + @b1 = Block.new + @box1.blocks << @b1 + @b1.save! + + @b2 = Block.new + @box1.blocks << @b2 + @b2.save! + + ###### BOX 2 + @b3 = Block.new + @box2.blocks << @b3 + @b3.save! + + @b4 = MainBlock.new + @box2.blocks << @b4 + @b4.save! + + @b5 = Block.new + @box2.blocks << @b5 + @b5.save! + + @b6 = Block.new + @box2.blocks << @b6 + @b6.save! + + ###### BOX 3 + @b7 = Block.new + @box3.blocks << @b7 + @b7.save! + + @b8 = Block.new + @box3.blocks << @b8 + @b8.save! + + @request.env['HTTP_REFERER'] = '/editor' + + @controller.expects(:boxes_holder).returns(holder).at_least_once + end + + def test_should_move_block_to_the_end_of_another_block + get :move_block, :profile => 'ze', :id => "block-#{@b1.id}", :target => "end-of-box-#{@box2.id}" + + assert_response :success + + @b1.reload + @box2.reload + + assert_equal @box2, @b1.box + assert @b1.in_list? + assert_equal @box2.blocks.size, @b1.position # i.e. assert @b1.last? + end + + def test_should_move_block_to_the_middle_of_another_block + # block 4 is in box 2 + get :move_block, :profile => 'ze', :id => "block-#{@b1.id}", :target => "before-block-#{@b4.id}" + + assert_response :success + + @b1.reload + @b4.reload + + assert_equal @b4.box, @b1.box + assert @b1.in_list? + assert_equal @b4.position - 1, @b1.position + end + + def test_block_can_be_moved_up + get :move_block, :profile => 'ze', :id => "block-#{@b4.id}", :target => "before-block-#{@b3.id}" + + assert_response :success + @b4.reload + @b3.reload + + assert_equal @b3.position - 1, @b4.position + end + + def test_block_can_be_moved_down + assert_equal [1,2,3], [@b3,@b4,@b5].map {|item| item.position} + + # b3 -> before b5 + get :move_block, :profile => 'ze', :id => "block-#{@b3.id}", :target => "before-block-#{@b5.id}" + + [@b3,@b4,@b5].each do |item| + item.reload + end + + assert_equal [1,2,3], [@b4, @b3, @b5].map {|item| item.position} + end + + def test_should_be_able_to_move_block_directly_down + post :move_block_down, :profile => 'ze', :id => @b1.id + assert_response :redirect + + @b1.reload + @b2.reload + + assert_equal [1,2], [@b2,@b1].map {|item| item.position} + end + + def test_should_be_able_to_move_block_directly_up + post :move_block_up, :profile => 'ze', :id => @b2.id + assert_response :redirect + + @b1.reload + @b2.reload + + assert_equal [1,2], [@b2,@b1].map {|item| item.position} + end + +end + diff --git a/test/functional/region_validators_controller_test.rb b/test/functional/region_validators_controller_test.rb index 7557c4b..50606b9 100644 --- a/test/functional/region_validators_controller_test.rb +++ b/test/functional/region_validators_controller_test.rb @@ -27,7 +27,7 @@ class RegionValidatorsControllerTest < Test::Unit::TestCase environment.regions << region assert !region.new_record? - @controller.expects(:environment).returns(environment) + @controller.expects(:environment).returns(environment).at_least_once get :region, :id => region.id diff --git a/test/integration/routing_test.rb b/test/integration/routing_test.rb index 0c1d3a5..6ed1e61 100644 --- a/test/integration/routing_test.rb +++ b/test/integration/routing_test.rb @@ -80,12 +80,13 @@ class RoutingTest < ActionController::IntegrationTest assert_routing('/cat', :controller => 'category', :action => 'index') end - def test_routing_to_controllers_inside_design_blocks_directory - assert_routing('/block/cojones/favorite_links_profile/show/1', :profile => 'cojones', :controller => 'favorite_links_profile', :action => 'show', :id => '1') - assert_routing('/block/cojones/favorite_links_profile/save', :profile => 'cojones', :controller => 'favorite_links_profile', :action => 'save') + #FIXME remove this if design_blocks is not going to be used; or uncomment otherwise; + #def test_routing_to_controllers_inside_design_blocks_directory + # assert_routing('/block/cojones/favorite_links_profile/show/1', :profile => 'cojones', :controller => 'favorite_links_profile', :action => 'show', :id => '1') + # assert_routing('/block/cojones/favorite_links_profile/save', :profile => 'cojones', :controller => 'favorite_links_profile', :action => 'save') - assert_routing('/block/cojones/list_block/show/1', :profile => 'cojones', :controller => 'list_block', :action => 'show', :id => '1') - end + # assert_routing('/block/cojones/list_block/show/1', :profile => 'cojones', :controller => 'list_block', :action => 'show', :id => '1') + #end def test_tag_viewing assert_routing('/tag', :controller => 'search', :action => 'tags') diff --git a/test/unit/acts_as_having_boxes.rb b/test/unit/acts_as_having_boxes.rb new file mode 100644 index 0000000..0df9959 --- /dev/null +++ b/test/unit/acts_as_having_boxes.rb @@ -0,0 +1,16 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ActsAsHavingBoxesTest < Test::Unit::TestCase + + should 'be able to find blocks by id' do + env = Environment.create!(:name => 'my test environment') + env.boxes.destroy_all + + env.boxes << Box.new + block = Block.new + env.boxes.first.blocks << block + + assert_equal block, env.blocks.find(block.id) + end + +end diff --git a/test/unit/environment_test.rb b/test/unit/environment_test.rb index 6ccd0b7..5f8d644 100644 --- a/test/unit/environment_test.rb +++ b/test/unit/environment_test.rb @@ -199,13 +199,24 @@ class EnvironmentTest < Test::Unit::TestCase assert env_boxes > 0 assert env_blocks > 0 - boxes = Design::Box.count - blocks = Design::Block.count + boxes = Box.count + blocks = Block.count env.destroy - assert_equal boxes - env_boxes, Design::Box.count - assert_equal blocks - env_blocks, Design::Block.count + assert_equal boxes - env_boxes, Box.count + assert_equal blocks - env_blocks, Block.count + end + + should 'have boxes and blocks upon creation' do + environment = Environment.create!(:name => 'a test environment') + assert environment.boxes.size > 0 + assert environment.blocks.size > 0 + end + + should 'have at least one MainBlock upon creation' do + environment = Environment.create!(:name => 'a test environment') + assert(environment.blocks.any? { |block| block.kind_of? MainBlock }) end end diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index aee4981..a72c82f 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -200,21 +200,34 @@ class ProfileTest < Test::Unit::TestCase assert_equal profile, Profile['testprofile'] end + should 'have boxes and blocks upon creation' do + profile = Profile.create!(:name => 'test profile', :identifier => 'testprofile') + + assert profile.boxes.size > 0 + assert profile.blocks.size > 0 + end + + should 'have at least one MainBlock upon creation' do + profile = Profile.create!(:name => 'test profile', :identifier => 'testprofile') + assert(profile.blocks.any? { |block| block.kind_of? MainBlock }) + end + should 'remove boxes and blocks when removing profile' do - profile = Profile.create!(:name => 'test environment', :identifier => 'testenv') + profile = Profile.create!(:name => 'test profile', :identifier => 'testprofile') profile_boxes = profile.boxes.size profile_blocks = profile.blocks.size + assert profile_boxes > 0 assert profile_blocks > 0 - boxes = Design::Box.count - blocks = Design::Block.count + boxes = Box.count + blocks = Block.count profile.destroy - assert_equal boxes - profile_boxes, Design::Box.count - assert_equal blocks - profile_blocks, Design::Block.count + assert_equal boxes - profile_boxes, Box.count + assert_equal blocks - profile_blocks, Block.count end should 'provide url to itself' do -- libgit2 0.21.2