Rename new_context and new_project actions to create to fit into the CRUD model, add tests for these methods, too.

Add a plugin to allow executing tests using an in-memory sqlite database. Faster!



git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@318 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2006-09-16 06:50:22 +00:00
parent 3e22381187
commit ba3757f29e
29 changed files with 416 additions and 114 deletions

View file

@ -66,6 +66,10 @@ class ApplicationController < ActionController::Base
redirect_with_flash message, options
end
def render_failure message, status = 404
render :text => message, :status => status
end
private
def get_current_user

View file

@ -32,14 +32,14 @@ class BackendController < ApplicationController
# Check whether the token in the URL matches the word in the User's table
def check_token_against_user_word(username, token)
@user = User.find_by_login( username )
unless ( token == @user.word)
raise (InvalidToken, "Sorry, you don't have permission to perform this action.")
unless (token == @user.word)
raise(InvalidToken, "Sorry, you don't have permission to perform this action.")
end
end
def check_context_belongs_to_user(context_id)
unless @user.contexts.exists? context_id
raise (CannotAccessContext, "Cannot access a context that does not belong to this user.")
raise(CannotAccessContext, "Cannot access a context that does not belong to this user.")
end
end

View file

@ -32,14 +32,33 @@ class ContextController < ApplicationController
@page_title = "TRACKS::Context: #{@context.name}"
end
# Creates a new context via Ajax helpers
# Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
# -u username:password
# -d '<request><context><name>new context_name</name></context></request>'
# http://our.tracks.host/context/create
#
def new_context
def create
@context = @user.contexts.build
@context.attributes = params['context']
params_are_invalid = true
if (params['context'] || (params['request'] && params['request']['context']))
@context.attributes = params['context'] || params['request']['context']
params_are_invalid = false
end
@context.name = deurlize(@context.name)
@saved = @context.save
@context_not_done_counts = { @context.id => 0 }
respond_to do |wants|
wants.js
wants.xml do
if @context.new_record? && params_are_invalid
render_failure "Expected post format is xml like so: <request><context><name>context name</name></context></request>."
elsif @context.new_record?
render_failure @context.errors.full_messages.join(', ')
else
render :xml => @context.to_xml( :except => :user_id )
end
end
end
end
# Called by a form button

View file

@ -56,12 +56,33 @@ class ProjectController < ApplicationController
end
end
def new_project
# Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
# -u username:password
# -d '<request><project><name>new project_name</name></project></request>'
# http://our.tracks.host/project/create
#
def create
@project = @user.projects.build
@project.attributes = params['project']
params_are_invalid = true
if (params['project'] || (params['request'] && params['request']['project']))
@project.attributes = params['project'] || params['request']['project']
params_are_invalid = false
end
@project.name = deurlize(@project.name)
@saved = @project.save
@project_not_done_counts = { @project.id => 0 }
respond_to do |wants|
wants.js
wants.xml do
if @project.new_record? && params_are_invalid
render_failure "Expected post format is xml like so: <request><project><name>project name</name></project></request>."
elsif @project.new_record?
render_failure @project.errors.full_messages.join(', ')
else
render :xml => @project.to_xml( :except => :user_id )
end
end
end
end
# Called by a form button

View file

@ -47,16 +47,14 @@ class TodoController < ApplicationController
end
end
# Called by a form button
# Parameters from form fields are passed to create new action
# in the selected context.
def add_item
def create
init
@item = @user.todos.build
@item.attributes = params["todo"]
p = params['todo'] || params['request']['todo']
@item.attributes = p
if @item.due?
@item.due = parse_date_per_user_prefs(params["todo"]["due"])
@item.due = parse_date_per_user_prefs(p["due"])
else
@item.due = ""
end
@ -70,7 +68,7 @@ class TodoController < ApplicationController
init_todos
@up_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s
end
render
render :action => 'create'
end
wants.xml { render :xml => @item.to_xml( :root => 'todo', :except => :user_id ) }
end
@ -86,6 +84,10 @@ class TodoController < ApplicationController
wants.xml { render :text => 'An error occurred on the server.' + $! }
end
end
def add_item
create
end
def edit
init

