radiant 1.0.1 → 1.1.0.alpha

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (51) hide show
  1. data/CHANGELOG.md +1 -1
  2. data/Gemfile +12 -2
  3. data/Gemfile.lock +1 -0
  4. data/README.md +1 -1
  5. data/app/models/standard_tags.rb +0 -75
  6. data/app/models/user_action_observer.rb +1 -1
  7. data/config/locales/en.yml +0 -11
  8. data/config/routes.rb +0 -1
  9. data/features/admin/configuration.feature +0 -1
  10. data/features/admin/layouts_management.feature +1 -1
  11. data/features/admin/user_permissions.feature +2 -39
  12. data/features/navigation_rendering.feature +1 -1
  13. data/features/step_definitions/admin/content_negotiation_steps.rb +0 -8
  14. data/features/step_definitions/admin/pagination_steps.rb +1 -19
  15. data/features/support/datasets_loader.rb +1 -1
  16. data/features/support/paths.rb +0 -6
  17. data/lib/generators/instance/templates/instance_environment.rb +2 -0
  18. data/lib/generators/instance/templates/instance_gemfile +11 -0
  19. data/lib/radiant.rb +3 -3
  20. data/lib/radiant/admin_ui.rb +1 -20
  21. data/radiant.gemspec +0 -10
  22. data/spec/controllers/admin/paginated_controller_spec.rb +3 -4
  23. data/spec/datasets/markup_pages_dataset.rb +14 -2
  24. data/spec/helpers/admin/pages_helper_spec.rb +0 -5
  25. data/spec/helpers/admin/references_helper_spec.rb +10 -8
  26. data/spec/helpers/application_helper_spec.rb +1 -2
  27. data/spec/lib/radiant/admin_ui/nav_tabs_spec.rb +3 -3
  28. data/spec/lib/radiant/admin_ui_spec.rb +2 -17
  29. data/spec/lib/radiant/initializer_spec.rb +4 -4
  30. data/spec/lib/radiant/taggable_spec.rb +1 -1
  31. data/spec/models/page_part_spec.rb +9 -8
  32. data/spec/models/page_spec.rb +19 -25
  33. data/spec/models/standard_tags_spec.rb +1 -60
  34. data/spec/models/text_filter_spec.rb +2 -2
  35. data/spec/models/user_action_observer_spec.rb +3 -5
  36. data/test/fixtures/extensions/basic/app/models/basic_extension_page.rb +2 -0
  37. metadata +789 -164
  38. data/app/controllers/admin/snippets_controller.rb +0 -8
  39. data/app/helpers/admin/snippets_helper.rb +0 -41
  40. data/app/models/snippet.rb +0 -23
  41. data/app/views/admin/snippets/_form.html.haml +0 -33
  42. data/app/views/admin/snippets/edit.html.haml +0 -9
  43. data/app/views/admin/snippets/index.html.haml +0 -33
  44. data/app/views/admin/snippets/new.html.haml +0 -7
  45. data/app/views/admin/snippets/remove.html.haml +0 -17
  46. data/features/admin/resource_pagination.feature +0 -27
  47. data/features/admin/snippets_management.feature +0 -57
  48. data/spec/controllers/admin/snippets_controller_spec.rb +0 -110
  49. data/spec/datasets/snippets_dataset.rb +0 -38
  50. data/spec/helpers/admin/snippets_helper_spec.rb +0 -4
  51. data/spec/models/snippet_spec.rb +0 -59
