diff --git a/.gitignore b/.gitignore index adbb2d67..ac411e58 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ db/*.sqlite3 log/*.log tmp/**/* .DS_Store +rerun.txt diff --git a/Gemfile b/Gemfile index 3d60124a..e45cd395 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,8 @@ gem "rails", "3.0.0.beta3" gem "liquid" gem "bson_ext", '0.20.1' gem "mongo_ext" -gem "mongoid", ">= 2.0.0.beta2" +gem "mongoid", ">= 2.0.0.beta4" +gem "mongoid_acts_as_tree", :git => 'git://github.com/evansagge/mongoid_acts_as_tree.git' gem "warden" gem "devise", ">= 1.1.rc0" gem "haml", '>= 3.0.0.beta.2', :git => 'git://github.com/nex3/haml.git' @@ -28,5 +29,9 @@ group :test do gem 'rspec-rails', '>= 2.0.0.beta.5' gem 'factory_girl', :git => 'git://github.com/thoughtbot/factory_girl.git', :branch => 'rails3' gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git' - gem 'cucumber-rails', :git => 'git://github.com/aslakhellesoy/cucumber-rails.git' + gem 'cucumber', '0.7.2' + gem 'cucumber-rails' + gem 'spork' + gem 'launchy' + gem 'mocha', :git => 'git://github.com/floehopper/mocha.git' end \ No newline at end of file diff --git a/app/controllers/admin/layouts_controller.rb b/app/controllers/admin/layouts_controller.rb index ac5faa74..6a79fb68 100644 --- a/app/controllers/admin/layouts_controller.rb +++ b/app/controllers/admin/layouts_controller.rb @@ -5,7 +5,7 @@ class Admin::LayoutsController < Admin::BaseController def index @layouts = current_site.layouts end - + def new @layout = current_site.layouts.build end diff --git a/app/controllers/admin/page_parts_controller.rb b/app/controllers/admin/page_parts_controller.rb new file mode 100644 index 00000000..c36948ed --- /dev/null +++ b/app/controllers/admin/page_parts_controller.rb @@ -0,0 +1,10 @@ +class Admin::PagePartsController < Admin::BaseController + + layout nil + + def index + parts = current_site.layouts.find(params[:layout_id]).parts + render :json => { :parts => parts } + end + +end diff --git a/app/controllers/admin/pages_controller.rb b/app/controllers/admin/pages_controller.rb index af20c946..2d778900 100644 --- a/app/controllers/admin/pages_controller.rb +++ b/app/controllers/admin/pages_controller.rb @@ -8,10 +8,11 @@ class Admin::PagesController < Admin::BaseController def new @page = current_site.pages.build + @page.parts << PagePart.build_body_part end def edit - @page = current_site.pages.find(params[:id]) + @page = current_site.pages.find(params[:id]) end def create diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb index 25754beb..7f34212f 100644 --- a/app/controllers/admin/sessions_controller.rb +++ b/app/controllers/admin/sessions_controller.rb @@ -6,4 +6,10 @@ class Admin::SessionsController < Devise::SessionsController before_filter :require_site + protected + + def after_sign_in_path_for(resource) + admin_pages_url + end + end \ No newline at end of file diff --git a/app/helpers/admin/pages_helper.rb b/app/helpers/admin/pages_helper.rb index a527d8e8..269ddbca 100644 --- a/app/helpers/admin/pages_helper.rb +++ b/app/helpers/admin/pages_helper.rb @@ -3,7 +3,6 @@ module Admin::PagesHelper def parent_pages_options roots = current_site.pages.roots.where(:slug.ne => '404').and(:_id.ne => @page.id) - puts roots.to_a.inspect returning [] do |list| roots.each do |page| list = add_children_to_options(page, list) diff --git a/app/models/layout.rb b/app/models/layout.rb index f76304c7..e1dc2b16 100644 --- a/app/models/layout.rb +++ b/app/models/layout.rb @@ -1,10 +1,12 @@ class Layout < LiquidTemplate ## associations ## + has_many_related :pages embeds_many :parts, :class_name => 'PagePart' ## callbacks ## before_save :build_parts_from_value + after_save :update_parts_in_pages ## validations ## validates_format_of :value, :with => Locomotive::Regexps::CONTENT_FOR_LAYOUT, :message => :missing_content_for_layout @@ -15,23 +17,31 @@ class Layout < LiquidTemplate def build_parts_from_value if self.value_changed? || self.new_record? - self.parts = [] + self.parts.clear - (groups = self.value.scan(Locomotive::Regexps::CONTENT_FOR)).each do |part| + body = nil + + self.value.scan(Locomotive::Regexps::CONTENT_FOR).each do |part| part[1].strip! part[1] = nil if part[1].empty? slug = part[0].strip.downcase - name = (if slug == 'layout' - I18n.t('admin.shared.attributes.body') + if slug == 'layout' + body = PagePart.new :slug => slug, :name => I18n.t('admin.shared.attributes.body') else - (part[1] || slug).gsub("\"", '') - end) - - self.parts.build :slug => slug, :name => name + self.parts.build :slug => slug, :name => (part[1] || slug).gsub("\"", '') + end end + + self.parts.insert(0, body) if body + + @_update_pages = true if self.value_changed? end end + def update_parts_in_pages + self.pages.each { |p| p.send(:update_parts!, self.parts) } if @_update_pages + end + end \ No newline at end of file diff --git a/app/models/page.rb b/app/models/page.rb index bab1e584..00ebb354 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -13,6 +13,7 @@ class Page ## associations ## belongs_to_related :site + belongs_to_related :layout embeds_many :parts, :class_name => 'PagePart' ## callbacks ## @@ -22,7 +23,7 @@ class Page before_save :change_parent before_create { |p| p.fix_position(false) } before_create :add_to_list_bottom - before_create :add_body_part + # before_create :add_body_part before_destroy :remove_from_list ## validations ## @@ -34,6 +35,7 @@ class Page ## behaviours ## acts_as_tree :order => ['position', 'asc'] + # accepts_nested_attributes_for :parts, :allow_destroy => true ## methods ## @@ -45,8 +47,12 @@ class Page self.slug == '404' && self.depth.to_i == 0 end + def parts_attributes=(attributes) + self.update_parts(attributes.values.map { |attrs| PagePart.new(attrs) }) + end + def add_body_part - self.parts.build :name => 'body', :value => '---body here---' + self.parts.build :name => 'body', :slug => 'layout', :value => '---body here---' end def parent=(owner) # missing in acts_as_tree @@ -76,11 +82,35 @@ class Page def ancestors return [] if root? - self.class.find(self.path.clone << nil) # bug in mongoid (it does not handle array with on element) + self.class.find(self.path.clone << nil) # bug in mongoid (it does not handle array with one element) end protected + def update_parts(parts) + performed = [] + + # add / update + parts.each do |part| + if (existing = self.parts.detect { |p| p.id == part.id || p.slug == part.slug }) + existing.attributes = part.attributes.delete_if { |k, v| %w{_id slug}.include?(k) } + else + self.parts << (existing = part) + end + performed << existing unless existing.disabled? + end + + # disable missing parts + (self.parts.map(&:slug) - performed.map(&:slug)).each do |slug| + self.parts.detect { |p| p.slug == slug }.disabled = true + end + end + + def update_parts!(new_parts) + self.update_parts(new_parts) + self.save + end + def change_parent if self.parent_id_changed? self.fix_position(false) diff --git a/app/models/page_part.rb b/app/models/page_part.rb index 8ad52095..455c7c22 100644 --- a/app/models/page_part.rb +++ b/app/models/page_part.rb @@ -1,20 +1,36 @@ class PagePart include Mongoid::Document - include Mongoid::Timestamps + # include Mongoid::Timestamps ## fields ## field :name, :type => String field :slug, :type => String field :value, :type => String field :disabled, :type => Boolean, :default => false + field :value, :type => String ## associations ## embedded_in :page, :inverse_of => :parts + # attr_accessor :_delete + ## callbacks ## - before_validate { |p| p.slug ||= p.name.slugify if p.name.present? } + # before_validate { |p| p.slug ||= p.name.slugify if p.name.present? } ## validations ## validates_presence_of :name, :slug + ## named scopes ## + named_scope :enabled, where(:disabled => false) + + ## methods ## + + # def _delete=(value) + # puts "set _delete #{value.inspect}" + # self.attributes[:_destroy] = true if %w(t 1 true).include?(value) + # end + + def self.build_body_part + self.new(:name => I18n.t('admin.shared.attributes.body'), :slug => 'layout') + end end \ No newline at end of file diff --git a/app/views/admin/pages/_form.html.haml b/app/views/admin/pages/_form.html.haml index f87066ce..5ec79f3f 100644 --- a/app/views/admin/pages/_form.html.haml +++ b/app/views/admin/pages/_form.html.haml @@ -1,7 +1,13 @@ +- content_for :head do + = javascript_include_tag 'admin/plugins/codemirror/codemirror', 'admin/plugins/wslide', 'admin/pages', 'admin/page_parts' + = stylesheet_link_tag 'admin/page_parts' + = f.foldable_inputs :name => :information do = f.input :title + = f.input :layout_id, :as => :select, :collection => current_site.layouts.all, :input_html => { :data_url => admin_layout_page_parts_url('_id_to_replace_') } + - if not @page.index? and not @page.not_found? = f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false @@ -15,57 +21,17 @@ = f.input :keywords = f.input :description +#page-parts + .nav + - @page.parts.each_with_index do |part, index| + = link_to content_tag(:span, part.name), "#parts-#{index + 1}", :id => "control-part-#{part.slug}", :class => "part-#{index} #{'on' if index == 0}", :style => "#{'display: none' if part.disabled?}" + .clear - - -/ <% f.foldable_inputs :name => :information do %> -/ <%= f.input :title, :required => false %> -/ -/ <% f.custom_input :path, :css => 'path' do %> -/ /<%= f.text_field :path %>.html -/ <% end %> -/ -/ <% f.custom_input :layout do %> -/ <%= f.select :layout_id, current_site.layouts.all.collect { |l| [l.name, l.id] }, :include_blank => true %> -/ <% end %> -/ -/ <%= f.input :keywords, :required => false %> -/ <%= f.input :description, :required => false %> -/ -/ <% f.custom_input :cache_expires_in do %> -/ <%= f.select :cache_expires_in, options_for_page_cache_expiration %> -/ <% end %> -/ -/ <% f.custom_input :visible, :css => 'checkbox' do %> -/ <%= f.check_box :visible %> -/ <% end %> -/ <% end %> -/ -/ <% unless f.object.new_record? %> -/
-/
-/ <% if body_part? %> -/ <%= t('admin.pages.form.body') %><% end -%><% @page.parts.active.each_with_index do |p, index| -%><%= p.slug.humanize %> -/ <% end %> -/
-/ -/
-/ -/
-/
-/ -/ <% content_for :head do %> -/ <%= javascript_include_tag 'admin/plugins/iphoneSwitch', 'admin/plugins/checkbox', 'admin/plugins/carousel', 'codemirror/codemirror', 'admin/pages' %> -/ <%= stylesheet_link_tag 'carousel', 'admin/page_parts' %> -/ <% end %> -/ <% end %> \ No newline at end of file + .wrapper + %ul{ :id => "parts" } + = f.fields_for :parts do |g| + %li{ :style => "#{'display: none' if g.object.disabled?}" } + %code= g.text_area :value + = g.hidden_field :name + = g.hidden_field :slug + = g.hidden_field :disabled, :class => 'disabled' \ No newline at end of file diff --git a/app/views/admin/pages/edit.html.haml b/app/views/admin/pages/edit.html.haml index 7c4bfb1c..866b62ab 100644 --- a/app/views/admin/pages/edit.html.haml +++ b/app/views/admin/pages/edit.html.haml @@ -1,8 +1,5 @@ - title link_to(@page.title.blank? ? @page.title_was : @page.title, '#', :rel => 'page_title', :title => t('.ask_for_title'), :class => 'editable') -- content_for :head do - = javascript_include_tag 'admin/pages' - - content_for :submenu do = render 'admin/shared/menu/contents' diff --git a/app/views/admin/pages/new.html.haml b/app/views/admin/pages/new.html.haml index 5868abae..d30452e8 100644 --- a/app/views/admin/pages/new.html.haml +++ b/app/views/admin/pages/new.html.haml @@ -1,8 +1,5 @@ - title t('.title') -- content_for :head do - = javascript_include_tag 'admin/pages' - - content_for :submenu do = render 'admin/shared/menu/contents' diff --git a/config/cucumber.yml b/config/cucumber.yml index b7acd380..621a14ce 100644 --- a/config/cucumber.yml +++ b/config/cucumber.yml @@ -1,7 +1,8 @@ <% rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" -rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" -std_opts = "#{rerun_opts} --format rerun --out rerun.txt --strict --tags ~@wip" +rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" +std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip" %> -default: <%= std_opts %> +default: <%= std_opts %> features wip: --tags @wip:3 --wip features +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/config/database.yml b/config/database.yml index 0b10b23d..8b145ac5 100644 --- a/config/database.yml +++ b/config/database.yml @@ -5,7 +5,7 @@ development: <<: *defaults database: locomotive_dev -test: +test: &test <<: *defaults database: locomotive_test @@ -15,3 +15,6 @@ production: username: user password: pass database: fanboy + +cucumber: + <<: *test \ No newline at end of file diff --git a/config/initializers/mongoid.rb b/config/initializers/mongoid.rb index 7e77f27b..25b16194 100644 --- a/config/initializers/mongoid.rb +++ b/config/initializers/mongoid.rb @@ -14,8 +14,10 @@ end ## various patches -# Enabling scope in validates_uniqueness_of validation + module Mongoid #:nodoc: + + # Enabling scope in validates_uniqueness_of validation module Validations #:nodoc: class UniquenessValidator < ActiveModel::EachValidator def validate_each(document, attribute, value, scope = nil) @@ -26,4 +28,14 @@ module Mongoid #:nodoc: end end end -end + + # FIX BUG #71 http://github.com/durran/mongoid/commit/47a97094b32448aa09965c854a24c78803c7f42e + module Associations + module InstanceMethods + def update_embedded(name) + association = send(name) + association.to_a.each { |doc| doc.save if doc.changed? || doc.new_record? } unless association.blank? + end + end + end +end \ No newline at end of file diff --git a/config/locales/admin_ui_en.yml b/config/locales/admin_ui_en.yml index 93c51024..0d02ebfc 100644 --- a/config/locales/admin_ui_en.yml +++ b/config/locales/admin_ui_en.yml @@ -20,7 +20,7 @@ en: messages: confirm: Are you sure ? - + shared: header: welcome: Welcome, {{name}} @@ -48,6 +48,9 @@ en: title: Listing pages no_items: "There are no pages for now. Just click here to create the first one." new: new page + messages: + successful_create: "Page was successfully created." + successful_update: "Page was successfully updated." layouts: index: diff --git a/config/routes.rb b/config/routes.rb index 2ea5399b..7cec9adf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,7 +22,9 @@ Locomotive::Application.routes.draw do |map| get :get_path, :on => :collection end - resources :layouts + resources :layouts do + resources :page_parts, :only => :index + end resources :snippets # get 'login' => 'sessions#new', :as => :new_account_session diff --git a/doc/TODO b/doc/TODO index 5cbbf720..3d12f716 100644 --- a/doc/TODO +++ b/doc/TODO @@ -15,14 +15,19 @@ x store node closed or open in cookies x snippets section x menu items have to be translated x layout needs at least content_for_layout -- validates_uniqueness_of :slug, :scope => :id -- page parts -- can not delete index + 404 pages +x parts js/css: + x codemirror + x change bg (separator) + x when a tab is selected, if we change layout, we should move to the first visible one +x page parts +x layout part should be always in first +x pages section (CRUD) - slug unique within a folder -- pages section (CRUD) +- validates_uniqueness_of :slug, :scope => :id - refactoring page.rb => create module pagetree - my account section (part of settings) - layouts section - create 404 + index pages once a site is created +- can not delete index + 404 pages - refactoring admin crud (pages + layouts + snippets) - remove all pages, snippets, ...etc when destroying a website \ No newline at end of file diff --git a/features/admin/login.feature b/features/admin/login.feature new file mode 100644 index 00000000..cf4f4dd0 --- /dev/null +++ b/features/admin/login.feature @@ -0,0 +1,19 @@ +@site_up +Feature: Login + In order to access locomotive admin panel + As an administrator + I want to log in + +Scenario: Successful authentication + When I go to login + And I fill in "account_email" with "admin@locomotiveapp.org" + And I fill in "account_password" with "easyone" + And I press "Log in" + Then I should see "Listing pages" + +Scenario: Failed authentication + When I go to login + And I fill in "account_email" with "admin@locomotiveapp.org" + And I fill in "account_password" with "" + And I press "Log in" + Then I should not see "Listing pages" \ No newline at end of file diff --git a/features/admin/pages.feature b/features/admin/pages.feature new file mode 100644 index 00000000..62ab2e98 --- /dev/null +++ b/features/admin/pages.feature @@ -0,0 +1,31 @@ +@site_up +@authenticated +Feature: Manage Skills + In order to manage pages + As an administrator + I want to add/edit/delete pages of my site + +Scenario: Pages list is not accessible for non authenticated accounts + Given I am not authenticated + When I go to pages + Then I should see "Login" + +Scenario: Creating a valid page + When I go to pages + And I follow "new page" + And I fill in "Title" with "Test" + And I fill in "Slug" with "test" + And I select "Home page" from "Parent" + And I fill in "page_parts_attributes_0_value" with "Lorem ipsum...." + And I press "Create" + Then I should see "Page was successfully created." + And I should have "Lorem ipsum...." in the test page layout + +Scenario: Updating a valid page + When I go to pages + And I follow "Home page" + And I fill in "Title" with "Home page !" + And I fill in "page_parts_attributes_0_value" with "My new content is here" + And I press "Update" + Then I should see "Page was successfully updated." + And I should have "My new content is here" in the index page layout \ No newline at end of file diff --git a/features/step_definitions/admin_steps.rb b/features/step_definitions/admin_steps.rb new file mode 100644 index 00000000..4e8f69b1 --- /dev/null +++ b/features/step_definitions/admin_steps.rb @@ -0,0 +1,63 @@ +Before('@site_up') do + create_site_and_admin_account + create_layout_samples + create_index_page +end + +Before('@authenticated') do + Given %{I am an authenticated user} +end + +### Authentication + +Given /^I am not authenticated$/ do + visit('/admin/logout') +end + + +Given /^I am an authenticated user$/ do + Given %{I go to login} + And %{I fill in "account_email" with "admin@locomotiveapp.org"} + And %{I fill in "account_password" with "easyone"} + And %{I press "Log in"} +end + +Then /^I am redirected to "([^\"]*)"$/ do |url| + assert [301, 302].include?(@integration_session.status), "Expected status to be 301 or 302, got #{@integration_session.status}" + location = @integration_session.headers["Location"] + assert_equal url, location + visit location +end + +### Pages + + +Then /^I should have "(.*)" in the (.*) page (.*)$/ do |content, page_slug, slug| + page = @site.pages.where(:slug => page_slug).first + part = page.parts.where(:slug => slug).first + part.should_not be_nil + part.value.should == content +end + +## Common + +def create_site_and_admin_account + @site = Factory(:site, :name => 'Locomotive test website', :subdomain => 'test') + @admin = Factory(:account, { :name => 'Admin', :email => 'admin@locomotiveapp.org' }) +end + +def create_layout_samples + Factory(:layout, :site => @site, :name => 'One column', :value => %{ + + My website + + +
\{\{ content_for_layout \}\}
+ + }) + Factory(:layout, :site => @site) +end + +def create_index_page + Factory(:page, :site => @site, :layout => @site.layouts.last, :parts => [PagePart.new(:slug => 'layout', :name => 'Body', :value => 'Hello world')]) +end \ No newline at end of file diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 55ac5693..e5775052 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -6,6 +6,7 @@ require 'uri' +require 'cgi' require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) module WithinHelpers @@ -147,7 +148,8 @@ end Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should contain "([^\"]*)"$/ do |field, selector, value| with_scope(selector) do - field_value = find_field(field).value + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value if field_value.respond_to? :should field_value.should =~ /#{value}/ else @@ -158,11 +160,12 @@ end Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should not contain "([^\"]*)"$/ do |field, selector, value| with_scope(selector) do - field_value = find_field(field).value + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value if field_value.respond_to? :should_not field_value.should_not =~ /#{value}/ else - assert_no_match(/#{value}/, field_value.value) + assert_no_match(/#{value}/, field_value) end end end @@ -199,9 +202,11 @@ Then /^(?:|I )should be on (.+)$/ do |page_name| end Then /^(?:|I )should have the following query string:$/ do |expected_pairs| - actual_params = CGI.parse(URI.parse(current_url).query) - expected_params = Hash[expected_pairs.rows_hash.map{|k,v| [k,[v]]}] - + query = URI.parse(current_url).query + actual_params = query ? CGI.parse(query) : {} + expected_params = {} + expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} + if actual_params.respond_to? :should actual_params.should == expected_params else diff --git a/features/support/env.rb b/features/support/env.rb index 7a2362f4..109bbabd 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -10,7 +10,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support require 'cucumber/rails/rspec' require 'cucumber/rails/world' -require 'cucumber/rails/active_record' require 'cucumber/web/tableish' require 'capybara/rails' @@ -34,26 +33,27 @@ Capybara.default_selector = :css # of your scenarios, as this makes it hard to discover errors in your application. ActionController::Base.allow_rescue = false -# If you set this to true, each scenario will run in a database transaction. -# You can still turn off transactions on a per-scenario basis, simply tagging -# a feature or scenario with the @no-txn tag. If you are using Capybara, -# tagging with @culerity or @javascript will also turn transactions off. -# -# If you set this to false, transactions will be off for all scenarios, -# regardless of whether you use @no-txn or not. -# -# Beware that turning transactions off will leave data in your database -# after each scenario, which can lead to hard-to-debug failures in -# subsequent scenarios. If you do this, we recommend you create a Before -# block that will explicitly put your database in a known state. -Cucumber::Rails::World.use_transactional_fixtures = true +require 'factory_girl' +require 'spec/factories' -# How to clean your database when transactions are turned off. See -# http://github.com/bmabey/database_cleaner for more info. -if defined?(ActiveRecord::Base) - begin - require 'database_cleaner' - DatabaseCleaner.strategy = :truncation - rescue LoadError => ignore_if_database_cleaner_not_present - end +Before do + Mongoid.master.collections.each(&:drop) end + +Locomotive.configure do |config| + config.default_domain = 'example.com' +end + +# class ActionController::Integration::Session +# def reset_with_test_subdomain! +# self.reset_without_test_subdomain! +# self.host = "test.example.com" +# end +# alias_method_chain :reset!, :test_subdomain +# end +# +# class ActionDispatch::Integration::Session +# DEFAULT_HOST = 'test.example.com' +# end + +Capybara.default_host = 'test.example.com' \ No newline at end of file diff --git a/features/support/paths.rb b/features/support/paths.rb index c575c075..3c015e7e 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -7,10 +7,16 @@ module NavigationHelpers # def path_to(page_name) case page_name - + when /the home\s?page/ '/' - + when /login/ + new_account_session_path + when /logout/ + destroy_account_session_path + when /pages/ + admin_pages_path + # Add more mappings here. # Here is an example that pulls values out of the Regexp: # @@ -18,8 +24,14 @@ module NavigationHelpers # user_profile_path(User.find_by_login($1)) else - raise "Can't find mapping from \"#{page_name}\" to a path.\n" + - "Now, go and add a mapping in #{__FILE__}" + begin + page_name =~ /the (.*) page/ + path_components = $1.split(/\s+/) + self.send(path_components.push('path').join('_').to_sym) + rescue Object => e + raise "Can't find mapping from \"#{page_name}\" to a path.\n" + + "Now, go and add a mapping in #{__FILE__}" + end end end end diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake index 6d12f71f..522aafc8 100644 --- a/lib/tasks/cucumber.rake +++ b/lib/tasks/cucumber.rake @@ -14,18 +14,24 @@ begin require 'cucumber/rake/task' namespace :cucumber do - Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t| + Cucumber::Rake::Task.new(:ok, 'Run features that should pass') do |t| t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. t.fork = true # You may get faster startup if you set this to false t.profile = 'default' end - Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t| + Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t| t.binary = vendored_cucumber_bin t.fork = true # You may get faster startup if you set this to false t.profile = 'wip' end + Cucumber::Rake::Task.new(:rerun, 'Record failing features and run only them if any exist') do |t| + t.binary = vendored_cucumber_bin + t.fork = true # You may get faster startup if you set this to false + t.profile = 'rerun' + end + desc 'Run all features' task :all => [:ok, :wip] end diff --git a/public/images/admin/form/header-left-on.png b/public/images/admin/form/header-left-on.png new file mode 100644 index 00000000..6842c86d Binary files /dev/null and b/public/images/admin/form/header-left-on.png differ diff --git a/public/images/admin/form/header-right-on.png b/public/images/admin/form/header-right-on.png new file mode 100644 index 00000000..ba18ec85 Binary files /dev/null and b/public/images/admin/form/header-right-on.png differ diff --git a/public/javascripts/admin/application.js b/public/javascripts/admin/application.js index ab076e0f..ce85514a 100644 --- a/public/javascripts/admin/application.js +++ b/public/javascripts/admin/application.js @@ -24,7 +24,7 @@ var addCodeMirrorEditor = function(type, el, parser) { if (type == 'liquid') type = 'xml'; var editor = CodeMirror.fromTextArea(el.attr('id'), { - height: "330px", + height: "400px", parserfile: parserfile, stylesheet: ["/stylesheets/admin/plugins/codemirror/" + type + "colors.css", "/stylesheets/admin/plugins/codemirror/liquidcolors.css"], path: "/javascripts/admin/plugins/codemirror/", diff --git a/public/javascripts/admin/page_parts.js b/public/javascripts/admin/page_parts.js new file mode 100644 index 00000000..6786cf8e --- /dev/null +++ b/public/javascripts/admin/page_parts.js @@ -0,0 +1,83 @@ +$(document).ready(function() { + + // slider + var resetSlider = function() { + $('#page-parts .wrapper ul').wslide({ + width: 880, + height: 400, + autolink: false, + duration: 300, + horiz: true + }); + } + + resetSlider(); + + // codemirror + $('#parts code textarea').each(function() { addCodeMirrorEditor('liquid', $(this)); }); + + var refreshParts = function(parts) { + console.log('refreshParts'); + $('#page-parts .nav a').removeClass('enabled'); + + $(parts).each(function() { + console.log("iterating..." + this.slug); + var control = $('#control-part-' + this.slug); + + // adding missing part + if (control.size() == 0) { + console.log('adding part'); + var nbParts = $('#page-parts .nav a').size(); + $('#page-parts .nav .clear').before('' + this.name + ''); + + var textareaInput = '