View file

@ -18,7 +18,7 @@ class UserController < ApplicationController
# Example usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
# -u admin:up2n0g00d
# -d '<request><login>username</login><password>abc123</password></request>'
# http://our.tracks.host/cpa/create_user
# http://our.tracks.host/user/create
#
def create
admin = User.find_admin
@ -108,11 +108,7 @@ class UserController < ApplicationController
end
private
def render_failure message, status = 404
render :text => message, :status => status
end
def check_create_user_params
return false unless params.has_key?(:request)
return false unless params[:request].has_key?(:login)

View file

@ -41,7 +41,7 @@
<%= end_form_tag %>
</div><!-- [end:context-context.id-edit-form] -->
</div><!-- [end:context_context.id] -->
<% if controller.action_name == 'new_context' %>
<% if controller.action_name == 'create' %>
<script>
new Effect.Appear('context-<%= context.id %>');
</script>

View file

@ -16,7 +16,7 @@
<a href="javascript:void(0)" onClick="Element.toggle('context_new'); Form.focusFirstElement('context-form');" accesskey="n" title="Create a new context">Create new context &#187;</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' } %>
<%= form_remote_tag :url => { :action => "create" }, :html=> { :id=>'context-form', :name=>'context', :class => 'inline-form' } %>
<%= hidden_field( "context", "id" ) %>
<label for="context_name">Context name</label>
<br />

View file

@ -39,7 +39,7 @@
<%= end_form_tag %>
</div><!-- [end:project-project.id-edit-form] -->
</div><!-- [end:container_project.id] -->
<% if controller.action_name == 'new_project' %>
<% if controller.action_name == 'create' %>
<script>
new Effect.Appear('project-<%= project.id %>');
</script>

View file

@ -15,7 +15,7 @@
<a href="#" onClick="Element.toggle('project_new'); Form.focusFirstElement('project-form');return false" accesskey="n" title="Create a new project">Create new project &#187;</a>
<div id="project_new" class="project_new" style="display:none">
<!--[form:project]-->
<%= form_remote_tag :url => { :action => "new_project" },
<%= form_remote_tag :url => { :action => "create" },
:html=> { :id=>'project-form', :name=>'project', :class => 'inline-form' } %>
<label for="project_name">Name:</label>
<br />

View file

@ -6,11 +6,8 @@ development:
password:
test:
adapter: mysql
database: tracks_test
host: localhost
username: root
password:
adapter: sqlite3
database: ":memory:"
production:
adapter: mysql

View file

@ -34,7 +34,7 @@ ActionController::Routing::Routes.draw do |map|
map.connect 'tickler/:action/:id', :controller => 'deferred'
# Context Routes
map.connect 'context/new_context', :controller => 'context', :action => 'new_context'
map.connect 'context/create', :controller => 'context', :action => 'create'
map.connect 'context/add_item', :controller => 'context', :action => 'add_item'
map.connect 'context/order', :controller => 'context', :action => 'order'
map.connect 'context/:id', :controller=> 'context', :action => 'show', :requirements => {:id => /\d+/}
@ -45,7 +45,7 @@ ActionController::Routing::Routes.draw do |map|
map.connect 'contexts/feed/:feedtype/:name/:token', :controller => 'feed', :action => 'list_contexts_only'
# Projects Routes
map.connect 'project/new_project', :controller => 'project', :action => 'new_project'
map.connect 'project/create', :controller => 'project', :action => 'create'
map.connect 'project/add_item/:id', :controller => 'project', :action => 'add_item'
map.connect 'project/toggle_check/:id', :controller => 'project', :action => 'toggle_check'
map.connect 'project/order', :controller => 'project', :action => 'order'

View file