@@ -1,8 +0,0 @@
1
- class Admin::SnippetsController < Admin::ResourceController
2
- paginate_models
3
- only_allow_access_to :index, :show, :new, :create, :edit, :update, :remove, :destroy,
4
- :when => [:designer, :admin],
5
- :denied_url => { :controller => 'admin/pages', :action => 'index' },
6
- :denied_message => 'You must have designer privileges to perform this action.'
7
-
8
- end
@@ -1,41 +0,0 @@
1
- module Admin::SnippetsHelper
2
- def snippet_edit_javascripts
3
- <<-CODE
4
-
5
- var tagReferenceWindows = {};
6
- function loadTagReference() {
7
- var pageType = 'Page';
8
- if (!tagReferenceWindows[pageType])
9
- tagReferenceWindows[pageType] = new Popup.AjaxWindow("#{admin_reference_path('tags')}?class_name=" + encodeURIComponent(pageType), {reload: false});
10
- var window = tagReferenceWindows[pageType];
11
- if('Page' != pageType) {
12
- $('tag_reference_link').highlight();
13
- window.show();
14
- } else {
15
- window.toggle();
16
- }
17
- lastPageType = pageType;
18
- return false;
19
- }
20
-
21
- var lastFilter = '#{@snippet.filter_id}';
22
- var filterWindows = {};
23
- function loadFilterReference() {
24
- var filter = $F("snippet_filter_id");
25
- if (filter != "") {
26
- if (!filterWindows[filter]) filterWindows[filter] = new Popup.AjaxWindow("#{admin_reference_path('filters')}?filter_name="+encodeURIComponent(filter), {reload: false});
27
- var window = filterWindows[filter];
28
- if(lastFilter != filter) {
29
- window.show();
30
- } else {
31
- window.toggle();
32
- }
33
- lastFilter = filter;
34
- } else {
35
- alert('No documentation for filter.');
36
- }
37
- return false;
38
- }
39
- CODE
40
- end
41
- end
@@ -1,23 +0,0 @@
1
- class Snippet < ActiveRecord::Base
2
-
3
- # Default Order
4
- default_scope :order => 'name'
5
-
6
- # Associations
7
- belongs_to :created_by, :class_name => 'User'
8
- belongs_to :updated_by, :class_name => 'User'
9
-
10
- # Validations
11
- validates_presence_of :name
12
- validates_length_of :name, :maximum => 100
13
- validates_length_of :filter_id, :maximum => 25, :allow_nil => true
14
- validates_format_of :name, :with => %r{^\S*$}
15
- validates_uniqueness_of :name
16
-
17
- object_id_attr :filter, TextFilter
18
-
19
- def after_initialize
20
- self.filter_id ||= Radiant::Config['defaults.snippet.filter'] if new_record?
21
- end
22
-
23
- end
@@ -1,33 +0,0 @@
1
- - form_for [:admin, @snippet], :html => {'data-onsubmit_status' => onsubmit_status(@snippet)} do |f|
2
- = f.hidden_field :lock_version
3
- = render_region :form_top, :locals => {:f => f}
4
- .form_area
5
- - render_region :form, :locals => {:f => f} do |form|
6
- - form.edit_title do
7
- %p.title
8
- = f.label :name, t('name')
9
- = f.text_field :name, :class => 'textbox activate', :maxlength => 100
10
- - form.edit_content do
11
- %p.content
12
- = f.label :content, t('body')
13
- ~ f.text_area :content, :class => "textarea large", :style => "width: 100%"
14
- - form.edit_filter do
15
- .set
16
- %p
17
- = f.label :filter_id, t('filter')
18
- = f.select :filter_id, filter_options_for_select(f.object.filter_id), :id => 'snippet_filter'
19
- %span.reference_links
20
- == #{t('reference')}:
21
- %span{:id => "filter_reference_link"}
22
- = link_to_function t('filter'), "loadFilterReference();"
23
- %span{:id => "tag_reference_link"}
24
- = link_to_function t('available_tags'), "loadTagReference('Page');"
25
- - render_region :form_bottom, :locals => {:f => f} do |form_bottom|
26
- - form_bottom.edit_buttons do
27
- .buttons{:style=>"clear: left"}
28
- = save_model_button(@snippet)
29
- = save_model_and_continue_editing_button(@snippet)
30
- = t('or')
31
- = link_to t('cancel'), admin_snippets_url
32
- - form_bottom.edit_timestamp do
33
- = updated_stamp @snippet
@@ -1,9 +0,0 @@
1
- - @page_title = @snippet.name + ' ' + t('snippet') + ' - ' + default_page_title
2
-
3
- - render_region :main do |main|
4
- - main.edit_header do
5
- %h1= t('edit_snippet')
6
- - main.edit_form do
7
- = render :partial => 'form'
8
-
9
- - content_for 'page_scripts', snippet_edit_javascripts
@@ -1,33 +0,0 @@
1
- - @page_title = t('snippets') + ' - ' + default_page_title
2
-
3
- .outset
4
- = render_region :top
5
- %table.index#snippets
6
- %thead
7
- %tr
8
- - render_region :thead do |thead|
9
- - thead.title_header do
10
- %th.name= t('snippet')
11
- - thead.actions_header do
12
- %th.actions{:style=>"width:9em"}= t('modify')
13
- %tbody
14
- - if @snippets.any?
15
- - @snippets.each do |snippet|
16
- %tr[snippet]
17
- - render_region :tbody, :locals => {:snippet => snippet} do |tbody|
18
- - tbody.title_cell do
19
- %td.name
20
- = link_to image('snippet', :alt => '') + ' ' + snippet.name, edit_admin_snippet_url(snippet)
21
- - tbody.actions_cell do
22
- %td.actions
23
- = link_to image('minus') + ' ' + t('remove'), remove_admin_snippet_url(snippet), :class => "action"
24
- - else
25
- %tr
26
- %td.empty{:colspan => admin.snippet.index.tbody.length}= t('no_snippets')
27
-
28
- - render_region :bottom do |bottom|
29
- - bottom.new_button do
30
- #actions
31
- = pagination_for(@snippets)
32
- %ul
33
- %li= link_to image('plus') + " " + t('new_snippet'), new_admin_snippet_url, :class => 'action_button'
@@ -1,7 +0,0 @@
1
- - render_region :main do |main|
2
- - main.edit_header do
3
- %h1= t('new_snippet')
4
- - main.edit_form do
5
- = render :partial => 'form'
6
-
7
- - content_for 'page_scripts', snippet_edit_javascripts
@@ -1,17 +0,0 @@
1
- %h1= t('remove_snippet')
2
-
3
- %p
4
- = t('text.snippets.remove_warning')
5
-
6
- %table.index#snippets
7
- %tbody
8
- %tr.node.level_1
9
- %td.snippet
10
- = image('snippet', :alt => "")
11
- %span.title= @snippet.name
12
-
13
- - form_for [:admin, @snippet], :html => {:method => :delete, 'data-onsubmit_status'=>"Removing snippet&#8230;"} do
14
- .buttons
15
- %input.button{:type=>"submit", :value => t('delete_snippet')}/
16
- = t('or')
17
- = link_to t('cancel'), admin_snippets_url
@@ -1,27 +0,0 @@
1
- Feature: Paginating admin views
2
- In order to reduce load time and page bulk
3
- a content editor
4
- wants longer resource lists to be paginated
5
-
6
- Background:
7
- Given There are many snippets
8
- And I am logged in as "designer"
9
- And I go to the "snippets" admin page
10
-
11
- Scenario: More snippets than we want to show on one page
12
- Then I should see "first"
13
- And I should not see "snippet_50"
14
- And I should see page 1 of the results
15
- And I should see pagination controls
16
- And I should see a depagination link
17
-
18
- When I follow "2" within "div.pagination"
19
- Then I should see page 2 of the results
20
- And I should see "snippet_50"
21
-
22
- When I follow "show all"
23
- # Then I should mention the request parameters
24
- Then I should see all the snippets
25
- And I should not see pagination controls
26
- And I should not see a depagination link
27
-
@@ -1,57 +0,0 @@
1
- Feature: Managing snippets
2
- In order to share content between layouts and pages, as a designer I want to
3
- manage a collection of snippets
4
-
5
- Background:
6
- Given I am logged in as "designer"
7
-
8
- Scenario: List snippets
9
- When I follow "Design" within "#navigation"
10
- And I follow "Snippets"
11
- Then I should see "first"
12
- And I should see "another"
13
- And I should see "markdown"
14
- # And a host of others
15
-
16
- Scenario: Create a snippet
17
- When I follow "Design" within "#navigation"
18
- And I follow "Snippets"
19
- And I follow "New Snippet"
20
- And I fill in "Name" with "Mine"
21
- And I fill in "Body" with "My snippet"
22
- And I press "Create Snippet"
23
- Then I should be on the snippets list
24
- And I should see "Mine"
25
-
26
- Scenario: Display form errors
27
- When I follow "Design" within "#navigation"
28
- And I follow "Snippets"
29
- And I follow "New Snippet"
30
- And I fill in "Body" with "My snippet"
31
- And I press "Create Snippet"
32
- Then I should see an error message
33
- And I should see the form
34
-
35
- Scenario: Continue editing
36
- When I follow "Design" within "#navigation"
37
- And I follow "Snippets"
38
- And I follow "New Snippet"
39
- And I fill in "Name" with "Mine"
40
- And I fill in "Body" with "My snippet"
41
- And I press "Save and Continue Editing"
42
- Then I should see "Edit Snippet"
43
- And I should see the form
44
-
45
- Scenario: View a snippet
46
- When I view a filtered snippet
47
- Then I should see "Edit Snippet"
48
- And I should see "Markdown"
49
-
50
- Scenario: Delete a snippet with confirmation
51
- When I follow "Design" within "#navigation"
52
- And I follow "Snippets"
53
- And I follow "Remove"
54
- Then I should see "permanently remove"
55
- And I should see "another"
56
- When I press "Delete Snippet"
57
- Then I should not see "another"
@@ -1,110 +0,0 @@
1
- require File.dirname(__FILE__) + "/../../spec_helper"
2
-
3
- describe Admin::SnippetsController do
4
- dataset :users, :snippets
5
-
6
- before :each do
7
- ActionController::Routing::Routes.reload
8
- login_as :designer
9
- end
10
-
11
- it "should be an ResourceController" do
12
- controller.should be_kind_of(Admin::ResourceController)
13
- end
14
-
15
- it "should handle Snippets" do
16
- controller.class.model_class.should == Snippet
17
- end
18
-
19
-
20
- describe "show" do
21
- it "should redirect to the edit action" do
22
- get :show, :id => 1
23
- response.should redirect_to(edit_admin_snippet_path(params[:id]))
24
- end
25
-
26
- it "should show xml when format is xml" do
27
- snippet = Snippet.first
28
- get :show, :id => snippet.id, :format => "xml"
29
- response.body.should == snippet.to_xml
30
- end
31
- end
32
-
33
- describe "with invalid snippet id" do
34
- [:edit, :remove].each do |action|
35
- before do
36
- @parameters = {:id => 999}
37
- end
38
- it "should redirect the #{action} action to the index action" do
39
- get action, @parameters
40
- response.should redirect_to(admin_snippets_path)
41
- end
42
- it "should say that the 'Snippet could not be found.' after the #{action} action" do
43
- get action, @parameters
44
- flash[:notice].should == 'Snippet could not be found.'
45
- end
46
- end
47
- it 'should redirect the update action to the index action' do
48
- put :update, @parameters
49
- response.should redirect_to(admin_snippets_path)
50
- end
51
- it "should say that the 'Snippet could not be found.' after the update action" do
52
- put :update, @parameters
53
- flash[:notice].should == 'Snippet could not be found.'
54
- end
55
- it 'should redirect the destroy action to the index action' do
56
- delete :destroy, @parameters
57
- response.should redirect_to(admin_snippets_path)
58
- end
59
- it "should say that the 'Snippet could not be found.' after the destroy action" do
60
- delete :destroy, @parameters
61
- flash[:notice].should == 'Snippet could not be found.'
62
- end
63
- end
64
-
65
- {:get => [:index, :show, :new, :edit, :remove],
66
- :post => [:create],
67
- :put => [:update],
68
- :delete => [:destroy]}.each do |method, actions|
69
- actions.each do |action|
70
- it "should require login to access the #{action} action" do
71
- logout
72
- lambda { send(method, action, :id => snippet_id(:first)) }.should require_login
73
- end
74
-
75
- if action == :show
76
- it "should request authentication for API access on show" do
77
- logout
78
- send(method, action, :id => snippet_id(:first), :format => "xml")
79
- response.response_code.should == 401
80
- end
81
- else
82
- it "should allow access to designers for the #{action} action" do
83
- lambda {
84
- send(method, action, :id => snippet_id(:first))
85
- }.should restrict_access(:allow => [users(:designer)],
86
- :url => '/admin/pages')
87
- end
88
-
89
- it "should allow access to admins for the #{action} action" do
90
- lambda {
91
- send(method, action, :id => snippet_id(:first))
92
- }.should restrict_access(:allow => [users(:designer)],
93
- :url => '/admin/pages')
94
- end
95
-
96
- it "should deny non-designers and non-admins for the #{action} action" do
97
- lambda {
98
- send(method, action, :id => Snippet.first.id)
99
- }.should restrict_access(:deny => [users(:non_admin), users(:existing)],
100
- :url => '/admin/pages')
101
- end
102
- end
103
- end
104
- end
105
-
106
- it "should clear the page cache when saved" do
107
- Radiant::Cache.should_receive(:clear)
108
- put :update, :id => snippet_id(:first), :snippet => {:content => "Foobar."}
109
- end
110
- end
@@ -1,38 +0,0 @@
1
- class SnippetsDataset < Dataset::Base
2
-
3
- def load
4
- create_snippet "first", :content => "test"
5
- create_snippet "another", :content => "another test"
6
- create_snippet "markdown", :filter_id => "Markdown", :content => "**markdown**"
7
- create_snippet "radius", :content => "<r:title />"
8
- create_snippet "global_page_cascade", :content => "<r:children:each><r:page:title /> </r:children:each>"
9
- create_snippet "recursive", :content => "<r:children:each><r:snippet name='recursive' /></r:children:each><r:title />"
10
- create_snippet "yielding", :content => "Before...<r:yield/>...and after"
11
- create_snippet "div_wrap", :content => "<div><r:yield/></div>"
12
- create_snippet "nested_yields", :content => '<snippet name="div_wrap">above <r:yield/> below</snippet>'
13
- create_snippet "yielding_often", :content => '<r:yield/> is <r:yield/>er than <r:yield/>'
14
- end
15
-
16
- helpers do
17
- def create_snippet(name, attributes={})
18
- create_record :snippet, name.symbolize, snippet_params(attributes.reverse_merge(:name => name))
19
- end
20
-
21
- def snippet_params(attributes={})
22
- name = attributes[:name] || unique_snippet_name
23
- {
24
- :name => name,
25
- :content => "<r:content />"
26
- }.merge(attributes)
27
- end
28
-
29
- private
30
-
31
- def unique_snippet_name
32
- @@unique_snippet_name_call_count ||= 0
33
- @@unique_snippet_name_call_count += 1
34
- "snippet-#{@@unique_snippet_name_call_count}"
35
- end
36
- end
37
-
38
- end
@@ -1,4 +0,0 @@
1
- require File.dirname(__FILE__) + "/../../spec_helper"
2
-
3
- describe Admin::SnippetsHelper do
4
- end
@@ -1,59 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- describe Snippet do
4
- dataset :snippets
5
- test_helper :validations
6
-
7
- before :each do
8
- @original_filter = Radiant::Config['defaults.snippet.filter']
9
- @snippet = @model = Snippet.new(snippet_params)
10
- end
11
-
12
- after :each do
13
- Radiant::Config['defaults.snippet.filter'] = @original_filter
14
- end
15
-
16
- it "should take the filter from the default filter" do
17
- Radiant::Config['defaults.snippet.filter'] = "Textile"
18
- snippet = Snippet.new :name => 'new-snippet'
19
- snippet.filter_id.should == "Textile"
20
- end
21
-
22
- it "shouldn't override existing snippets filters with the default filter" do
23
- snippet = Snippet.find(:first, :conditions => {:filter_id => nil})
24
- Radiant::Config['defaults.snippet.filter'] = "Textile"
25
- snippet.reload
26
- snippet.filter_id.should_not == "Textile"
27
- end
28
-
29
- it 'should validate length of' do
30
- {
31
- :name => 100,
32
- :filter_id => 25
33
- }.each do |field, max|
34
- assert_invalid field, ('this must not be longer than %d characters' % max), 'x' * (max + 1)
35
- assert_valid field, 'x' * max
36
- end
37
- end
38
-
39
- it 'should validate presence of' do
40
- [:name].each do |field|
41
- assert_invalid field, 'this must not be blank', '', ' ', nil
42
- end
43
- end
44
-
45
- it 'should validate uniqueness of' do
46
- assert_invalid :name, 'this name is already in use', 'first', 'another', 'markdown'
47
- assert_valid :name, 'just-a-test'
48
- end
49
-
50
- it 'should validate format of name' do
51
- assert_valid :name, 'abc', 'abcd-efg', 'abcd_efg', 'abc.html', '/', '123'
52
- assert_invalid :name, 'cannot contain spaces or tabs'
53
- end
54
-
55
- it 'should allow the filter to be specified' do
56
- @snippet = snippets(:markdown)
57
- @snippet.filter.should be_kind_of(MarkdownFilter)
58
- end
59
- end