diff --git a/app/assets/javascripts/locomotive/models/content_entry.js.coffee b/app/assets/javascripts/locomotive/models/content_entry.js.coffee index 59747023..25a0d592 100644 --- a/app/assets/javascripts/locomotive/models/content_entry.js.coffee +++ b/app/assets/javascripts/locomotive/models/content_entry.js.coffee @@ -44,7 +44,8 @@ class Locomotive.Models.ContentEntry extends Backbone.Model _.each @get('has_many_custom_fields'), (field) => # include the has_many relationships name = field[0] - hash["#{name}_attributes"] = @get(name).toMinJSON() + if @get(name).length > 0 + hash["#{name}_attributes"] = @get(name).toMinJSON() _.each @get('many_to_many_custom_fields'), (field) => # include the many_to_many relationships name = field[0]; setter_name = field[1] diff --git a/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee index 19267aa3..b9a7233b 100644 --- a/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee @@ -62,14 +62,15 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F @$("##{@model.paramRoot}_#{name}_input label").after(view.render().el) enable_has_many_fields: -> - _.each @model.get('has_many_custom_fields'), (field) => - name = field[0]; inverse_of = field[1] - new_entry = new Locomotive.Models.ContentEntry(@options["#{name}_new_entry"]) - view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, new_entry: new_entry, inverse_of: inverse_of + unless @model.isNew() + _.each @model.get('has_many_custom_fields'), (field) => + name = field[0]; inverse_of = field[1] + new_entry = new Locomotive.Models.ContentEntry(@options["#{name}_new_entry"]) + view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, new_entry: new_entry, inverse_of: inverse_of - @_has_many_field_views.push(view) + @_has_many_field_views.push(view) - @$("##{@model.paramRoot}_#{name}_input label").after(view.render().el) + @$("##{@model.paramRoot}_#{name}_input label").after(view.render().el) enable_many_to_many_fields: -> _.each @model.get('many_to_many_custom_fields'), (field) => diff --git a/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee index 985159d9..975e587a 100644 --- a/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee @@ -21,8 +21,6 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con entry = new Locomotive.Models.ContentEntry(response) @options.parent_view.insert_or_update_entry(entry) @close() - on_error: => - @shake() create_dialog: -> @dialog = $(@el).dialog @@ -56,11 +54,9 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con close: (event) -> event.stopPropagation() & event.preventDefault() if event? + @clear_errors() $(@el).dialog('close') - shake: -> - $(@el).parents('.ui-dialog').effect('shake', { times: 4 }, 100) - center: -> $(@el).dialog('option', 'position', 'center') @@ -73,5 +69,11 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con else @refresh() + enable_has_many_fields: -> + # disabled in a popup form + + enable_many_to_many_fields: -> + # disabled in a popup form + tinyMCE_settings: -> window.Locomotive.tinyMCE.popupSettings diff --git a/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee b/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee index a26d993f..e451fc9f 100644 --- a/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee @@ -14,6 +14,8 @@ class Locomotive.Views.Sites.MembershipEntryView extends Backbone.View $(@el).html(ich.membership_entry(data)) + $(@el).attr('data-role', @model.get('role')) + @$('select').val(@model.get('role')) return @ diff --git a/app/controllers/locomotive/current_site_controller.rb b/app/controllers/locomotive/current_site_controller.rb index 30ead3e7..cb846e8c 100644 --- a/app/controllers/locomotive/current_site_controller.rb +++ b/app/controllers/locomotive/current_site_controller.rb @@ -28,7 +28,7 @@ module Locomotive def filter_attributes unless can?(:manage, Locomotive::Membership) - params[:site].delete(:memberships_attributes) + params[:site].delete(:memberships_attributes) if params[:site] end end diff --git a/app/helpers/locomotive/custom_fields_helper.rb b/app/helpers/locomotive/custom_fields_helper.rb index 71032e19..973b7f65 100644 --- a/app/helpers/locomotive/custom_fields_helper.rb +++ b/app/helpers/locomotive/custom_fields_helper.rb @@ -3,7 +3,7 @@ module Locomotive def options_for_custom_field_type %w(string text select boolean date file belongs_to has_many many_to_many).map do |type| - [t("custom_fields.types.#{type}"), type] + [t("custom_fields.type.#{type}"), type] end end @@ -53,8 +53,9 @@ module Locomotive current_site.content_types.where(:'entries_custom_fields.type'.in => %w(belongs_to many_to_many)).each do |content_type| content_type.entries_custom_fields.each do |field| if %w(belongs_to many_to_many).include?(field.type) - hash[field.type] ||= [] - hash[field.type] << { + type = field.type == 'belongs_to' ? 'has_many' : field.type + hash[type] ||= [] + hash[type] << { :label => field.label, :name => field.name, :class_name => content_type.klass_with_custom_fields(:entries).to_s diff --git a/app/helpers/locomotive/theme_assets_helper.rb b/app/helpers/locomotive/theme_assets_helper.rb index 13804425..7805c616 100644 --- a/app/helpers/locomotive/theme_assets_helper.rb +++ b/app/helpers/locomotive/theme_assets_helper.rb @@ -21,6 +21,10 @@ module Locomotive end end + def theme_assets_to_json(list) + return nil.to_json if list.nil? + list.map { |asset| asset.as_json(:ability => current_ability) }.to_json + end end end \ No newline at end of file diff --git a/app/models/locomotive/extensions/site/locales.rb b/app/models/locomotive/extensions/site/locales.rb index 5fbfc8d4..c84f41ae 100644 --- a/app/models/locomotive/extensions/site/locales.rb +++ b/app/models/locomotive/extensions/site/locales.rb @@ -33,6 +33,8 @@ module Locomotive # @returns [ String ] The localized fullpath according to the current locale # def localized_page_fullpath(page, locale = nil) + return nil if page.fullpath_translations.blank? + locale = (locale || I18n.locale).to_s fullpath = page.fullpath_translations[locale] || page.fullpath_translations[self.default_locale] diff --git a/app/presenters/locomotive/base_presenter.rb b/app/presenters/locomotive/base_presenter.rb index 1f42baba..59c1c6d9 100644 --- a/app/presenters/locomotive/base_presenter.rb +++ b/app/presenters/locomotive/base_presenter.rb @@ -13,6 +13,7 @@ class Locomotive::BasePresenter @source = object @options = options || {} @depth = options[:depth] || 0 + @ability = options[:ability] if @options[:current_account] && @options[:current_site] @ability = Locomotive::Ability.new @options[:current_account], @options[:current_site] diff --git a/app/presenters/locomotive/content_type_presenter.rb b/app/presenters/locomotive/content_type_presenter.rb index 511496c8..7fba5aa7 100644 --- a/app/presenters/locomotive/content_type_presenter.rb +++ b/app/presenters/locomotive/content_type_presenter.rb @@ -1,7 +1,7 @@ module Locomotive class ContentTypePresenter < BasePresenter - delegate :name, :description, :slug, :order_by, :order_direction, :highlighted_field_name, :group_by_field_name, :api_accounts, :to => :source + delegate :name, :description, :slug, :order_by, :order_direction, :label_field_name, :group_by_field_id, :public_submission_accounts, :to => :source def entries_custom_fields self.source.ordered_entries_custom_fields.collect(&:as_json) @@ -12,7 +12,7 @@ module Locomotive end def included_methods - super + %w(name description slug order_by order_direction highlighted_field_name group_by_field_name api_accounts entries_custom_fields klass_name) + super + %w(name description slug order_by order_direction label_field_name group_by_field_id public_submission_accounts entries_custom_fields klass_name) end end diff --git a/app/presenters/locomotive/theme_asset_presenter.rb b/app/presenters/locomotive/theme_asset_presenter.rb index 929204ba..3ab86ec8 100644 --- a/app/presenters/locomotive/theme_asset_presenter.rb +++ b/app/presenters/locomotive/theme_asset_presenter.rb @@ -23,8 +23,12 @@ module Locomotive I18n.l(self.source.updated_at, :format => :short) end + def can_be_deleted + self.ability.try(:can?, :destroy, self.source) + end + def included_methods - default_list = %w(content_type folder local_path url size dimensions updated_at) + default_list = %w(content_type folder local_path url size dimensions can_be_deleted updated_at) default_list += %w(plain_text) if plain_text? super + default_list end diff --git a/app/views/locomotive/custom_fields/types/_has_many.html.haml b/app/views/locomotive/custom_fields/types/_has_many.html.haml index b405ee3e..efd40225 100644 --- a/app/views/locomotive/custom_fields/types/_has_many.html.haml +++ b/app/views/locomotive/custom_fields/types/_has_many.html.haml @@ -52,7 +52,7 @@ = form.inputs :name => :attributes do - target_content_type.ordered_entries_custom_fields.each_with_index do |_field, index| - - next if _field.name == field.inverse_of || _field.type == 'has_many' + - next if _field.name == field.inverse_of || %w(has_many many_to_many).include?(_field.type) = render "locomotive/custom_fields/types/#{_field.type}", :f => form, diff --git a/app/views/locomotive/theme_assets/_asset.html.haml b/app/views/locomotive/theme_assets/_asset.html.haml index f2349d42..80fc18c8 100644 --- a/app/views/locomotive/theme_assets/_asset.html.haml +++ b/app/views/locomotive/theme_assets/_asset.html.haml @@ -6,4 +6,6 @@ %span!= t('.updated_at') %span.date {{updated_at}} - = link_to 'x', '#', :class => 'remove', :confirm => t('locomotive.messages.confirm') \ No newline at end of file + {{#if can_be_deleted}} + = link_to 'x', '#', :class => 'remove', :confirm => t('locomotive.messages.confirm') + {{/if}} \ No newline at end of file diff --git a/app/views/locomotive/theme_assets/index.html.haml b/app/views/locomotive/theme_assets/index.html.haml index 3f049d7d..d4b11fd6 100644 --- a/app/views/locomotive/theme_assets/index.html.haml +++ b/app/views/locomotive/theme_assets/index.html.haml @@ -17,10 +17,10 @@ - content_for :backbone_view_data do :plain snippets: #{can?(:manage, Locomotive::Snippet) ? @snippets.map { |snippet| snippet.to_presenter.as_json_for_html_view }.to_json : 'null'}, - images: #{@assets[:images].to_json}, - media: #{@assets[:media].to_json}, - js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? @js_and_css_assets.to_json : 'null'}, - fonts: #{can?(:manage, Locomotive::ThemeAsset) ? @assets[:fonts].to_json : 'null'} + images: #{theme_assets_to_json(@assets[:images])}, + media: #{theme_assets_to_json(@assets[:media])}, + js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@js_and_css_assets) : 'null'}, + fonts: #{can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@assets[:fonts]) : 'null'} - content_for :submenu do = render_cell 'locomotive/settings_menu', :show diff --git a/features/backoffice/authorization/current_site.feature b/features/backoffice/authorization/current_site.feature index 3475f201..bad9ba6c 100644 --- a/features/backoffice/authorization/current_site.feature +++ b/features/backoffice/authorization/current_site.feature @@ -12,6 +12,7 @@ Background: When I go to site settings Then I should see "Log in" + @javascript Scenario: Accessing site settings as an Admin Given I am an authenticated "admin" When I go to site settings @@ -25,6 +26,7 @@ Background: And I should see delete on the "designer" And I should see delete on the "author" + @javascript Scenario: Accessing site settings as a Designer Given I am an authenticated "designer" When I go to site settings @@ -38,6 +40,7 @@ Background: And I should not see delete on myself And I should see delete on the "author" + @javascript Scenario: Accessing site settings as an Author Given I am an authenticated "author" When I go to site settings diff --git a/features/backoffice/authorization/inline_front_end_editing.feature b/features/backoffice/authorization/inline_front_end_editing.feature index 213b34eb..5f5d4be8 100644 --- a/features/backoffice/authorization/inline_front_end_editing.feature +++ b/features/backoffice/authorization/inline_front_end_editing.feature @@ -18,31 +18,28 @@ Feature: Inline frontend editing Scenario: As an unauthenticated user Given I am not authenticated When I view the rendered page at "/about" - Then I should not see "edit" - When I view the rendered page at "/about/edit" - Then I should not see "Page Content" + Then I should not see "Admin" + When I view the rendered page at "/about/_admin" + Then I should not see "Editing mode" And I should see "Log in" Scenario: Inline editing as an Admin Given I am an authenticated "admin" When I view the rendered page at "/about" - Then I should see "admin" - And I should see "edit" - When I view the rendered page at "/about/edit" - Then I should see "Page Content" + Then I should see "Admin" + When I view the rendered page at "/about/_admin" + Then I should see "Editing mode" Scenario: Inline editing as a Designer Given I am an authenticated "designer" When I view the rendered page at "/about" - Then I should see "admin" - And I should see "edit" - When I view the rendered page at "/about/edit" - Then I should see "Page Content" + Then I should see "Admin" + When I view the rendered page at "/about/_admin" + Then I should see "Editing mode" Scenario: Inline editing as an Author Given I am an authenticated "author" When I view the rendered page at "/about" - Then I should see "admin" - And I should see "edit" - When I view the rendered page at "/about/edit" - Then I should see "Page Content" + Then I should see "Admin" + When I view the rendered page at "/about/_admin" + Then I should see "Editing mode" diff --git a/features/backoffice/authorization/theme_assets.feature b/features/backoffice/authorization/theme_assets.feature index cc0011ef..c1b1cc05 100644 --- a/features/backoffice/authorization/theme_assets.feature +++ b/features/backoffice/authorization/theme_assets.feature @@ -13,6 +13,7 @@ Background: When I go to theme assets Then I should see "Log in" + @javascript Scenario: Accessing theme assets as an Admin Given I am an authenticated "admin" When I go to theme assets @@ -22,8 +23,9 @@ Background: And I should see "Style and javascript" And I should see "Images" And I should see "dog.png" - And I should see a delete image button + And I should see a delete link + @javascript Scenario: Accessing theme assets as a Designer Given I am an authenticated "designer" When I go to theme assets @@ -33,8 +35,9 @@ Background: And I should see "Style and javascript" And I should see "Images" And I should see "dog.png" - And I should see a delete image button + And I should see a delete link + @javascript Scenario: Accessing theme assets as an Author Given I am an authenticated "author" When I go to theme assets @@ -44,4 +47,4 @@ Background: And I should not see "Style and javascript" And I should see "Images" And I should see "dog.png" - And I should not see a delete image button + And I should not see a delete link diff --git a/features/backoffice/content_types.feature b/features/backoffice/content_types.feature deleted file mode 100644 index d8de23ef..00000000 --- a/features/backoffice/content_types.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Manage Content Types - In order to manage custom content models - As an administrator - I want to add/edit/delete custom models of my site - -Background: - Given I have the site: "test site" set up - And I have a custom model named "Projects" with - | label | type | required | - | Name | string | true | - | Description | text | false | - And I am an authenticated user - -@javascript -Scenario: I do not want my content form to have n duplicated fields if I submit n times the content type form with errors (bug) - When I go to the "Projects" model edition page - And I fill in "Name" with "" - And I press "Save" - And I press "Save" - And I press "Save" - When I follow "new item" - Then I should see once the "Name" field diff --git a/features/backoffice/content_types/has_many.feature b/features/backoffice/content_types/has_many.feature index e0c1f344..ebae8e76 100644 --- a/features/backoffice/content_types/has_many.feature +++ b/features/backoffice/content_types/has_many.feature @@ -5,15 +5,16 @@ Feature: Create and manage has many relationships Background: Given I have the site: "test site" set up - And I have a custom model named "Projects" with - | label | type | required | target | - | Name | string | true | | - | Description | text | false | | And I have a custom model named "Clients" with | label | type | required | target | | Name | string | true | | | Description | string | false | | - | Projects | has_many | false | Projects | + And I have a custom model named "Projects" with + | label | type | required | target | + | Name | string | true | | + | Description | text | false | | + | Client | belongs_to | false | Clients | + And I set up a has_many relationship between "Clients" and "Projects" And I have entries for "Clients" with | name | description | | Alpha, Inc | Description for Alpha, Inc | @@ -28,19 +29,33 @@ Background: @javascript Scenario: I view a client without any projects - When I go to the "Clients" model list page + When I go to the list of "Clients" And I follow "Alpha, Inc" - And I wait until the has many selector is visible - Then I should see "Empty" within the list of items + Then I should see "The list is empty" within the list of entries @javascript Scenario: I add a project to a client - When I go to the "Clients" model list page + When I go to the list of "Projects" + And I follow "Fun project" + And I select "Alpha, Inc" from "Client" + And I press "Save" + Then I should see "Entry was successfully updated." + When I go to the list of "Clients" + And I follow "Alpha, Inc" + Then I should see "Fun project" within the list of entries + +@javascript +Scenario: I add a project to a client from the client page + When I go to the list of "Clients" And I follow "Beta, Inc" - And I wait until the has many selector is visible - Then "Fun project" should be an option for "label" - And I press "+ add" - When I press "Save" - And I wait until the has many selector is visible - Then I should see "Fun project" within the list of added items - And "Fun project" should not be an option for "label" \ No newline at end of file + And I follow "+ Add a new entry" + Then I should see "Projects โ€” new entry" + When I press "Create" within the dialog popup + Then I should see "Entry was not created." + When I fill in "Name" with "Project X" within the dialog popup + And I fill in "Description" with "Lorem ipsum" within the dialog popup + And I sync my form with my backbone model because of Firefox + And I press "Create" within the dialog popup + Then I should see "Entry was successfully created." + And I should see "Project X" within the list of entries + And "p.empty" should not be visible within the list of entries diff --git a/features/backoffice/content_types/has_many_reverse.feature b/features/backoffice/content_types/has_many_reverse.feature deleted file mode 100644 index be0353f8..00000000 --- a/features/backoffice/content_types/has_many_reverse.feature +++ /dev/null @@ -1,61 +0,0 @@ -Feature: Set up a has many reverse relationship - In order to have a true 1:N relationship between 2 content types - As an administrator - I want to set up a reverse a has many relationship - -Background: - Given I have the site: "test site" set up - And I have a custom model named "Clients" with - | label | type | required | - | Name | string | true | - | Description | string | false | - And I have a custom model named "Projects" with - | label | type | required | target | - | Name | string | true | | - | Description | text | false | | - | Client | has_one | false | Clients | - And I set up a reverse has_many relationship between "Clients" and "Projects" - And I have entries for "Clients" with - | name | description | - | Apple Inc | Lorem ipsum | - | NoCoffee | Lorem ipsum... | - And I have entries for "Projects" with - | name | description | - | My sexy project | Lorem ipsum | - | Foo project | Lorem ipsum... | - | Bar project | Lorem ipsum... | - - And I am an authenticated user - -@javascript -Scenario: I do not see the "Add Item" button for new parent - When I go to the "Clients" model creation page - Then "New item" should not be an option for "label" - -@javascript -Scenario: I attach already created items for an existing parent and save it - When I go to the "Clients" model list page - And I follow "Apple Inc" - And I wait until the has many selector is visible - Then "My sexy project" should be an option for "label" - When I select "My sexy project" from "label" - And I press "+ add" - And "My sexy project" should not be an option for "label" - When I press "Save" - And I wait until the has many selector is visible - Then "My sexy project" should not be an option for "label" - -@javascript -Scenario: I create a new item and attach it - When I go to the "Clients" model list page - And I follow "Apple Inc" - And I wait until the has many selector is visible - And I press "+ add" - Then I should see "Apple Inc ยป Projects โ€” new item" - And I should not see "Client" within the main form - When I fill in "Name" with "iPad" - And I press "Create" - Then I should see "Content was successfully created." - When I wait until the has many selector is visible - Then I should see "iPad" - And "iPad" should not be an option for "label" \ No newline at end of file diff --git a/features/backoffice/content_types/many_to_many.feature b/features/backoffice/content_types/many_to_many.feature new file mode 100644 index 00000000..b7e26e15 --- /dev/null +++ b/features/backoffice/content_types/many_to_many.feature @@ -0,0 +1,42 @@ +Feature: Set up a many to many relationship + In order to have a N:N relationship between 2 content types + As an administrator + I want to set up a many to many relationship + +Background: + Given I have the site: "test site" set up + And I have a custom model named "Articles" with + | label | type | required | + | Title | string | true | + | Body | string | false | + And I have a custom model named "Projects" with + | label | type | required | target | + | Name | string | true | | + | Description | text | false | | + And I set up a many_to_many relationship between "Articles" and "Projects" + And I have entries for "Articles" with + | title | body | + | Hello world | Lorem ipsum | + | Lorem ipsum | Lorem ipsum... | + And I have entries for "Projects" with + | name | description | + | My sexy project | Lorem ipsum | + | Foo project | Lorem ipsum... | + | Bar project | Lorem ipsum... | + + And I am an authenticated user + +@javascript +Scenario: I attach projects to an article + When I go to the list of "Articles" + And I follow "Hello world" + Then I should see "The list is empty. Add an entry from the select box below." + When I select "My sexy project" from "entry" + And I follow "+ add" + Then I should see "My sexy project" within the list of entries + And "p.empty" should not be visible within the list of entries + When I press "Save" + Then I should see "Entry was successfully updated." + When I go to the list of "Projects" + And I follow "My sexy project" + Then I should see "Hello world" within the list of entries \ No newline at end of file diff --git a/features/backoffice/contents.feature b/features/backoffice/contents.feature index ef3ccf6f..476d5f51 100644 --- a/features/backoffice/contents.feature +++ b/features/backoffice/contents.feature @@ -19,11 +19,11 @@ Background: | Bar project | Lorem ipsum... | Design | Scenario: - When I go to the "Projects" model list page + When I go to the list of "Projects" Then I should see "My sexy project" Scenario: Add a new entry - When I go to the "Projects" model list page + When I go to the list of "Projects" And I follow "new entry" Then I should see "Projects โ€” new entry" When I fill in "Name" with "My other sexy project" @@ -32,39 +32,39 @@ Scenario: Add a new entry Then I should see "Entry was successfully created." Scenario: Add an invalid entry - When I go to the "Projects" model list page + When I go to the list of "Projects" And I follow "new entry" And I fill in "Description" with "Lorem ipsum...." And I press "Create" Then I should not see "Entry was successfully created." Scenario: Update an existing entry - When I go to the "Projects" model list page + When I go to the list of "Projects" And I follow "My sexy project" When I fill in "Name" with "My other sexy project (UPDATED)" And I press "Save" Then I should see "Entry was successfully updated." - When I go to the "Projects" model list page + When I go to the list of "Projects" Then I should see "My other sexy project (UPDATED)" Scenario: Update an invalid entry - When I go to the "Projects" model list page + When I go to the list of "Projects" And I follow "My sexy project" When I fill in "Name" with "" And I press "Save" Then I should not see "Entry was successfully updated." Scenario: Destroy an entry - When I go to the "Projects" model list page + When I go to the list of "Projects" And I follow "x" Then I should see "Entry was successfully deleted." And I should not see "My sexy project" Scenario: Group entries by category - When I go to the "Projects" model list page + When I go to the list of "Projects" Then I should not see "Development" And I should not see "Design" When I change the presentation of the "Projects" model by grouping items by "Category" - And I go to the "Projects" model list page + And I go to the list of "Projects" Then I should see "Development" And I should see "Design" \ No newline at end of file diff --git a/features/backoffice/pages.feature b/features/backoffice/pages.feature index 722e4b62..5905a48b 100644 --- a/features/backoffice/pages.feature +++ b/features/backoffice/pages.feature @@ -19,6 +19,7 @@ Scenario: Creating a valid page And I fill in "page_title" with "Test" And I fill in "Slug" with "test" And I select "Home page" from "Parent" + And I sync my form with my backbone model because of Firefox And I press "Create" Then I should see "Page was successfully created." And I should have "{% extends 'parent' %}" in the test page diff --git a/features/public/tablerow.feature b/features/public/tablerow.feature index 86355f3d..b461d8e0 100644 --- a/features/public/tablerow.feature +++ b/features/public/tablerow.feature @@ -8,10 +8,10 @@ Background: | label | type | required | | Name | string | true | And I have entries for "Projects" with - | name | - | Project 1 | - | Project 2 | - | Project 3 | + | name | _position | + | Project 1 | 1 | + | Project 2 | 2 | + | Project 3 | 3 | Scenario: Use the tablerow tag Given a page named "project-table" with the template: diff --git a/features/step_definitions/content_types_steps.rb b/features/step_definitions/content_types_steps.rb index 8451a3d8..c904d564 100644 --- a/features/step_definitions/content_types_steps.rb +++ b/features/step_definitions/content_types_steps.rb @@ -1,10 +1,13 @@ Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields| site = Locomotive::Site.first - content_type = FactoryGirl.build(:content_type, :site => site, :name => name) + content_type = FactoryGirl.build(:content_type, :site => site, :name => name, :order_by => '_position') fields.hashes.each do |field| - if (target_name = field.delete('target')).present? - target_content_type = site.content_types.where(:name => target_name).first - field['target'] = target_content_type.content_klass.to_s + # found a belongs_to association + if field['type'] == 'belongs_to' + target_name = field.delete('target') + target_model = @site.content_types.where(:name => target_name).first + + field['class_name'] = target_model.klass_with_custom_fields(:entries).to_s end content_type.entries_custom_fields.build field @@ -13,22 +16,6 @@ Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields| content_type.save.should be_true end -Given /^I set up a reverse has_many relationship between "([^"]*)" and "([^"]*)"$/ do |name_1, name_2| - site = Locomotive::Site.first - - content_type_1 = site.content_types.where(:name => name_1).first - content_type_2 = site.content_types.where(:name => name_2).first - - content_type_1.entries_custom_fields.build({ - :label => name_2, - :type => 'has_many', - :target => content_type_2.content_klass.to_s, - :reverse_lookup => content_type_2.content_klass.custom_field_alias_to_name(name_1.downcase.singularize) - }) - - content_type_1.save.should be_true -end - Given %r{^I have "([^"]*)" as "([^"]*)" values of the "([^"]*)" model$} do |values, field, name| content_type = Locomotive::ContentType.where(:name => name).first field = content_type.entries_custom_fields.detect { |f| f.label == field } @@ -62,7 +49,3 @@ end Then %r{^I should not see (\d+) times the "([^"]*)" field$} do |n, field| page.all(:css, "#content_#{field.underscore.downcase}_input").size.should_not == n.to_i end - -Then %r{^I should see once the "([^"]*)" field$} do |field| - page.should have_css("#content_#{field.underscore.downcase}_input", :count => 1) -end diff --git a/features/step_definitions/current_site_steps.rb b/features/step_definitions/current_site_steps.rb index abef1b24..94b0c839 100644 --- a/features/step_definitions/current_site_steps.rb +++ b/features/step_definitions/current_site_steps.rb @@ -1,9 +1,9 @@ Then /^I should see the role dropdown on the "([^"]*)"$/ do |user| - find(:css, "li.membership[data-role=#{user}] select").should be_present + find(:css, "#site_memberships_input div.entry[data-role=#{user}] select").should be_present end Then /^I should see the role dropdown on the "([^"]*)" without the "([^"]*)" option$/ do |user, option| - find(:css, "li.membership[data-role=#{user}] select").text.should_not include option + find(:css, "#site_memberships_input div.entry[data-role=#{user}] select").text.should_not include option end Then /^I should see the role dropdown on myself$/ do @@ -11,7 +11,7 @@ Then /^I should see the role dropdown on myself$/ do end Then /^I should not see the role dropdown on the "([^"]*)"$/ do |user| - page.has_css?("li.membership[data-role=#{user}] select").should be_false + page.has_css?("#site_memberships_input div.entry[data-role=#{user}] select").should be_false end Then /^I should not see the role dropdown on myself$/ do @@ -19,15 +19,15 @@ Then /^I should not see the role dropdown on myself$/ do end Then /^I should not see any role dropdowns$/ do - page.has_css?('li.membership select').should be_false + page.has_css?('#site_memberships_input div.entry select').should be_false end Then /^I should see delete on the "([^"]*)"$/ do |role| - page.has_css?("li.membership[data-role=#{role}] .actions a.remove").should be_true + page.has_css?("#site_memberships_input div.entry[data-role=#{role}] .actions a.remove").should be_true end Then /^I should not see delete on the "([^"]*)"$/ do |role| - page.has_css?("li.membership[data-role=#{role}] .actions a.remove").should be_false + page.has_css?("#site_memberships_input div.entry[data-role=#{role}] .actions a.remove").should be_false end Then /^I should not see delete on myself$/ do @@ -35,7 +35,7 @@ Then /^I should not see delete on myself$/ do end Then /^I should not see any delete buttons$/ do - page.has_css?('li.membership .actions a.remove').should be_false + page.has_css?('#site_memberships_input div.entry .actions a.remove').should be_false end When /^I select the "([^"]*)" role for the "author" user/ do |role| diff --git a/features/step_definitions/more_web_steps.rb b/features/step_definitions/more_web_steps.rb index 28c9e15c..eba8b90c 100644 --- a/features/step_definitions/more_web_steps.rb +++ b/features/step_definitions/more_web_steps.rb @@ -14,9 +14,20 @@ When /^I wait until ([^"]*) is visible$/ do |locator| page.has_css?(selector_for(locator), :visible => true) end +When /^I sync my form with my backbone model because of Firefox$/ do + page.execute_script("$(':input').trigger('change')") +end + +Then /^"([^"]*)" should not be visible$/ do |text| + begin + assert page.find(text).visible? != true + rescue Capybara::ElementNotFound + end +end + Then /^"([^"]*)" should( not)? be an option for "([^"]*)"(?: within "([^\"]*)")?$/ do |value, negate, field, selector| with_scope(selector) do expectation = negate ? :should_not : :should field_labeled(field).first(:xpath, ".//option[text() = '#{value}']").send(expectation, be_present) end -end \ No newline at end of file +end diff --git a/features/step_definitions/has_many_steps.rb b/features/step_definitions/relationships_steps.rb similarity index 63% rename from features/step_definitions/has_many_steps.rb rename to features/step_definitions/relationships_steps.rb index a215cc63..2a6823f8 100644 --- a/features/step_definitions/has_many_steps.rb +++ b/features/step_definitions/relationships_steps.rb @@ -15,9 +15,47 @@ Given %r{^I have an? "([^"]*)" model which has many "([^"]*)"$} do |parent_model :class_name => @child_model.klass_with_custom_fields(:entries).to_s, :inverse_of => parent_model.singularize.downcase }) + @parent_model.save end +Given %r{^I set up a has_many relationship between "([^"]*)" and "([^"]*)"$} do |source_name, target_name| + source_model = @site.content_types.where(:name => source_name).first + target_model = @site.content_types.where(:name => target_name).first + + source_model.entries_custom_fields.build({ + :label => target_name, + :type => 'has_many', + :class_name => target_model.klass_with_custom_fields(:entries).to_s, + :inverse_of => source_name.singularize.downcase + }) + + source_model.save +end + +Given %r{^I set up a many_to_many relationship between "([^"]*)" and "([^"]*)"$} do |first_name, last_name| + first_model = @site.content_types.where(:name => first_name).first + last_model = @site.content_types.where(:name => last_name).first + + first_model.entries_custom_fields.build({ + :label => last_name, + :type => 'many_to_many', + :class_name => last_model.klass_with_custom_fields(:entries).to_s, + :inverse_of => first_name.singularize.downcase + }) + + first_model.save + + last_model.entries_custom_fields.build({ + :label => first_name, + :type => 'many_to_many', + :class_name => first_model.klass_with_custom_fields(:entries).to_s, + :inverse_of => last_name.singularize.downcase + }) + + last_model.save +end + Then /^I should be able to view a paginaed list of a has many association$/ do # Create models step %{I have an "Articles" model which has many "Comments"} diff --git a/features/step_definitions/snippet_steps.rb b/features/step_definitions/snippet_steps.rb index c2522a27..aa2b0ac6 100644 --- a/features/step_definitions/snippet_steps.rb +++ b/features/step_definitions/snippet_steps.rb @@ -17,10 +17,6 @@ When /^I change the snippet template to "([^"]*)"$/ do |code| page.evaluate_script "window.application_view.view.editor.setValue('#{code}')" end -# Then /^I should see "([^"]*)" as the snippet template$/ do |code| -# find(:css, "#theme_asset_plain_text").value.should == code -# end - # checks to see if a string is in the slug Then /^I should have "(.*)" in the (.*) snippet/ do |content, snippet_slug| snippet = @site.snippets.where(:slug => snippet_slug).first diff --git a/features/step_definitions/theme_asset_steps.rb b/features/step_definitions/theme_asset_steps.rb index 8caeafcc..6cf5b71c 100644 --- a/features/step_definitions/theme_asset_steps.rb +++ b/features/step_definitions/theme_asset_steps.rb @@ -10,7 +10,6 @@ def create_plain_text_asset(name, type) :performing_plain_text => true }) - # asset.should be_valid asset.save! end @@ -25,7 +24,7 @@ Given /^a stylesheet asset named "([^"]*)"$/ do |name| end Given /^I have an image theme asset named "([^"]*)"$/ do |name| - @asset = FactoryGirl.create(:theme_asset, :site => @site, :source => File.open(Rails.root.join('spec', 'fixtures', 'assets', '5k.png'))) + @asset = FactoryGirl.create(:theme_asset, :site => @site, :source => File.open(Rails.root.join('..', 'fixtures', 'assets', '5k.png'))) @asset.source_filename = name @asset.save! end @@ -41,10 +40,10 @@ Then /^I should see "([^"]*)" as the theme asset code$/ do |code| find(:css, "#theme_asset_plain_text").value.should == code end -Then /^I should see a delete image button$/ do - page.has_css?("ul.theme-assets li .more a.remove").should be_true +Then /^I should see a delete link$/ do + page.has_css?(".box ul li .more a.remove").should be_true end -Then /^I should not see a delete image button$/ do - page.has_css?("ul.theme-assets li .more a.remove").should be_false +Then /^I should not see a delete link$/ do + page.has_css?(".box ul li .more a.remove").should be_false end diff --git a/features/support/env.rb b/features/support/env.rb index 022c96eb..cbbdcb91 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -40,6 +40,8 @@ Capybara.configure do |config| ensure_host_resolution(config.app_host) end +Capybara.default_wait_time = 5 + # Capybara.javascript_driver = :rack_test # Stop endless errors like diff --git a/features/support/paths.rb b/features/support/paths.rb index e71b3239..f5b4d62b 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -21,7 +21,7 @@ module NavigationHelpers when /new page/ new_page_path when /"(.*)" edition page/ - page = Site.first.pages.where(:slug => $1).first + page = Locomotive::Site.first.pages.where(:slug => $1).first edit_page_path(page) when /theme assets/ theme_assets_path @@ -29,15 +29,12 @@ module NavigationHelpers edit_current_site_path when /account settings/ edit_my_account_path - when /the "(.*)" model list page/ + when /the list of "(.*)"/ content_type = Locomotive::Site.first.content_types.where(:name => $1).first content_entries_path(content_type.slug) - when /the "(.*)" model creation page/ + when /the "(.*)" model edition page/ content_type = Locomotive::Site.first.content_types.where(:name => $1).first - new_content_entry_path(content_type.slug) - # when /the "(.*)" model edition page/ - # content_type = Locomotive::Site.first.content_types.where(:name => $1).first - # edit_content_entry_path(content_type) + edit_content_type_path(content_type) # Add more mappings here. # Here is an example that pulls values out of the Regexp: diff --git a/features/support/selectors.rb b/features/support/selectors.rb index 6b5a6bc2..81989d50 100644 --- a/features/support/selectors.rb +++ b/features/support/selectors.rb @@ -8,24 +8,24 @@ module HtmlSelectorsHelpers def selector_for(locator) case locator - when "the page" - "html > body" + when 'the page' + 'html > body' - when "the main form" - "form.formtastic" - - when "the list of added items" - ".has-many-selector li.item.added" - - when "the list of items" - ".has-many-selector" - - when "the has many selector" - ".has-many-selector ul li.template" + when 'the main form' + 'form.formtastic' + + when 'the dialog popup' + '.ui-dialog' + + when 'the list of entries' + 'li.input.relationship' when 'the role' '.role' - + + when 'the submit button' + 'form.formtastic #local-actions-bottom-bar input[type=submit]' + # Add more mappings here. # Here is an example that pulls values out of the Regexp: # diff --git a/lib/locomotive/render.rb b/lib/locomotive/render.rb index 68f54658..b9a42b42 100644 --- a/lib/locomotive/render.rb +++ b/lib/locomotive/render.rb @@ -102,7 +102,7 @@ module Locomotive flash.discard response.headers['Content-Type'] = 'text/html; charset=utf-8' - response.headers['Editable'] = 'true' unless self.editing_page? + response.headers['Editable'] = 'true' unless self.editing_page? || current_locomotive_account.nil? if @page.with_cache? fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true