@ -6,9 +6,9 @@ ActiveRecord::Schema.define(:version => 9) do
create_table "contexts", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "hide", :integer, :limit => 4, :default => 0, :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "hide", :boolean, :default => false
t.column "user_id", :integer, :default => 1
t.column "user_id", :integer, :default => 0, :null => false
end
create_table "notes", :force => true do |t|
@ -22,8 +22,8 @@ ActiveRecord::Schema.define(:version => 9) do
create_table "projects", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "done", :boolean, :default => false
t.column "user_id", :integer, :default => 1
t.column "done", :integer, :limit => 4, :default => 0, :null => false
t.column "user_id", :integer, :default => 0, :null => false
t.column "description", :text
end
@ -37,23 +37,23 @@ ActiveRecord::Schema.define(:version => 9) do
create_table "todos", :force => true do |t|
t.column "context_id", :integer, :default => 0, :null => false
t.column "project_id", :integer
t.column "description", :string, :default => "", :null => false
t.column "description", :string, :limit => 100, :default => "", :null => false
t.column "notes", :text
t.column "done", :boolean, :default => false, :null => false
t.column "done", :integer, :limit => 4, :default => 0, :null => false
t.column "created_at", :datetime
t.column "due", :date
t.column "completed", :datetime
t.column "user_id", :integer, :default => 1
t.column "project_id", :integer
t.column "user_id", :integer, :default => 0, :null => false
t.column "type", :string, :default => "Immediate", :null => false
t.column "show_from", :date
end
create_table "users", :force => true do |t|
t.column "login", :string, :limit => 80, :default => "", :null => false
t.column "password", :string, :limit => 40, :default => "", :null => false
t.column "login", :string, :limit => 80
t.column "password", :string, :limit => 40
t.column "word", :string
t.column "is_admin", :boolean, :default => false, :null => false
t.column "is_admin", :integer, :limit => 4, :default => 0, :null => false
t.column "preferences", :text
end

View file

@ -1,38 +1,40 @@
require File.dirname(__FILE__) + '/../test_helper'
require File.dirname(__FILE__) + '/todo_container_controller_test_base'
require 'context_controller'
# Re-raise errors caught by the controller.
class ContextController; def rescue_action(e) raise e end; end
class ContextControllerTest < Test::Unit::TestCase
class ContextControllerTest < TodoContainerControllerTestBase
fixtures :users, :contexts
def setup
@controller = ContextController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
perform_setup(Context, ContextController)
end
def test_create_context
num_contexts = Context.count
@request.session['user_id'] = users(:other_user).id
xhr :post, :new_context, :context => {:name => 'newcontext'}
def test_create_context_via_ajax_increments_number_of_context
assert_ajax_create_increments_count '@newcontext'
end
def test_create_context_with_ajax_success_rjs
ajax_create '@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'}
def test_create_via_ajax_with_slash_in_name_does_not_increment_number_of_contexts
assert_ajax_create_does_not_increment_count 'foo/bar'
end
def test_create_with_slash_in_name_fails_with_rjs
ajax_create '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

View file

@ -1,37 +1,40 @@
require File.dirname(__FILE__) + '/../test_helper'
require File.dirname(__FILE__) + '/todo_container_controller_test_base'
require 'project_controller'
# Re-raise errors caught by the controller.
class ProjectController; def rescue_action(e) raise e end; end
class ProjectControllerTest < Test::Unit::TestCase
class ProjectControllerTest < TodoContainerControllerTestBase
fixtures :users, :projects
def setup
@controller = ProjectController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
perform_setup(Project, ProjectController)
end
def test_create_project
num_projects = Project.count
@request.session['user_id'] = users(:other_user).id
xhr :post, :new_project, :project => {:name => 'My New Project'}
def test_create_project_via_ajax_increments_number_of_projects
assert_ajax_create_increments_count 'My New Project'
end
def test_create_project_with_ajax_success_rjs
ajax_create 'My New Project'
assert_rjs :hide, "warning"
assert_rjs :insert_html, :bottom, "list-projects"
assert_rjs :sortable, 'list-projects', { :tag => 'div', :handle => 'handle', :complete => visual_effect(:highlight, 'list-projects'), :url => {:controller => 'project', :action => 'order'} }
# not yet sure how to write the following properly...
assert_rjs :call, "Form.reset", "project-form"
assert_rjs :call, "Form.focusFirstElement", "project-form"
assert_equal num_projects + 1, Project.count
end
def test_create_with_slash_in_name_fails
num_projects = Project.count
@request.session['user_id'] = users(:other_user).id
xhr :post, :new_project, :project => {:name => 'foo/bar'}
def test_create_with_slash_in_name_does_not_increment_number_of_projects
assert_ajax_create_does_not_increment_count 'foo/bar'
end
def test_create_with_slash_in_name_fails_with_rjs
ajax_create '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_projects, Project.count
end
end

View file

@ -0,0 +1,32 @@
class TodoContainerControllerTestBase < Test::Unit::TestCase
def perform_setup(container_class, controller_class)
@controller = controller_class.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
@request.session['user_id'] = users(:other_user).id
@initial_count = container_class.count
@container_class = container_class
end
def test_truth
assert true
end
def assert_ajax_create_increments_count(name)
assert_count_after_ajax_create(name, @initial_count + 1)
end
def assert_ajax_create_does_not_increment_count(name)
assert_count_after_ajax_create(name, @initial_count)
end
def assert_count_after_ajax_create(name, expected_count)
ajax_create(name)
assert_equal(expected_count, @container_class.count)
end
def ajax_create(name)
xhr :post, :create, @container_class.name.downcase.to_sym => {:name => name}
end
end

View file

@ -0,0 +1,76 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'context_controller'
require 'context'
require 'action_controller/integration'
# Re-raise errors caught by the controller.
class ContextController; def rescue_action(e) raise e end; end
class ContextControllerXmlApiTest < ActionController::IntegrationTest
fixtures :users, :contexts
@@context_name = "@newcontext"
@@valid_postdata = "<request><context><name>#{@@context_name}</name></context></request>"
def setup
assert_test_environment_ok
end
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml_to_context_create @@valid_postdata, 'nobody', 'nohow'
assert_401_unauthorized
end
def test_fails_with_invalid_xml_format
authenticated_post_xml_to_context_create "<foo></bar>"
assert_404_invalid_xml
end
def test_fails_with_invalid_xml_format2
authenticated_post_xml_to_context_create "<request><context></context></request>"
assert_404_invalid_xml
end
def test_xml_simple_param_parsing
authenticated_post_xml_to_context_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:context)
assert @controller.params[:request][:context].has_key?(:name)
assert_equal @@context_name, @controller.params[:request][:context][:name]
end
def test_fails_with_too_long_name
invalid_with_long_name_postdata = "<request><context><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></context></request>"
authenticated_post_xml_to_context_create invalid_with_long_name_postdata
assert_response_and_body 404, "Name context name must be less than 256 characters"
end
def test_fails_with_slash_in_name
authenticated_post_xml_to_context_create "<request><context><name>foo/bar</name></context></request>"
assert_response_and_body 404, "Name cannot contain the slash ('/') character"
end
def test_creates_new_project
initial_count = Context.count
authenticated_post_xml_to_context_create
assert_response_and_body 200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<context>\n <name>#{@@context_name}</name>\n <hide type=\"integer\">0</hide>\n <id type=\"integer\">0</id>\n <position type=\"integer\">1</position>\n</context>\n"
assert_equal initial_count + 1, Context.count
context1 = Context.find_by_name(@@context_name)
assert_not_nil context1, "expected context '#{@@context_name}' to be created"
end
def test_fails_with_get_verb
authenticated_get_xml "/context/create", users(:other_user).login, 'sesame', {}
end
private
def authenticated_post_xml_to_context_create(postdata = @@valid_postdata, user = users(:other_user).login, password = 'sesame')
authenticated_post_xml "/context/create", user, password, postdata
end
def assert_404_invalid_xml
assert_response_and_body 404, "Expected post format is xml like so: <request><context><name>context name</name></context></request>."
end
end

View file

@ -9,42 +9,40 @@ class UserController; def rescue_action(e) raise e end; end
class CreateUserControllerTest < ActionController::IntegrationTest
fixtures :users
@@foobar_postdata = "<request><login>foo</login><password>bar</password></request>"
@@john_postdata = "<request><login>john</login><password>barracuda</password></request>"
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", User.get_salt()
@foobar_postdata = "<request><login>foo</login><password>bar</password></request>"
@john_postdata = "<request><login>john</login><password>barracuda</password></request>"
assert_test_environment_ok
end
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml '/user/create', 'nobody', 'nohow', @foobar_postdata
authenticated_post_xml_to_user_create @@foobar_postdata, 'nobody', 'nohow'
assert_401_unauthorized
end
def test_fails_with_401_if_not_admin_user
authenticated_post_xml '/user/create', users(:other_user).login, 'sesame', @foobar_postdata
authenticated_post_xml_to_user_create @@foobar_postdata, users(:other_user).login, 'sesame'
assert_401_unauthorized
end
def test_content_type_must_be_xml
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', @foobar_postdata, {'CONTENT_TYPE' => "application/x-www-form-urlencoded"}
authenticated_post_xml_to_user_create @@foobar_postdata, users(:admin_user).login, 'abracadabra', {'CONTENT_TYPE' => "application/x-www-form-urlencoded"}
assert_response_and_body 404, "Content Type must be application/xml."
end
def test_fails_with_invalid_xml_format
invalid_postdata = "<foo></bar>"
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', invalid_postdata
authenticated_post_xml_to_user_create "<foo></bar>"
assert_404_invalid_xml
end
def test_fails_with_invalid_xml_format2
invalid_postdata = "<request><username>foo</username></request>"
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', invalid_postdata
authenticated_post_xml_to_user_create "<request><username>foo</username></request>"
assert_404_invalid_xml
end
def test_xml_simple_param_parsing
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', @foobar_postdata
authenticated_post_xml_to_user_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:login)
assert @controller.params[:request].has_key?(:password)
@ -53,21 +51,21 @@ class CreateUserControllerTest < ActionController::IntegrationTest
end
def test_fails_with_too_short_password
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', @foobar_postdata
authenticated_post_xml_to_user_create
assert_response_and_body 404, "Password is too short (minimum is 5 characters)"
end
def test_fails_with_nonunique_login
existing_login = users(:other_user).login
data = "<request><login>#{existing_login}</login><password>barracuda</password></request>"
authenticated_post_xml "/user/create", users(:admin_user).login, 'abracadabra', data
authenticated_post_xml_to_user_create "<request><login>#{existing_login}</login><password>barracuda</password></request>"
assert_response_and_body 404, "Login has already been taken"
end
def test_creates_new_user
authenticated_post_xml '/user/create', users(:admin_user).login, 'abracadabra', @john_postdata
initial_count = User.count
authenticated_post_xml_to_user_create @@john_postdata
assert_response_and_body 200, "User created."
assert_equal 3, User.count
assert_equal initial_count + 1, User.count
john1 = User.find_by_login('john')
assert_not_nil john1, "expected user john to be created"
john2 = User.authenticate('john','barracuda')
@ -79,37 +77,13 @@ class CreateUserControllerTest < ActionController::IntegrationTest
end
private
def authenticated_post_xml(url, username, password, parameters, headers = {})
post url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def authenticated_get_xml(url, username, password, parameters, headers = {})
get url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def assert_401_unauthorized
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
def authenticated_post_xml_to_user_create(postdata = @@foobar_postdata, user = users(:admin_user).login, password = 'abracadabra', headers = {})
authenticated_post_xml "/user/create", user, password, postdata, headers
end
def assert_404_invalid_xml
assert_response_and_body 404, "Expected post format is xml like so: <request><login>username</login><password>abc123</password></request>."
end
def assert_response_and_body (type, body, message = nil)
#puts @response.body
assert_response type, message
assert_equal body, @response.body, message
end
end

View file

@ -0,0 +1,76 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'project_controller'
require 'project'
require 'action_controller/integration'
# Re-raise errors caught by the controller.
class ProjectController; def rescue_action(e) raise e end; end
class ProjectControllerXmlApiTest < ActionController::IntegrationTest
fixtures :users, :projects
@@project_name = "My New Project"
@@valid_postdata = "<request><project><name>#{@@project_name}</name></project></request>"
def setup
assert_test_environment_ok
end
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml_to_project_create @@valid_postdata, 'nobody', 'nohow'
assert_401_unauthorized
end
def test_fails_with_invalid_xml_format
authenticated_post_xml_to_project_create "<foo></bar>"
assert_404_invalid_xml
end
def test_fails_with_invalid_xml_format2
authenticated_post_xml_to_project_create "<request><project></project></request>"
assert_404_invalid_xml
end
def test_xml_simple_param_parsing
authenticated_post_xml_to_project_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:project)
assert @controller.params[:request][:project].has_key?(:name)
assert_equal @@project_name, @controller.params[:request][:project][:name]
end
def test_fails_with_too_long_name
invalid_with_long_name_postdata = "<request><project><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></project></request>"
authenticated_post_xml_to_project_create invalid_with_long_name_postdata
assert_response_and_body 404, "Name project name must be less than 256 characters"
end
def test_fails_with_slash_in_name
authenticated_post_xml_to_project_create "<request><project><name>foo/bar</name></project></request>"
assert_response_and_body 404, "Name cannot contain the slash ('/') character"
end
def test_creates_new_project
initial_count = Project.count
authenticated_post_xml_to_project_create
assert_response_and_body 200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project>\n <name>#{@@project_name}</name>\n <done type=\"integer\">0</done>\n <id type=\"integer\">0</id>\n <description></description>\n <position type=\"integer\">1</position>\n</project>\n"
assert_equal initial_count + 1, Project.count
project1 = Project.find_by_name(@@project_name)
assert_not_nil project1, "expected project '#{@@project_name}' to be created"
end
def test_fails_with_get_verb
authenticated_get_xml "/project/create", users(:other_user).login, 'sesame', {}
end
private
def authenticated_post_xml_to_project_create(postdata = @@valid_postdata, user = users(:other_user).login, password = 'sesame')
authenticated_post_xml "/project/create", user, password, postdata
end
def assert_404_invalid_xml
assert_response_and_body 404, "Expected post format is xml like so: <request><project><name>project name</name></project></request>."
end
end

View file

@ -4,7 +4,7 @@ class StoriesTest < ActionController::IntegrationTest
fixtures :users, :projects, :contexts, :todos, :notes
def setup
assert_equal "change-me", User.get_salt
assert_test_environment_ok
end
# ####################################################

View file

@ -44,4 +44,41 @@ class Test::Unit::TestCase
end
return string
end
end
class ActionController::IntegrationTest
def assert_test_environment_ok
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", User.get_salt()
end
def authenticated_post_xml(url, username, password, parameters, headers = {})
post url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def authenticated_get_xml(url, username, password, parameters, headers = {})
get url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def assert_response_and_body (type, body, message = nil)
#puts @response.body
assert_response type, message
assert_equal body, @response.body, message
end
def assert_401_unauthorized
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
end
end

View file

@ -0,0 +1,20 @@
MemoryTestFix
=============
A simple fix to run tests with sqlite. From example at
http://blog.seagul.co.uk/articles/2006/02/08/in-memory-sqlite-database-for-rails-testing
In your database.yml, use
test:
adapter: sqlite3
database: ":memory:"
It runs much faster!
== Authors
Chris Roos
adapted by Geoffrey Grosenbach, http://nubyonrails.com

View file

@ -0,0 +1,22 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the memory_test_fix plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the memory_test_fix plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'MemoryTestFix'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -0,0 +1,7 @@
author: Chris Roos
summary: Makes SQLite3 memory tests possible by preloading the schema.
homepage: http://blog.seagul.co.uk/articles/2006/02/08/in-memory-sqlite-database-for-rails-testing
plugin: http://topfunky.net/svn/plugins/memory_test_fix
license: MIT
version: 0.1
rails_version: 1.1+

View file

@ -0,0 +1,2 @@
require 'memory_test_fix'

View file

@ -0,0 +1,12 @@
# MemoryTestFix
def in_memory_database?
ENV["RAILS_ENV"] == "test" and
ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLiteAdapter and
Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
end
if in_memory_database?
puts "Creating sqlite in memory database"
load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default
# ActiveRecord::Migrator.up('db/migrate') # use migrations
end