mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-16 23:30:12 +01:00
Applied changes to context corresponding to yesterday's project changeset: tests, prohibit slashes, introduce RJS, relocate new context form.
git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@266 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
2796e3a4eb
commit
d6ac8086d6
9 changed files with 125 additions and 69 deletions
|
|
@ -35,16 +35,10 @@ class ContextController < ApplicationController
|
|||
# Creates a new context via Ajax helpers
|
||||
#
|
||||
def new_context
|
||||
context = @user.contexts.build
|
||||
context.attributes = params['context']
|
||||
context.name = deurlize(context.name)
|
||||
|
||||
if context.save
|
||||
render :partial => 'context_listing', :locals => { :context_listing => context }
|
||||
else
|
||||
flash["warning"] = "Couldn't add new context"
|
||||
render :text => "#{flash["warning"]}"
|
||||
end
|
||||
@context = @user.contexts.build
|
||||
@context.attributes = params['context']
|
||||
@context.name = deurlize(@context.name)
|
||||
@saved = @context.save
|
||||
end
|
||||
|
||||
# Called by a form button
|
||||
|
|
|
|||
|
|
@ -1,2 +1,12 @@
|
|||
module ContextHelper
|
||||
|
||||
def get_listing_sortable_options
|
||||
{
|
||||
:tag => 'div',
|
||||
:handle => 'handle',
|
||||
:complete => visual_effect(:highlight, 'list-contexts'),
|
||||
:url => {:controller => 'context', :action => 'order'}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ class Context < ActiveRecord::Base
|
|||
attr_protected :user
|
||||
|
||||
# Context name must not be empty
|
||||
# and must be less than 255 bytes
|
||||
# and must be less than 256 characters
|
||||
validates_presence_of :name, :message => "context must have a name"
|
||||
validates_length_of :name, :maximum => 255, :message => "context name must be less than %d"
|
||||
validates_length_of :name, :maximum => 255, :message => "context name must be less than 256 characters"
|
||||
validates_uniqueness_of :name, :message => "already exists", :scope => "user_id"
|
||||
validates_format_of :name, :with => /^[^\/]*$/i, :message => "cannot contain the slash ('/') character"
|
||||
|
||||
def self.list_of(hidden=false)
|
||||
find(:all, :conditions => [ "hide = ?" , hidden ], :order => "position ASC")
|
||||
|
|
|
|||
|
|
@ -1,48 +1,32 @@
|
|||
<div id="full_width_display">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<div id="display_box">
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<div id="<%= name %>"<%= flash[name] ? "" : " style=\"display:none\""%>><%= flash[name] %></div>
|
||||
<% end %>
|
||||
|
||||
<div id="list-contexts">
|
||||
<% for context in @contexts %>
|
||||
<%= render_partial( 'context_listing', context ) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% sortable_options = {
|
||||
:tag => 'div',
|
||||
:handle => 'handle',
|
||||
:complete => visual_effect(:highlight, 'list-contexts'),
|
||||
:url => {:controller => 'context', :action => 'order'}
|
||||
}%>
|
||||
<%= sortable_element 'list-contexts', sortable_options %>
|
||||
<br />
|
||||
<a href="javascript:void(0)" onClick="Element.toggle('context_new'); Form.focusFirstElement('context-form');" accesskey="n" title="Create a new context">Create new context »</a>
|
||||
<div id="context_new" class="context_new" style="display:none">
|
||||
<!--[form:context]-->
|
||||
<%= form_remote_tag :url => { :action => "new_context" },
|
||||
:update=> "list-contexts",
|
||||
:position=> "bottom",
|
||||
:loading => "Form.reset('context-form')",
|
||||
:complete => "Sortable.create('list-contexts', #{options_for_javascript(sortable_options)});Form.focusFirstElement('context-form');",
|
||||
:html=> { :id=>'context-form', :name=>'context', :class => 'inline-form' } %>
|
||||
<%= hidden_field( "context", "id" ) %>
|
||||
<label for="context_name">Context name</label>
|
||||
<%= text_field( "context", "name" ) %>
|
||||
<label for="new_context_on_front">Hide from front page?</label>
|
||||
<%= check_box( "context", "hide" ) %>
|
||||
<input type="submit" value="Add" />
|
||||
<%= end_form_tag %>
|
||||
<!--[eoform:context]-->
|
||||
<div id="list-contexts">
|
||||
<% for context in @contexts %>
|
||||
<%= render_partial( 'context_listing', context ) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= sortable_element 'list-contexts', get_listing_sortable_options %>
|
||||
</div>
|
||||
|
||||
<% if flash["confirmation"] %>
|
||||
<div class="confirmation"><%= flash["confirmation"] %></div>
|
||||
<% end %>
|
||||
<% if flash["warning"] %>
|
||||
<div class="warning"><%= flash["warning"] %></div>
|
||||
<% end %>
|
||||
|
||||
</div><!-- End of display_box -->
|
||||
<div id="input_box">
|
||||
<a href="javascript:void(0)" onClick="Element.toggle('context_new'); Form.focusFirstElement('context-form');" accesskey="n" title="Create a new context">Create new context »</a>
|
||||
<div id="context_new" class="context_new" style="display:none">
|
||||
<!--[form:context]-->
|
||||
<%= form_remote_tag :url => { :action => "new_context" }, :html=> { :id=>'context-form', :name=>'context', :class => 'inline-form' } %>
|
||||
<%= hidden_field( "context", "id" ) %>
|
||||
<label for="context_name">Context name</label>
|
||||
<br />
|
||||
<%= text_field( "context", "name" ) %>
|
||||
<br />
|
||||
<label for="new_context_on_front">Hide from front page?</label>
|
||||
<%= check_box( "context", "hide" ) %>
|
||||
<br />
|
||||
<input type="submit" value="Add" />
|
||||
<%= end_form_tag %>
|
||||
<!--[eoform:context]-->
|
||||
</div>
|
||||
</div>
|
||||
11
tracks/app/views/context/new_context.rjs
Normal file
11
tracks/app/views/context/new_context.rjs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
if @saved
|
||||
page.hide "warning"
|
||||
page.insert_html :bottom, "list-contexts", :partial => 'context_listing', :locals => { :context_listing => @context }
|
||||
page.sortable "list-contexts", get_listing_sortable_options
|
||||
page.call "Form.reset", "context-form"
|
||||
page.call "Form.focusFirstElement", "context-form"
|
||||
else
|
||||
page.hide "warning"
|
||||
page.replace_html "warning", content_tag("div", content_tag("h2", "#{pluralize(@context.errors.count, "error")} prohibited this record from being saved") + content_tag("p", "There were problems with the following fields:") + content_tag("ul", @context.errors.each_full { |msg| content_tag("li", msg) }), "id" => "ErrorExplanation", "class" => "ErrorExplanation")
|
||||
page.visual_effect :appear, 'warning', :duration => 0.5
|
||||
end
|
||||
|
|
@ -17,10 +17,15 @@
|
|||
<!--[form:project]-->
|
||||
<%= form_remote_tag :url => { :action => "new_project" },
|
||||
:html=> { :id=>'project-form', :name=>'project', :class => 'inline-form' } %>
|
||||
<label for="project_name">Name:</label><br />
|
||||
<%= text_field 'project', 'name' %><br />
|
||||
<label for="project_description">Description (optional):</label><br />
|
||||
<%= text_area 'project', 'description', "cols" => 30, "rows" => 4 %> <input type="submit" value="Add" />
|
||||
<label for="project_name">Name:</label>
|
||||
<br />
|
||||
<%= text_field 'project', 'name' %>
|
||||
<br />
|
||||
<label for="project_description">Description (optional):</label>
|
||||
<br />
|
||||
<%= text_area 'project', 'description', "cols" => 30, "rows" => 4 %>
|
||||
<br />
|
||||
<input type="submit" value="Add" />
|
||||
<%= end_form_tag %>
|
||||
<!--[eoform:project]-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,13 +5,34 @@ require 'context_controller'
|
|||
class ContextController; def rescue_action(e) raise e end; end
|
||||
|
||||
class ContextControllerTest < Test::Unit::TestCase
|
||||
fixtures :users, :contexts
|
||||
|
||||
def setup
|
||||
@controller = ContextController.new
|
||||
request, response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
||||
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
def test_create_context
|
||||
num_contexts = Context.count
|
||||
@request.session['user_id'] = users(:other_user).id
|
||||
xhr :post, :new_context, :context => {:name => 'newcontext'}
|
||||
assert_rjs :hide, "warning"
|
||||
assert_rjs :insert_html, :bottom, "list-contexts"
|
||||
assert_rjs :sortable, 'list-contexts', { :tag => 'div', :handle => 'handle', :complete => visual_effect(:highlight, 'list-contexts'), :url => {:controller => 'context', :action => 'order'} }
|
||||
# not yet sure how to write the following properly...
|
||||
assert_rjs :call, "Form.reset", "context-form"
|
||||
assert_rjs :call, "Form.focusFirstElement", "context-form"
|
||||
assert_equal num_contexts + 1, Context.count
|
||||
end
|
||||
|
||||
def test_create_with_slash_in_name_fails
|
||||
num_contexts = Context.count
|
||||
@request.session['user_id'] = users(:other_user).id
|
||||
xhr :post, :new_context, :context => {:name => 'foo/bar'}
|
||||
assert_rjs :hide, "warning"
|
||||
assert_rjs :replace_html, 'warning', "<div class=\"ErrorExplanation\" id=\"ErrorExplanation\"><h2>1 error prohibited this record from being saved</h2><p>There were problems with the following fields:</p><ul>Name cannot contain the slash ('/') character</ul></div>"
|
||||
assert_rjs :visual_effect, :appear, "warning", :duration => '0.5'
|
||||
assert_equal num_contexts, Context.count
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,8 +3,38 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|||
class ContextTest < Test::Unit::TestCase
|
||||
fixtures :contexts
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
def setup
|
||||
@agenda = contexts(:agenda)
|
||||
@email = contexts(:email)
|
||||
end
|
||||
|
||||
def test_validate_presence_of_name
|
||||
@agenda.name = ""
|
||||
assert !@agenda.save
|
||||
assert_equal 1, @agenda.errors.count
|
||||
assert_equal "context must have a name", @agenda.errors.on(:name)
|
||||
end
|
||||
|
||||
def test_validate_name_is_less_than_256
|
||||
@agenda.name = "a"*256
|
||||
assert !@agenda.save
|
||||
assert_equal 1, @agenda.errors.count
|
||||
assert_equal "context name must be less than 256 characters", @agenda.errors.on(:name)
|
||||
end
|
||||
|
||||
def test_validate_name_is_unique
|
||||
newcontext = Context.new
|
||||
newcontext.name = contexts(:agenda).name
|
||||
assert !newcontext.save
|
||||
assert_equal 1, newcontext.errors.count
|
||||
assert_equal "already exists", newcontext.errors.on(:name)
|
||||
end
|
||||
|
||||
def test_validate_name_does_not_contain_slash
|
||||
newcontext = Context.new
|
||||
newcontext.name = "phone/telegraph"
|
||||
assert !newcontext.save
|
||||
assert_equal 1, newcontext.errors.count
|
||||
assert_equal "cannot contain the slash ('/') character", newcontext.errors.on(:name)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ class ProjectTest < Test::Unit::TestCase
|
|||
fixtures :projects
|
||||
|
||||
def setup
|
||||
@timemachine = Project.find(1)
|
||||
@moremoney = Project.find(2)
|
||||
@timemachine = projects(:timemachine)
|
||||
@moremoney = projects(:moremoney)
|
||||
end
|
||||
|
||||
def test_validate_presence_of_name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue