mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-29 05:18:49 +01:00
Merge branch 'bsag'
This commit is contained in:
commit
791639b883
1360 changed files with 87015 additions and 64321 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@ public/javascripts/cache
|
|||
public/stylesheets/cache
|
||||
tmp
|
||||
vendor/plugins/query_trace/
|
||||
rerun.txt
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class CannotAccessContext < RuntimeError; end
|
|||
|
||||
class ApplicationController < ActionController::Base
|
||||
|
||||
protect_from_forgery :secret => SITE_CONFIG['salt']
|
||||
protect_from_forgery
|
||||
|
||||
helper :application
|
||||
include LoginSystem
|
||||
|
|
@ -28,6 +28,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
layout proc{ |controller| controller.mobile? ? "mobile" : "standard" }
|
||||
exempt_from_layout /\.js\.erb$/
|
||||
|
||||
|
||||
before_filter :set_session_expiration
|
||||
before_filter :set_time_zone
|
||||
|
|
@ -217,6 +218,22 @@ class ApplicationController < ActionController::Base
|
|||
self.class.openid_enabled?
|
||||
end
|
||||
|
||||
def self.cas_enabled?
|
||||
Tracks::Config.cas_enabled?
|
||||
end
|
||||
|
||||
def cas_enabled?
|
||||
self.class.cas_enabled?
|
||||
end
|
||||
|
||||
def self.prefered_auth?
|
||||
Tracks::Config.prefered_auth?
|
||||
end
|
||||
|
||||
def prefered_auth?
|
||||
self.class.prefered_auth?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_date_per_user_prefs( s )
|
||||
|
|
@ -259,6 +276,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def set_time_zone
|
||||
Time.zone = current_user.prefs.time_zone if logged_in?
|
||||
locale = params[:locale] || 'en-US'
|
||||
I18n.locale = locale
|
||||
end
|
||||
|
||||
def set_zindex_counter
|
||||
|
|
@ -7,7 +7,6 @@ class ContextsController < ApplicationController
|
|||
before_filter :set_context_from_params, :only => [:update, :destroy]
|
||||
skip_before_filter :login_required, :only => [:index]
|
||||
prepend_before_filter :login_or_feed_token_required, :only => [:index]
|
||||
session :off, :only => :index, :if => Proc.new { |req| ['rss','atom','txt'].include?(req.parameters[:format]) }
|
||||
|
||||
def index
|
||||
# #true is passed here to force an immediate load so that size and empty?
|
||||
|
|
|
|||
|
|
@ -6,12 +6,32 @@ class LoginController < ApplicationController
|
|||
skip_before_filter :login_required
|
||||
before_filter :login_optional
|
||||
before_filter :get_current_user
|
||||
|
||||
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
|
||||
# This will allow the user to view the index page without authentication
|
||||
# but will process CAS authentication data if the user already
|
||||
# has an SSO session open.
|
||||
if defined? CASClient
|
||||
# Only require sub-library if gem is installed and loaded
|
||||
require 'casclient/frameworks/rails/filter'
|
||||
before_filter CASClient::Frameworks::Rails::GatewayFilter, :only => :login_cas
|
||||
|
||||
# This requires the user to be authenticated for viewing all other pages.
|
||||
before_filter CASClient::Frameworks::Rails::Filter, :only => [:login_cas ]
|
||||
end
|
||||
end
|
||||
|
||||
def login
|
||||
if cas_enabled?
|
||||
@username = session[:cas_user]
|
||||
@login_url = CASClient::Frameworks::Rails::Filter.login_url(self)
|
||||
end
|
||||
if openid_enabled? && using_open_id?
|
||||
login_openid
|
||||
elsif cas_enabled? && session[:cas_user]
|
||||
login_cas
|
||||
else
|
||||
@page_title = "TRACKS::Login"
|
||||
cookies[:preferred_auth] = prefered_auth? unless cookies[:preferred_auth]
|
||||
case request.method
|
||||
when :post
|
||||
if @user = User.authenticate(params['user_login'], params['user_password'])
|
||||
|
|
@ -49,9 +69,13 @@ class LoginController < ApplicationController
|
|||
@user.forget_me if logged_in?
|
||||
cookies.delete :auth_token
|
||||
session['user_id'] = nil
|
||||
reset_session
|
||||
notify :notice, "You have been logged out of Tracks."
|
||||
redirect_to_login
|
||||
if ( SITE_CONFIG['authentication_schemes'].include? 'cas') && session[:cas_user]
|
||||
CASClient::Frameworks::Rails::Filter.logout(self)
|
||||
else
|
||||
reset_session
|
||||
notify :notice, "You have been logged out of Tracks."
|
||||
redirect_to_login
|
||||
end
|
||||
end
|
||||
|
||||
def check_expiry
|
||||
|
|
@ -73,6 +97,33 @@ class LoginController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def login_cas
|
||||
# If checkbox on login page checked, we don't expire the session after 1 hour
|
||||
# of inactivity and we remember this user for future browser sessions
|
||||
|
||||
session['noexpiry'] ||= params['user_noexpiry']
|
||||
if session[:cas_user]
|
||||
if @user = User.find_by_login(session[:cas_user])
|
||||
session['user_id'] = @user.id
|
||||
msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
|
||||
notify :notice, "Login successful: session #{msg}"
|
||||
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
|
||||
unless should_expire_sessions?
|
||||
@user.remember_me
|
||||
cookies[:auth_token] = { :value => @user.remember_token, :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] }
|
||||
end
|
||||
#redirect_back_or_home
|
||||
else
|
||||
notify :warning, "Sorry, no user by that CAS username exists (#{session[:cas_user]})"
|
||||
redirect_to signup_url ; return
|
||||
end
|
||||
else
|
||||
notify :warning, result.message
|
||||
end
|
||||
redirect_back_or_home
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -80,7 +131,7 @@ class LoginController < ApplicationController
|
|||
def redirect_to_login
|
||||
respond_to do |format|
|
||||
format.html { redirect_to login_path }
|
||||
format.m { redirect_to formatted_login_path(:format => 'm') }
|
||||
format.m { redirect_to login_path(:format => 'm') }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -114,4 +165,6 @@ class LoginController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ class ProjectsController < ApplicationController
|
|||
before_filter :default_context_filter, :only => [:create, :update]
|
||||
skip_before_filter :login_required, :only => [:index]
|
||||
prepend_before_filter :login_or_feed_token_required, :only => [:index]
|
||||
session :off, :only => :index, :if => Proc.new { |req| ['rss','atom','txt'].include?(req.parameters[:format]) }
|
||||
|
||||
def index
|
||||
@source_view = params['_source_view'] || 'project_list'
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ class TodosController < ApplicationController
|
|||
append_before_filter :get_todo_from_params, :only => [ :edit, :toggle_check, :toggle_star, :show, :update, :destroy, :remove_predecessor]
|
||||
protect_from_forgery :except => [:auto_complete_for_tag, :auto_complete_for_predecessor]
|
||||
|
||||
session :off, :only => :index, :if => Proc.new { |req| is_feed_request(req) }
|
||||
|
||||
def index
|
||||
current_user.deferred_todos.find_and_activate_ready
|
||||
@projects = current_user.projects.find(:all, :include => [:default_context])
|
||||
|
|
@ -351,7 +349,7 @@ class TodosController < ApplicationController
|
|||
cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']}
|
||||
redirect_to old_path
|
||||
else
|
||||
redirect_to formatted_todos_path(:m)
|
||||
redirect_to todos_path(:format => 'm')
|
||||
end
|
||||
else
|
||||
render :action => "edit", :format => :m
|
||||
|
|
@ -463,12 +461,12 @@ class TodosController < ApplicationController
|
|||
|
||||
def filter_to_context
|
||||
context = current_user.contexts.find(params['context']['id'])
|
||||
redirect_to formatted_context_todos_path(context, :m)
|
||||
redirect_to context_todos_path(context, :format => 'm')
|
||||
end
|
||||
|
||||
def filter_to_project
|
||||
project = current_user.projects.find(params['project']['id'])
|
||||
redirect_to formatted_project_todos_path(project, :m)
|
||||
redirect_to project_todos_path(project, :format => 'm')
|
||||
end
|
||||
|
||||
# /todos/tag/[tag_name] shows all the actions tagged with tag_name
|
||||
|
|
@ -607,9 +605,9 @@ class TodosController < ApplicationController
|
|||
# Begin matching todos in current project
|
||||
@items = current_user.todos.find(:all,
|
||||
:select => 'description, project_id, context_id, created_at',
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ?) AND ' +
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
|
||||
'NOT (id = ?) AND lower(description) LIKE ? AND project_id = ?',
|
||||
'active', 'pending',
|
||||
'active', 'pending', 'deferred',
|
||||
@todo.id,
|
||||
'%' + params[:predecessor_list].downcase + '%',
|
||||
@todo.project_id ],
|
||||
|
|
@ -619,9 +617,9 @@ class TodosController < ApplicationController
|
|||
if @items.empty? # Match todos in other projects
|
||||
@items = current_user.todos.find(:all,
|
||||
:select => 'description, project_id, context_id, created_at',
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ?) AND ' +
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
|
||||
'NOT (id = ?) AND lower(description) LIKE ?',
|
||||
'active', 'pending',
|
||||
'active', 'pending', 'deferred',
|
||||
params[:id], '%' + params[:q].downcase + '%' ],
|
||||
:order => 'description ASC',
|
||||
:limit => 10
|
||||
|
|
@ -631,8 +629,8 @@ class TodosController < ApplicationController
|
|||
# New todo - TODO: Filter on project
|
||||
@items = current_user.todos.find(:all,
|
||||
:select => 'description, project_id, context_id, created_at',
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?',
|
||||
'active', 'pending',
|
||||
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?',
|
||||
'active', 'pending', 'deferred',
|
||||
'%' + params[:q].downcase + '%' ],
|
||||
:order => 'description ASC',
|
||||
:limit => 10
|
||||
|
|
@ -640,6 +638,15 @@ class TodosController < ApplicationController
|
|||
end
|
||||
render :inline => "<%= auto_complete_result2(@items) %>"
|
||||
end
|
||||
|
||||
def convert_to_project
|
||||
@todo = Todo.find(params[:id])
|
||||
@project = Project.new(:name => @todo.description, :description => @todo.notes,
|
||||
:default_context => @todo.context)
|
||||
@todo.destroy
|
||||
@project.save!
|
||||
redirect_to project_url(@project)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ class UsersController < ApplicationController
|
|||
|
||||
# GET /users/new
|
||||
def new
|
||||
@auth_types = []
|
||||
unless session[:cas_user]
|
||||
Tracks::Config.auth_schemes.each {|auth| @auth_types << [auth,auth]}
|
||||
else
|
||||
@auth_types << ['cas','cas']
|
||||
end
|
||||
|
||||
if User.no_users_yet?
|
||||
@page_title = "TRACKS::Sign up as the admin user"
|
||||
@heading = "Welcome to TRACKS. To get started, please create an admin account:"
|
||||
|
|
@ -66,6 +73,13 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
user = User.new(params['user'])
|
||||
|
||||
if Tracks::Config.auth_schemes.include?('cas')
|
||||
if user.auth_type.eql? "cas"
|
||||
user.crypted_password = "cas"
|
||||
end
|
||||
end
|
||||
|
||||
unless user.valid?
|
||||
session['new_user'] = user
|
||||
redirect_to :action => 'new'
|
||||
|
|
@ -94,6 +108,9 @@ class UsersController < ApplicationController
|
|||
return
|
||||
end
|
||||
user = User.new(params[:request])
|
||||
if Tracks::Config.auth_schemes.include?('cas') && session[:cas_user]
|
||||
user.auth_type = "cas" #if they area cas user
|
||||
end
|
||||
user.password_confirmation = params[:request][:password]
|
||||
if user.save
|
||||
render :text => "User created.", :status => 200
|
||||
|
|
@ -203,4 +220,4 @@ class UsersController < ApplicationController
|
|||
return true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def link_to_project_mobile(project, accesskey, descriptor = sanitize(project.name))
|
||||
link_to( descriptor, formatted_project_path(project, :m), {:title => "View project: #{project.name}", :accesskey => accesskey} )
|
||||
link_to( descriptor, project_path(project, :format => 'm'), {:title => "View project: #{project.name}", :accesskey => accesskey} )
|
||||
end
|
||||
|
||||
def item_link_to_context(item)
|
||||
|
|
@ -170,13 +170,41 @@ module ApplicationHelper
|
|||
standard_format = current_user.prefs.date_format
|
||||
translations = [
|
||||
['%m', 'mm'],
|
||||
['%b', 'M'],
|
||||
['%B', 'MM'],
|
||||
['%d', 'dd'],
|
||||
['%Y', 'yy'],
|
||||
['%y', 'y']
|
||||
['%a', 'D'],
|
||||
['%A', 'DD'],
|
||||
['%y', 'y'],
|
||||
['%Y', 'yy']
|
||||
]
|
||||
translations.inject(standard_format) do |str, translation|
|
||||
str.gsub(*translation)
|
||||
end
|
||||
end
|
||||
|
||||
AUTO_LINK_MESSAGE_RE = %r{message://<[^>]+>} unless const_defined?(:AUTO_LINK_MESSAGE_RE)
|
||||
|
||||
# Converts message:// links to href. This URL scheme is used on Mac OS X
|
||||
# to link to a mail message in Mail.app.
|
||||
def auto_link_message(text)
|
||||
text.gsub(AUTO_LINK_MESSAGE_RE) do
|
||||
href = $&
|
||||
left, right = $`, $'
|
||||
# detect already linked URLs and URLs in the middle of a tag
|
||||
if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
|
||||
# do not change string; URL is alreay linked
|
||||
href
|
||||
else
|
||||
content_tag(:a, h(href), :href => h(href))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def format_note(note)
|
||||
note = auto_link_message(note)
|
||||
note = auto_link(note)
|
||||
note = markdown(note)
|
||||
note = sanitize(note)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,6 +64,14 @@ module TodosHelper
|
|||
:complete => todo_stop_waiting_js(todo))
|
||||
end
|
||||
end
|
||||
|
||||
def remote_promote_to_project_menu_item(todo)
|
||||
url = {:controller => 'todos', :action => 'convert_to_project', :id => todo.id,
|
||||
:_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")}
|
||||
url[:_tag_name] = @tag_name if @source_view == 'tag'
|
||||
|
||||
return link_to("Promote to project", url)
|
||||
end
|
||||
|
||||
def todo_start_waiting_js(todo)
|
||||
return "$('#ul#{dom_id(todo)}').css('visibility', 'hidden'); $('##{dom_id(todo)}').block({message: null})"
|
||||
|
|
@ -262,9 +270,10 @@ module TodosHelper
|
|||
end
|
||||
|
||||
def empty_container_msg_div_id
|
||||
return "tickler-empty-nd" if source_view_is_one_of(:project, :tag) && @todo.deferred?
|
||||
return "p#{@todo.project_id}empty-nd" if source_view_is :project
|
||||
return "c#{@todo.context_id}empty-nd"
|
||||
todo = @todo || @successor
|
||||
return "tickler-empty-nd" if source_view_is_one_of(:project, :tag) && todo.deferred?
|
||||
return "p#{todo.project_id}empty-nd" if source_view_is :project
|
||||
return "c#{todo.context_id}empty-nd"
|
||||
end
|
||||
|
||||
def project_names_for_autocomplete
|
||||
|
|
@ -315,5 +324,5 @@ module TodosHelper
|
|||
def auto_complete_result2(entries, phrase = nil)
|
||||
return entries.map{|e| e.specification()}.join("\n") rescue ''
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class Todo < ActiveRecord::Base
|
|||
after_save :save_predecessors
|
||||
|
||||
named_scope :active, :conditions => { :state => 'active' }
|
||||
named_scope :not_completed, :conditions => ['NOT (state = ? )', 'completed']
|
||||
named_scope :not_completed, :conditions => ['NOT (todos.state = ? )', 'completed']
|
||||
named_scope :are_due, :conditions => ['NOT (todos.due IS NULL)']
|
||||
|
||||
STARRED_TAG_NAME = "starred"
|
||||
|
|
|
|||
|
|
@ -153,11 +153,14 @@ class User < ActiveRecord::Base
|
|||
if Tracks::Config.auth_schemes.include?('ldap')
|
||||
return candidate if candidate.auth_type == 'ldap' && SimpleLdapAuthenticator.valid?(login, pass)
|
||||
end
|
||||
if Tracks::Config.auth_schemes.include?('cas') && candidate.auth_type.eql?("cas")
|
||||
return candidate #because we can not auth them with out thier real password we have to settle for this
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def self.find_by_open_id_url(raw_identity_url)
|
||||
normalized_open_id_url = OpenIdAuthentication.normalize_url(raw_identity_url)
|
||||
normalized_open_id_url = OpenIdAuthentication.normalize_identifier(raw_identity_url)
|
||||
find(:first, :conditions => ['open_id_url = ?', normalized_open_id_url])
|
||||
end
|
||||
|
||||
|
|
@ -248,6 +251,6 @@ protected
|
|||
|
||||
def normalize_open_id_url
|
||||
return if open_id_url.nil?
|
||||
self.open_id_url = OpenIdAuthentication.normalize_url(open_id_url)
|
||||
self.open_id_url = OpenIdAuthentication.normalize_identifier(open_id_url)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<% context = mobile_context_listing -%>
|
||||
<div id="ctx"><%= link_to context.name, formatted_context_path(context, :m) %><%= " (" + count_undone_todos_phrase(context,"actions") + ")" %></div>
|
||||
<div id="ctx"><%= link_to context.name, context_path(context, :format => 'm') %><%= " (" + count_undone_todos_phrase(context,"actions") + ")" %></div>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ on importMessage(theMessage)
|
|||
set theSender to the sender of theMessage
|
||||
set theSubject to subject of theMessage
|
||||
if theSubject is equal to "" then set theSubject to emptySubject
|
||||
set theMessageId to message id of theMessage
|
||||
|
||||
-- Construct the description string from the email info
|
||||
set myDesc to "Email " & theSender & " about " & theSubject
|
||||
|
|
@ -42,13 +43,15 @@ on importMessage(theMessage)
|
|||
if length of myDesc > 100 then
|
||||
set myDesc to characters 1 thru 100 of myDesc
|
||||
end if
|
||||
|
||||
set myNote to "message://<" & theMessageId & ">"
|
||||
end try
|
||||
end tell
|
||||
|
||||
-- Now send all that info to Tracks
|
||||
-- Edit the URL of your Tracks installation if necessary"
|
||||
tell application "<%= home_url %>backend/api"
|
||||
set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc}}
|
||||
set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc, myNote}}
|
||||
end tell
|
||||
|
||||
(* Growl support - comment out or delete this section if
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@
|
|||
<h1><span class="count"><%= @down_count %></span> <%=
|
||||
current_user.time.strftime(@prefs.title_date_format) -%></h1>
|
||||
<div class="nav">
|
||||
<%= (link_to("0-New action", formatted_new_todo_path(:m, new_todo_params))+" | ") unless @new_mobile -%>
|
||||
<%= (link_to("1-Home", formatted_todos_path(:m))+" | ") unless @home -%>
|
||||
<%= (link_to("2-Contexts", formatted_contexts_path(:m))+" | ") -%>
|
||||
<%= (link_to("3-Projects", formatted_projects_path(:m))+" | ") -%>
|
||||
<%= (link_to("0-New action", new_todo_path(new_todo_params, :format => 'm'))+" | ") unless @new_mobile -%>
|
||||
<%= (link_to("1-Home", todos_path(:format => 'm'))+" | ") unless @home -%>
|
||||
<%= (link_to("2-Contexts", contexts_path(:format => 'm'))+" | ") -%>
|
||||
<%= (link_to("3-Projects", projects_path(:format => 'm'))+" | ") -%>
|
||||
<%= (link_to("4-Starred", {:action => "tag", :controller => "todos", :id => "starred.m"})) -%>
|
||||
<% end
|
||||
end -%><%= render_flash -%>
|
||||
|
|
@ -27,15 +27,15 @@
|
|||
<%= yield -%>
|
||||
<hr/><% if !@prefs.nil? -%>
|
||||
<div class="nav">
|
||||
<%= (link_to("Logout", formatted_logout_path(:format => 'm')) +" | ") -%>
|
||||
<%= (link_to("0-New action", formatted_new_todo_path(:m), {:accesskey => "0"})+" | ") unless @new_mobile -%>
|
||||
<%= (link_to("1-Home", formatted_todos_path(:m), {:accesskey => "1"})+" | ") unless @home -%>
|
||||
<%= (link_to("2-Contexts", formatted_contexts_path(:m), {:accesskey => "2"})+" | ") -%>
|
||||
<%= (link_to("3-Projects", formatted_projects_path(:m), {:accesskey => "3"})+" | ") -%>
|
||||
<%= (link_to("Logout", logout_path(:format => 'm')) +" | ") -%>
|
||||
<%= (link_to("0-New action", new_todo_path(:format => 'm'), {:accesskey => "0"})+" | ") unless @new_mobile -%>
|
||||
<%= (link_to("1-Home", todos_path(:format => 'm'), {:accesskey => "1"})+" | ") unless @home -%>
|
||||
<%= (link_to("2-Contexts", contexts_path(:format => 'm'), {:accesskey => "2"})+" | ") -%>
|
||||
<%= (link_to("3-Projects", projects_path(:format => 'm'), {:accesskey => "3"})+" | ") -%>
|
||||
<%= (link_to("4-Starred", {:action => "tag", :controller => "todos", :id => "starred.m"}, {:accesskey => "4"})+" | ") -%>
|
||||
<%= (link_to("Tickler", {:action => "index", :controller => "tickler.m"})+" | ") -%>
|
||||
<%= (link_to("Feeds", {:action => "index", :controller => "feeds.m"})) -%>
|
||||
</div>
|
||||
<% end -%>
|
||||
<%= render :partial => "shared/mobile_footer" -%>
|
||||
</body></html>
|
||||
</body></html>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
<div id="minilinks">
|
||||
<%= link_to("Toggle notes", "#", {:accesskey => "S", :title => "Toggle all notes", :id => "toggle-notes-nav"}) %>
|
||||
|
|
||||
<%= link_to "Logout (#{current_user.display_name}) »", logout_path %>
|
||||
<%= link_to "Logout (#{current_user.display_name}) »", logout_path %> <p>
|
||||
</div>
|
||||
<div id="navcontainer">
|
||||
<ul class="sf-menu">
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
<%= periodically_call_remote( :url => {:controller => "login", :action => "check_expiry"},
|
||||
:frequency => (5*60)) %>
|
||||
<% end -%>
|
||||
<%= periodically_call_remote( :url => formatted_check_deferred_todos_path(:js),
|
||||
<%= periodically_call_remote( :url => check_deferred_todos_path(:format => 'js'),
|
||||
:method => :post,
|
||||
:frequency => (10*60)) %>
|
||||
<%= yield %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<% auth_schemes = Tracks::Config.auth_schemes
|
||||
show_database_form = auth_schemes.include?('database')
|
||||
show_openid_form = auth_schemes.include?('open_id')
|
||||
show_cas_form = auth_schemes.include?('cas')
|
||||
-%>
|
||||
|
||||
<div title="Account login" id="loginform" class="form">
|
||||
|
|
@ -8,9 +9,8 @@
|
|||
<%= render_flash %>
|
||||
|
||||
<h3>Please log in to use Tracks:</h3>
|
||||
|
||||
<% if show_database_form %>
|
||||
<div id="database_auth_form" style="display:block">
|
||||
<div id="database_auth_form" style="display:<%=(@prefered_auth.eql?('database')) ? "block" : "none"%>">
|
||||
<% form_tag :action=> 'login' do %>
|
||||
<table>
|
||||
<tr>
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
<% end %>
|
||||
|
||||
<% if show_openid_form %>
|
||||
<div id="openid_auth_form" style="display:none">
|
||||
<div id="openid_auth_form" style="display:<%=(@prefered_auth.eql?('openid')) ? "block" : "none"%>">
|
||||
<% form_tag :action=> 'login' do %>
|
||||
<table>
|
||||
<tr>
|
||||
|
|
@ -54,24 +54,48 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if show_cas_form %>
|
||||
<div id="cas_auth_form" style="display:<%=(@prefered_auth.eql?('cas')) ? "block" : "none"%>">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<% if @username && @user%>
|
||||
<p>Hello, <%= @username %>! You are authenticated.</p>
|
||||
<% elsif @username %>
|
||||
<p>Hello, <%= @username %>! You do not have an account on Tracks.
|
||||
<%if SITE_CONFIG['open_signups']%>
|
||||
If you like to request on please go here to <%= link_to "Request Account" , signup_url %>
|
||||
<%end%>
|
||||
</p>
|
||||
<% else %>
|
||||
<p><%= link_to("CAS Login", login_cas_url) %> </p>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<% if show_openid_form %><p id="alternate_auth_openid" class="alternate_auth">or, <a href="#" onclick="Login.showOpenid();return false;">login with an OpenId</a></p><% end %>
|
||||
<% if show_database_form %><p id="alternate_auth_database" class="alternate_auth">or, <a href="#" onclick="Login.showDatabase();return false;">go back to the standard login</a></p><% end %>
|
||||
<% if show_cas_form %><p id="alternate_auth_cas" class="alternate_auth">or, <a href="#" onclick="Login.showCAS();return false;">go to the CAS</a></p><% end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
function showPreferredAuth() {
|
||||
var preferredAuth = $.cookie('preferred_auth');
|
||||
var casEnabled = <%= show_cas_form ? 'true' : 'false' %>;
|
||||
var databaseEnabled = <%= show_database_form ? 'true' : 'false' %>;
|
||||
var openidEnabled = <%= show_openid_form ? 'true' : 'false' %>;
|
||||
if (preferredAuth && preferredAuth == 'openid' && openidEnabled) {
|
||||
Login.showOpenid();
|
||||
}
|
||||
else if (databaseEnabled) {
|
||||
else if (preferredAuth && preferredAuth == 'database' && databaseEnabled) {
|
||||
Login.showDatabase();
|
||||
}
|
||||
else if (openidEnabled) {
|
||||
Login.showOpenid();
|
||||
else if (preferredAuth && preferredAuth == 'cas' && casEnabled) {
|
||||
Login.showCAS();
|
||||
}
|
||||
}
|
||||
$(document).ready(showPreferredAuth);
|
||||
|
|
@ -81,7 +105,8 @@ var Login = {
|
|||
$('#database_auth_form').hide();
|
||||
$('#openid_auth_form').show();
|
||||
$('#alternate_auth_openid').hide();
|
||||
$('#alternate_auth_database').show();
|
||||
$('#alternate_auth_database').show(); ;
|
||||
$('#alternate_auth_cas').show();
|
||||
$('#openid_url').focus();
|
||||
$('#openid_url').select();
|
||||
$.cookie('preferred_auth', 'openid');
|
||||
|
|
@ -92,10 +117,21 @@ var Login = {
|
|||
$('#database_auth_form').show();
|
||||
$('#alternate_auth_database').hide();
|
||||
$('#alternate_auth_openid').show();
|
||||
$('#alternate_auth_cas').show();
|
||||
$('#user_login').focus();
|
||||
$('#user_login').select();
|
||||
$.cookie('preferred_auth', 'database');
|
||||
},
|
||||
showCAS: function(container) {
|
||||
$('#database_auth_form').hide();
|
||||
$('#openid_auth_form').hide();
|
||||
$('#cas_auth_form').show();
|
||||
$('#alternate_auth_cas').hide();
|
||||
$('#alternate_auth_openid').show();
|
||||
$('#alternate_auth_database').show();
|
||||
$.cookie('preferred_auth', 'cas');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<% if show_database_form %>
|
||||
<div id="database_auth_form">
|
||||
<% form_tag formatted_login_path(:format => 'm') do %>
|
||||
<% form_tag login_path(:format => 'm') do %>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="user_login">Login:</label></td>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
<h4>...or login with an Open ID:</h4>
|
||||
|
||||
<div id="openid_auth_form">
|
||||
<% form_tag formatted_login_path(:format => 'm') do %>
|
||||
<% form_tag login_path(:format => 'm') do %>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="100px"><label for="openid_url">Identity URL:</label></td>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
<div class="mobile_note_info">
|
||||
<br/>
|
||||
<%= link_to("In: " + note.project.name, formatted_project_path(note.project, :m)) %>
|
||||
<%= link_to("In: " + note.project.name, project_path(note.project, :format => 'm')) %>
|
||||
Created: <%= format_date(note.created_at) %>
|
||||
<% if note.updated_at? -%>
|
||||
| Modified: <%= format_date(note.updated_at) %>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<% note = mobile_notes_summary -%>
|
||||
<div class="note"><%= link_to( truncated_note(note), formatted_note_path(note, :m)) %></div>
|
||||
<div class="note"><%= link_to( truncated_note(note), note_path(note, :format => 'm')) %></div>
|
||||
<% note = nil -%>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<div id="<%= dom_id(note, 'container') %>">
|
||||
<h2><%= link_to("Note #{note.id}", note_path(note), :title => "Show note #{note.id}" ) %></h2>
|
||||
<div class="project_notes" id="<%= dom_id(note) %>">
|
||||
<%= sanitize(markdown(auto_link(note.body))) %>
|
||||
|
||||
<%= format_note(note.body) %>
|
||||
|
||||
<div class="note_footer">
|
||||
<%= link_to_remote(
|
||||
image_tag("blank.png",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% project = mobile_project_listing -%>
|
||||
<div id="pjr"><%=
|
||||
link_to(project.name, formatted_project_path(project)) +
|
||||
" (" + count_undone_todos_and_notes_phrase(project,"actions") + ")" %></div>
|
||||
link_to(project.name, project_path(project, :format => 'm')) +
|
||||
" (" + count_undone_todos_and_notes_phrase(project,"actions") + ")" %></div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ suppress_edit_button ||= false
|
|||
<div class="buttons">
|
||||
<span class="grey"><%= project.current_state.to_s.upcase %></span>
|
||||
<a class="delete_project_button"
|
||||
href="<%= formatted_project_path(project, :js) %>"
|
||||
href="<%= project_path(project, :format => 'js') %>"
|
||||
title="delete the project '<%= project.name %>'"><%= image_tag( "blank.png",
|
||||
:title => "Delete project",
|
||||
:class=>"delete_item") %></a>
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ end -%>
|
|||
<% else
|
||||
-%><span class="m_t">
|
||||
<% end -%>
|
||||
<%= date_span -%> <%= link_to mobile_todo.description, formatted_todo_path(mobile_todo, :m) -%>
|
||||
<%= date_span -%> <%= link_to mobile_todo.description, todo_path(mobile_todo, :format => 'm') -%>
|
||||
<% if parent_container_type == 'context' or parent_container_type == 'tag' -%>
|
||||
<%= "<span class=\"prj\"> (" +
|
||||
link_to(mobile_todo.project.name, formatted_project_path(mobile_todo.project, :m)) +
|
||||
link_to(mobile_todo.project.name, project_path(mobile_todo.project, :format => 'm')) +
|
||||
")</span>" unless mobile_todo.project.nil? -%>
|
||||
<% end
|
||||
if parent_container_type == 'project' or parent_container_type == 'tag' -%>
|
||||
<%= "<span class=\"ctx\"> (" +
|
||||
link_to(mobile_todo.context.name, formatted_context_path(mobile_todo.context, :m)) +
|
||||
link_to(mobile_todo.context.name, context_path(mobile_todo.context, :format => 'm')) +
|
||||
")</span>" -%>
|
||||
<% end -%>
|
||||
<%= tag_list_mobile -%>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
|||
<li><%= remote_defer_menu_item(1, todo) %></li>
|
||||
<li><%= remote_defer_menu_item(7, todo) %></li>
|
||||
<% end %>
|
||||
<li><%= remote_promote_to_project_menu_item(todo) %></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<%= link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_notes', :title => 'Show notes'}) %>
|
||||
|
||||
<div class="todo_notes" id="<%= dom_id(item, 'notes') %>" style="display:none">
|
||||
<%= sanitize(markdown( auto_link(item.notes)) ) %>
|
||||
<%= format_note(item.notes) %>
|
||||
</div>
|
||||
|
|
@ -17,7 +17,7 @@ if @saved
|
|||
if @new_context_created
|
||||
page.insert_html :top, 'display_box', :partial => 'contexts/context', :locals => { :context => @todo.context, :collapsible => true }
|
||||
else
|
||||
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}" if source_view_is_one_of(:todo, :deferred)
|
||||
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}" if source_view_is_one_of(:todo, :deferred, :tag)
|
||||
page.insert_html :bottom, item_container_id(@todo), :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type, :source_view => @source_view }
|
||||
page.visual_effect :highlight, dom_id(@todo), :duration => 3
|
||||
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<% form_tag formatted_todos_path(:m), :method => :post do %>
|
||||
<% form_tag todos_path(:format => 'm'), :method => :post do %>
|
||||
<%= render :partial => 'edit_mobile' %>
|
||||
<p><input type="submit" value="Create" tabindex="12" accesskey="#" /></p>
|
||||
<% end -%>
|
||||
<%= link_to "Back", @return_path %>
|
||||
<%= link_to "Back", @return_path %>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ if @removed
|
|||
# update display if pending->active
|
||||
if @successor.active?
|
||||
page[@successor].remove unless source_view_is_one_of(:todo, :context)
|
||||
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
|
||||
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@successor.context_id}"
|
||||
page.insert_html :bottom, item_container_id(@successor), :partial => 'todos/todo', :locals => {
|
||||
:todo => @successor, :parent_container_type => parent_container_type }
|
||||
page.visual_effect :highlight, dom_id(@successor, 'line'), {'startcolor' => "'#99ff99'"}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% form_tag formatted_todo_path(@todo, :m), :method => :put do %>
|
||||
<% form_tag todo_path(@todo, :format => 'm'), :method => :put do %>
|
||||
<%= render :partial => 'edit_mobile', :locals => { :parent_container_type => "show_mobile" } %>
|
||||
<p><input type="submit" value="Update" tabindex="6" accesskey="#" /></p>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ if @saved
|
|||
end
|
||||
|
||||
# remove container if empty
|
||||
if @remaining_in_context == 0 && source_view_is(:todo)
|
||||
if @remaining_in_context == 0 && source_view_is_one_of(:todo, :tag)
|
||||
page.visual_effect :fade, "c"+@todo.context.id.to_s, :duration => 0.4
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,22 @@
|
|||
<h3><%= @heading -%></h3>
|
||||
|
||||
<table>
|
||||
<%if Tracks::Config.auth_schemes.include?('cas') && session[:cas_user]%>
|
||||
<tr>
|
||||
<td><label for="user_login">With your CAS username:</label></td>
|
||||
<td> "<%= session[:cas_user]%>" </td>
|
||||
<td>
|
||||
<%= hidden_field "user", "login", :value => session[:cas_user] %>
|
||||
<%= hidden_field "user", "password", :value => session[:cas_user] %>
|
||||
<%= hidden_field "user", "password_confirmation", :value => session[:cas_user] %>
|
||||
<%= hidden_field"user", "auth_type", :value => "cas" %></td>
|
||||
</tr>
|
||||
<%else%>
|
||||
<tr>
|
||||
<td><label for="user_login">Desired login:</label></td>
|
||||
<td> <%= text_field "user", "login", :size => 20 %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><label for="user_password">Choose password:</label></td>
|
||||
<td><%= password_field "user", "password", :size => 20 %></td>
|
||||
</tr>
|
||||
|
|
@ -20,6 +31,11 @@
|
|||
<td><label for="user_password_confirmation">Confirm password:</label></td>
|
||||
<td><%= password_field "user", "password_confirmation", :size => 20 %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="user_auth_type">Authentication Type:</label></td>
|
||||
<td><%= select("user", "auth_type", @auth_types, { :include_blank => false })%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><input type="submit" id="signup" value="Signup »" class="primary" /></td>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ module Rails
|
|||
def load_initializer
|
||||
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
|
||||
Rails::Initializer.run(:install_gem_spec_stubs)
|
||||
Rails::GemDependency.add_frozen_gem_path
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -81,8 +82,8 @@ module Rails
|
|||
end
|
||||
|
||||
def load_rubygems
|
||||
min_version = '1.3.2'
|
||||
require 'rubygems'
|
||||
min_version = '1.3.1'
|
||||
unless rubygems_version >= min_version
|
||||
$stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
||||
exit 1
|
||||
|
|
|
|||
8
config/cucumber.yml
Normal file
8
config/cucumber.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<%
|
||||
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
||||
rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
||||
std_opts = "#{rerun_opts} --format rerun --out rerun.txt --strict --tags ~@wip"
|
||||
%>
|
||||
default: <%= std_opts %> --tags ~@selenium
|
||||
selenium: <%= std_opts %> --tags @selenium
|
||||
wip: --tags @wip:3 --wip features
|
||||
|
|
@ -17,15 +17,12 @@ end
|
|||
Rails::Initializer.run do |config|
|
||||
# Skip frameworks you're not going to use
|
||||
# config.frameworks -= [ :action_web_service, :action_mailer ]
|
||||
config.frameworks += [ :action_web_service]
|
||||
config.action_web_service = Rails::OrderedOptions.new
|
||||
config.load_paths += %W( #{RAILS_ROOT}/app/apis )
|
||||
|
||||
config.gem "highline"
|
||||
config.gem "RedCloth"
|
||||
# Need to do rspec here and not in test.rb. Needed for rake to work which loads
|
||||
# the rspec.task file
|
||||
config.gem "rspec", :lib => false, :version => ">=1.2.2"
|
||||
config.gem "soap4r", :lib => false
|
||||
config.gem 'datanoise-actionwebservice', :lib => 'actionwebservice'
|
||||
|
||||
config.action_controller.use_accept_header = true
|
||||
|
||||
|
|
@ -61,9 +58,13 @@ Rails::Initializer.run do |config|
|
|||
# allow other protocols in urls for sanitzer. Add to your liking, for example
|
||||
# config.action_view.sanitized_allowed_protocols = 'onenote', 'blah', 'proto'
|
||||
# to enable "link":onenote://... or "link":blah://... hyperlinks
|
||||
config.action_view.sanitized_allowed_protocols = 'onenote'
|
||||
config.action_view.sanitized_allowed_protocols = 'onenote', 'message'
|
||||
|
||||
# See Rails::Configuration for more options
|
||||
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
|
||||
#requires rubycas-client gem to be installed
|
||||
config.gem "rubycas-client", :lib => 'casclient'
|
||||
end
|
||||
end
|
||||
|
||||
# Add new inflection rules using the following format
|
||||
|
|
@ -99,6 +100,17 @@ if ( SITE_CONFIG['authentication_schemes'].include? 'open_id')
|
|||
OpenID::Util.logger = RAILS_DEFAULT_LOGGER
|
||||
end
|
||||
|
||||
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
|
||||
#requires rubycas-client gem to be installed
|
||||
if defined? CASClient
|
||||
require 'casclient/frameworks/rails/filter'
|
||||
CASClient::Frameworks::Rails::Filter.configure(
|
||||
:cas_base_url => SITE_CONFIG['cas_server'] ,
|
||||
:cas_server_logout => SITE_CONFIG['cas_server_logout']
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
tracks_version='1.8devel'
|
||||
# comment out next two lines if you do not want (or can not) the date of the
|
||||
# last git commit in the footer
|
||||
|
|
|
|||
29
config/environments/cucumber.rb
Normal file
29
config/environments/cucumber.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Edit at your own peril - it's recommended to regenerate this file
|
||||
# in the future when you upgrade to a newer version of Cucumber.
|
||||
|
||||
# IMPORTANT: Setting config.cache_classes to false is known to
|
||||
# break Cucumber's use_transactional_fixtures method.
|
||||
# For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165
|
||||
config.cache_classes = true
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.action_controller.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Disable request forgery protection in test environment
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
||||
# Tell Action Mailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
|
||||
config.gem 'cucumber-rails', :lib => false, :version => '>=0.2.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
|
||||
config.gem 'database_cleaner', :lib => false, :version => '>=0.2.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
|
||||
config.gem 'webrat', :lib => false, :version => '>=0.6.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
|
||||
config.gem 'rspec', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
|
||||
config.gem 'rspec-rails', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ config.action_controller.allow_forgery_protection = false
|
|||
# See http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/5519ca7fd4dde3c1
|
||||
class ActionController::RackRequest
|
||||
DEFAULT_SESSION_OPTIONS = {
|
||||
:database_manager => CGI::Session::MemoryStore, # store data in memory
|
||||
#:database_manager => CGI::Session::MemoryStore, # store data in memory
|
||||
:prefix => "ruby_sess.", # prefix session file names
|
||||
:session_path => "/", # available to all paths in app
|
||||
:session_key => "_session_id",
|
||||
|
|
@ -50,10 +50,7 @@ config.gem "flexmock"
|
|||
config.gem "ZenTest", :lib => "zentest", :version => ">=4.0.0"
|
||||
config.gem "hpricot"
|
||||
config.gem "hoe"
|
||||
|
||||
# config.gem for rspec is in environment.rb. Needed for rake to work which loads
|
||||
# the rspec.task file
|
||||
config.gem "rspec", :lib => false, :version => ">= 1.2.2"
|
||||
config.gem "rspec-rails", :lib => false, :version => ">=1.2.2"
|
||||
config.gem "webrat", :lib => false, :version => ">=0.4.3"
|
||||
config.gem "cucumber", :lib => false, :version => ">=0.3.0"
|
||||
config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com"
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
# See test_url_with_slash_in_query_string_are_parsed_correctly in test/functional/todos_controller_test.rb
|
||||
# and http://blog.swivel.com/code/2009/06/rails-auto_link-and-certain-query-strings.html
|
||||
module ActionView::Helpers::TextHelper
|
||||
remove_const :AUTO_LINK_RE
|
||||
AUTO_LINK_RE = %r{
|
||||
( # leading text
|
||||
<\w+.*?>| # leading HTML tag, or
|
||||
[^=!:'"/]| # leading punctuation, or
|
||||
^ # beginning of line
|
||||
)
|
||||
(
|
||||
(?:https?://)| # protocol spec, or
|
||||
(?:www\.) # www.*
|
||||
)
|
||||
(
|
||||
[-\w]+ # subdomain or domain
|
||||
(?:\.[-\w]+)* # remaining subdomains or domain
|
||||
(?::\d+)? # port
|
||||
(?:/(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))*)* # path
|
||||
(?:\?[\w\+@%&=.;:/-]+)? # query string
|
||||
(?:\#[\w\-]*)? # trailing anchor
|
||||
)
|
||||
([[:punct:]]|<|$|) # trailing text
|
||||
}x
|
||||
end
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
ActionController::Routing::Routes.draw do |map|
|
||||
map.with_options :controller => 'login' do |login|
|
||||
login.login 'login', :action => 'login'
|
||||
login.login_cas 'login_cas', :action => 'login_cas'
|
||||
login.formatted_login 'login.:format', :action => 'login'
|
||||
login.logout 'logout', :action => 'logout'
|
||||
login.formatted_logout 'logout.:format', :action => 'logout'
|
||||
|
|
|
|||
|
|
@ -9,6 +9,17 @@ authentication_schemes:
|
|||
- "database"
|
||||
# - "ldap"
|
||||
# - "open_id"
|
||||
# - "cas"
|
||||
|
||||
|
||||
#set the prefered authentication scheme to display first on the login page
|
||||
#prefered_auth: database
|
||||
|
||||
|
||||
# Uncomment if using cas
|
||||
#cas_server: "https://cas.demo.edu/cas"
|
||||
#cas_server_logout: "https://cas.demo.edu/cas/logout"
|
||||
|
||||
|
||||
|
||||
# You''ll probably want to change this to the time zone of the computer where Tracks is running
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Feature: View, add, remove notes
|
|||
And I should see note "My Note A" on the notes page
|
||||
Then the badge should show 1
|
||||
|
||||
@needsjs
|
||||
@selenium
|
||||
Scenario: Delete note from notes page
|
||||
Given I have logged in as "testuser" with password "secret"
|
||||
And I have a project "Pass Final Exam" with 2 notes
|
||||
|
|
@ -33,7 +33,7 @@ Feature: View, add, remove notes
|
|||
Then the first note should disappear
|
||||
Then the badge should show 1
|
||||
|
||||
@needsjs
|
||||
@selenium
|
||||
Scenario: Link to note
|
||||
Given I have logged in as "testuser" with password "secret"
|
||||
And I have a project "Pass Final Exam" with 1 note
|
||||
|
|
@ -41,7 +41,7 @@ Feature: View, add, remove notes
|
|||
And I click the icon next to the note
|
||||
Then I should see the note text
|
||||
|
||||
@needsjs
|
||||
@selenium
|
||||
Scenario: Toggle notes
|
||||
Given I have logged in as "testuser" with password "secret"
|
||||
And I have two projects with one note each
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Then "the badge should show (.*)" do |number|
|
||||
Then /the badge should show (.*)/ do |number|
|
||||
badge = -1
|
||||
response.should have_xpath("//span[@id='badge_count']") do |node|
|
||||
badge = node.first.content.to_i
|
||||
|
|
|
|||
261
features/step_definitions/web_steps.rb
Normal file
261
features/step_definitions/web_steps.rb
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
||||
# It is recommended to regenerate this file in the future when you upgrade to a
|
||||
# newer version of cucumber-rails. Consider adding your own code to a new file
|
||||
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
||||
# files.
|
||||
|
||||
|
||||
require 'uri'
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
||||
|
||||
# Commonly used webrat steps
|
||||
# http://github.com/brynary/webrat
|
||||
|
||||
Given /^(?:|I )am on (.+)$/ do |page_name|
|
||||
visit path_to(page_name)
|
||||
end
|
||||
|
||||
When /^(?:|I )go to (.+)$/ do |page_name|
|
||||
visit path_to(page_name)
|
||||
end
|
||||
|
||||
When /^(?:|I )press "([^\"]*)"$/ do |button|
|
||||
click_button(button)
|
||||
end
|
||||
|
||||
When /^(?:|I )follow "([^\"]*)"$/ do |link|
|
||||
click_link(link)
|
||||
end
|
||||
|
||||
When /^(?:|I )follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
|
||||
click_link_within(parent, link)
|
||||
end
|
||||
|
||||
When /^(?:|I )fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
|
||||
fill_in(field, :with => value)
|
||||
end
|
||||
|
||||
When /^(?:|I )fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
|
||||
fill_in(field, :with => value)
|
||||
end
|
||||
|
||||
# Use this to fill in an entire form with data from a table. Example:
|
||||
#
|
||||
# When I fill in the following:
|
||||
# | Account Number | 5002 |
|
||||
# | Expiry date | 2009-11-01 |
|
||||
# | Note | Nice guy |
|
||||
# | Wants Email? | |
|
||||
#
|
||||
# TODO: Add support for checkbox, select og option
|
||||
# based on naming conventions.
|
||||
#
|
||||
When /^(?:|I )fill in the following:$/ do |fields|
|
||||
fields.rows_hash.each do |name, value|
|
||||
When %{I fill in "#{name}" with "#{value}"}
|
||||
end
|
||||
end
|
||||
|
||||
When /^(?:|I )select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
|
||||
select(value, :from => field)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's datetime_select helper. For example:
|
||||
# When I select "December 25, 2008 10:00" as the date and time
|
||||
When /^(?:|I )select "([^\"]*)" as the date and time$/ do |time|
|
||||
select_datetime(time)
|
||||
end
|
||||
|
||||
# Use this step when using multiple datetime_select helpers on a page or
|
||||
# you want to specify which datetime to select. Given the following view:
|
||||
# <%= f.label :preferred %><br />
|
||||
# <%= f.datetime_select :preferred %>
|
||||
# <%= f.label :alternative %><br />
|
||||
# <%= f.datetime_select :alternative %>
|
||||
# The following steps would fill out the form:
|
||||
# When I select "November 23, 2004 11:20" as the "Preferred" date and time
|
||||
# And I select "November 25, 2004 10:30" as the "Alternative" date and time
|
||||
When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
|
||||
select_datetime(datetime, :from => datetime_label)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's time_select helper. For example:
|
||||
# When I select "2:20PM" as the time
|
||||
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
|
||||
# will convert the 2:20PM to 14:20 and then select it.
|
||||
When /^(?:|I )select "([^\"]*)" as the time$/ do |time|
|
||||
select_time(time)
|
||||
end
|
||||
|
||||
# Use this step when using multiple time_select helpers on a page or you want to
|
||||
# specify the name of the time on the form. For example:
|
||||
# When I select "7:30AM" as the "Gym" time
|
||||
When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
|
||||
select_time(time, :from => time_label)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's date_select helper. For example:
|
||||
# When I select "February 20, 1981" as the date
|
||||
When /^(?:|I )select "([^\"]*)" as the date$/ do |date|
|
||||
select_date(date)
|
||||
end
|
||||
|
||||
# Use this step when using multiple date_select helpers on one page or
|
||||
# you want to specify the name of the date on the form. For example:
|
||||
# When I select "April 26, 1982" as the "Date of Birth" date
|
||||
When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
|
||||
select_date(date, :from => date_label)
|
||||
end
|
||||
|
||||
When /^(?:|I )check "([^\"]*)"$/ do |field|
|
||||
check(field)
|
||||
end
|
||||
|
||||
When /^(?:|I )uncheck "([^\"]*)"$/ do |field|
|
||||
uncheck(field)
|
||||
end
|
||||
|
||||
When /^(?:|I )choose "([^\"]*)"$/ do |field|
|
||||
choose(field)
|
||||
end
|
||||
|
||||
# Adds support for validates_attachment_content_type. Without the mime-type getting
|
||||
# passed to attach_file() you will get a "Photo file is not one of the allowed file types."
|
||||
# error message
|
||||
When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"$/ do |path, field|
|
||||
type = path.split(".")[1]
|
||||
|
||||
case type
|
||||
when "jpg"
|
||||
type = "image/jpg"
|
||||
when "jpeg"
|
||||
type = "image/jpeg"
|
||||
when "png"
|
||||
type = "image/png"
|
||||
when "gif"
|
||||
type = "image/gif"
|
||||
end
|
||||
|
||||
attach_file(field, path, type)
|
||||
end
|
||||
|
||||
Then /^(?:|I )should see "([^\"]*)"$/ do |text|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
response.should contain(text)
|
||||
else
|
||||
assert_contain text
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
|
||||
within(selector) do |content|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
content.should contain(text)
|
||||
else
|
||||
assert content.include?(text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
|
||||
regexp = Regexp.new(regexp)
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
response.should contain(regexp)
|
||||
else
|
||||
assert_contain regexp
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
|
||||
within(selector) do |content|
|
||||
regexp = Regexp.new(regexp)
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
content.should contain(regexp)
|
||||
else
|
||||
assert content =~ regexp
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should not see "([^\"]*)"$/ do |text|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
response.should_not contain(text)
|
||||
else
|
||||
assert_not_contain text
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should not see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
|
||||
within(selector) do |content|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
content.should_not contain(text)
|
||||
else
|
||||
assert !content.include?(text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
|
||||
regexp = Regexp.new(regexp)
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
response.should_not contain(regexp)
|
||||
else
|
||||
assert_not_contain regexp
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should not see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
|
||||
within(selector) do |content|
|
||||
regexp = Regexp.new(regexp)
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
content.should_not contain(regexp)
|
||||
else
|
||||
assert content !~ regexp
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
field_labeled(field).value.should =~ /#{value}/
|
||||
else
|
||||
assert_match(/#{value}/, field_labeled(field).value)
|
||||
end
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
field_labeled(field).value.should_not =~ /#{value}/
|
||||
else
|
||||
assert_no_match(/#{value}/, field_labeled(field).value)
|
||||
end
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
field_labeled(label).should be_checked
|
||||
else
|
||||
assert field_labeled(label).checked?
|
||||
end
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
field_labeled(label).should_not be_checked
|
||||
else
|
||||
assert !field_labeled(label).checked?
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:|I )should be on (.+)$/ do |page_name|
|
||||
current_path = URI.parse(current_url).select(:path, :query).compact.join('?')
|
||||
if defined?(Spec::Rails::Matchers)
|
||||
current_path.should == path_to(page_name)
|
||||
else
|
||||
assert_equal path_to(page_name), current_path
|
||||
end
|
||||
end
|
||||
|
||||
Then /^show me the page$/ do
|
||||
save_and_open_page
|
||||
end
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
||||
|
||||
# Commonly used webrat steps
|
||||
# http://github.com/brynary/webrat
|
||||
|
||||
Given /^I am on (.+)$/ do |page_name|
|
||||
visit path_to(page_name)
|
||||
end
|
||||
|
||||
When /^I go to (.+)$/ do |page_name|
|
||||
visit path_to(page_name)
|
||||
end
|
||||
|
||||
When /^I press "([^\"]*)"$/ do |button|
|
||||
click_button(button)
|
||||
end
|
||||
|
||||
When /^I follow "([^\"]*)"$/ do |link|
|
||||
click_link(link)
|
||||
end
|
||||
|
||||
When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
|
||||
fill_in(field, :with => value)
|
||||
end
|
||||
|
||||
When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
|
||||
select(value, :from => field)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's datetime_select helper. For example:
|
||||
# When I select "December 25, 2008 10:00" as the date and time
|
||||
When /^I select "([^\"]*)" as the date and time$/ do |time|
|
||||
select_datetime(time)
|
||||
end
|
||||
|
||||
# Use this step when using multiple datetime_select helpers on a page or
|
||||
# you want to specify which datetime to select. Given the following view:
|
||||
# <%= f.label :preferred %><br />
|
||||
# <%= f.datetime_select :preferred %>
|
||||
# <%= f.label :alternative %><br />
|
||||
# <%= f.datetime_select :alternative %>
|
||||
# The following steps would fill out the form:
|
||||
# When I select "November 23, 2004 11:20" as the "Preferred" data and time
|
||||
# And I select "November 25, 2004 10:30" as the "Alternative" data and time
|
||||
When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
|
||||
select_datetime(datetime, :from => datetime_label)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's time_select helper. For example:
|
||||
# When I select "2:20PM" as the time
|
||||
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
|
||||
# will convert the 2:20PM to 14:20 and then select it.
|
||||
When /^I select "([^\"]*)" as the time$/ do |time|
|
||||
select_time(time)
|
||||
end
|
||||
|
||||
# Use this step when using multiple time_select helpers on a page or you want to
|
||||
# specify the name of the time on the form. For example:
|
||||
# When I select "7:30AM" as the "Gym" time
|
||||
When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
|
||||
select_time(time, :from => time_label)
|
||||
end
|
||||
|
||||
# Use this step in conjunction with Rail's date_select helper. For example:
|
||||
# When I select "February 20, 1981" as the date
|
||||
When /^I select "([^\"]*)" as the date$/ do |date|
|
||||
select_date(date)
|
||||
end
|
||||
|
||||
# Use this step when using multiple date_select helpers on one page or
|
||||
# you want to specify the name of the date on the form. For example:
|
||||
# When I select "April 26, 1982" as the "Date of Birth" date
|
||||
When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
|
||||
select_date(date, :from => date_label)
|
||||
end
|
||||
|
||||
When /^I check "([^\"]*)"$/ do |field|
|
||||
check(field)
|
||||
end
|
||||
|
||||
When /^I uncheck "([^\"]*)"$/ do |field|
|
||||
uncheck(field)
|
||||
end
|
||||
|
||||
When /^I choose "([^\"]*)"$/ do |field|
|
||||
choose(field)
|
||||
end
|
||||
|
||||
When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
|
||||
attach_file(field, path)
|
||||
end
|
||||
|
||||
Then /^I should see "([^\"]*)"$/ do |text|
|
||||
response.should contain(text)
|
||||
end
|
||||
|
||||
Then /^I should not see "([^\"]*)"$/ do |text|
|
||||
response.should_not contain(text)
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
|
||||
field_labeled(field).value.should =~ /#{value}/
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
|
||||
field_labeled(field).value.should_not =~ /#{value}/
|
||||
end
|
||||
|
||||
Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
|
||||
field_labeled(label).should be_checked
|
||||
end
|
||||
|
||||
Then /^I should be on (.+)$/ do |page_name|
|
||||
URI.parse(current_url).path.should == path_to(page_name)
|
||||
end
|
||||
|
|
@ -1,17 +1,57 @@
|
|||
# Sets up the Rails environment for Cucumber
|
||||
ENV["RAILS_ENV"] ||= "test"
|
||||
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
||||
# It is recommended to regenerate this file in the future when you upgrade to a
|
||||
# newer version of cucumber-rails. Consider adding your own code to a new file
|
||||
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
||||
# files.
|
||||
|
||||
ENV["RAILS_ENV"] ||= "cucumber"
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
||||
|
||||
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
|
||||
require 'cucumber/rails/rspec'
|
||||
require 'cucumber/rails/world'
|
||||
require 'cucumber/formatter/unicode' # Comment out this line if you don't want Cucumber Unicode support
|
||||
Cucumber::Rails.use_transactional_fixtures
|
||||
Cucumber::Rails.bypass_rescue # Comment out this line if you want Rails own error handling
|
||||
# (e.g. rescue_action_in_public / rescue_responses / rescue_from)
|
||||
require 'cucumber/rails/active_record'
|
||||
require 'cucumber/web/tableish'
|
||||
|
||||
require 'webrat'
|
||||
require 'webrat/core/matchers'
|
||||
# require 'cucumber/webrat/element_locator' # Deprecated in favor of #tableish - remove this line if you don't use #element_at or #table_at
|
||||
|
||||
Webrat.configure do |config|
|
||||
config.mode = :rails
|
||||
config.open_error_files = false # Set to true if you want error pages to pop up in the browser
|
||||
end
|
||||
|
||||
require 'cucumber/rails/rspec'
|
||||
require 'webrat/core/matchers'
|
||||
|
||||
# If you set this to false, any error raised from within your app will bubble
|
||||
# up to your step definition and out to cucumber unless you catch it somewhere
|
||||
# on the way. You can make Rails rescue errors and render error pages on a
|
||||
# per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
|
||||
#
|
||||
# If you set this to true, Rails will rescue all errors and render error
|
||||
# pages, more or less in the same way your application would behave in the
|
||||
# default production environment. It's not recommended to do this for all
|
||||
# of your scenarios, as this makes it hard to discover errors in your application.
|
||||
ActionController::Base.allow_rescue = false
|
||||
|
||||
# If you set this to true, each scenario will run in a database transaction.
|
||||
# You can still turn off transactions on a per-scenario basis, simply tagging
|
||||
# a feature or scenario with the @no-txn tag. If you are using Capybara,
|
||||
# tagging with @culerity or @javascript will also turn transactions off.
|
||||
#
|
||||
# If you set this to false, transactions will be off for all scenarios,
|
||||
# regardless of whether you use @no-txn or not.
|
||||
#
|
||||
# Beware that turning transactions off will leave data in your database
|
||||
# after each scenario, which can lead to hard-to-debug failures in
|
||||
# subsequent scenarios. If you do this, we recommend you create a Before
|
||||
# block that will explicitly put your database in a known state.
|
||||
Cucumber::Rails::World.use_transactional_fixtures = true
|
||||
|
||||
# How to clean your database when transactions are turned off. See
|
||||
# http://github.com/bmabey/database_cleaner for more info.
|
||||
require 'database_cleaner'
|
||||
DatabaseCleaner.strategy = :truncation
|
||||
|
||||
require 'factory_girl'
|
||||
Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,47 @@
|
|||
$LOAD_PATH.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib') if File.directory?(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
|
||||
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
||||
# It is recommended to regenerate this file in the future when you upgrade to a
|
||||
# newer version of cucumber-rails. Consider adding your own code to a new file
|
||||
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
||||
# files.
|
||||
|
||||
|
||||
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
|
||||
|
||||
vendored_cucumber_bin = Dir["#{RAILS_ROOT}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
|
||||
$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
|
||||
|
||||
begin
|
||||
require 'cucumber/rake/task'
|
||||
|
||||
Cucumber::Rake::Task.new(:features) do |t|
|
||||
t.cucumber_opts = "--format pretty"
|
||||
namespace :cucumber do
|
||||
Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
|
||||
t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
|
||||
t.fork = true # You may get faster startup if you set this to false
|
||||
t.profile = 'default'
|
||||
end
|
||||
|
||||
Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
|
||||
t.binary = vendored_cucumber_bin
|
||||
t.fork = true # You may get faster startup if you set this to false
|
||||
t.profile = 'wip'
|
||||
end
|
||||
|
||||
desc 'Run all features'
|
||||
task :all => [:ok, :wip]
|
||||
end
|
||||
desc 'Alias for cucumber:ok'
|
||||
task :cucumber => 'cucumber:ok'
|
||||
|
||||
task :default => :cucumber
|
||||
|
||||
task :features => :cucumber do
|
||||
STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
|
||||
end
|
||||
task :features => 'db:test:prepare'
|
||||
rescue LoadError
|
||||
desc 'Cucumber rake task not available'
|
||||
task :features do
|
||||
desc 'cucumber rake task not available (cucumber not installed)'
|
||||
task :cucumber do
|
||||
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,51 @@
|
|||
raise "To avoid rake task loading problems: run 'rake clobber' in vendor/plugins/rspec" if File.directory?(File.join(File.dirname(__FILE__), *%w[.. .. vendor plugins rspec pkg]))
|
||||
raise "To avoid rake task loading problems: run 'rake clobber' in vendor/plugins/rspec-rails" if File.directory?(File.join(File.dirname(__FILE__), *%w[.. .. vendor plugins rspec-rails pkg]))
|
||||
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
||||
rspec_gem_dir = nil
|
||||
Dir["#{RAILS_ROOT}/vendor/gems/*"].each do |subdir|
|
||||
rspec_gem_dir = subdir if subdir.gsub("#{RAILS_ROOT}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
|
||||
end
|
||||
rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec')
|
||||
|
||||
# In rails 1.2, plugins aren't available in the path until they're loaded.
|
||||
# Check to see if the rspec plugin is installed first and require
|
||||
# it if it is. If not, use the gem version.
|
||||
rspec_base = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec/lib')
|
||||
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
|
||||
require 'spec/rake/spectask'
|
||||
if rspec_gem_dir && (test ?d, rspec_plugin_dir)
|
||||
raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
|
||||
end
|
||||
|
||||
if rspec_gem_dir
|
||||
$LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
|
||||
elsif File.exist?(rspec_plugin_dir)
|
||||
$LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
|
||||
end
|
||||
|
||||
# Don't load rspec if running "rake gems:*"
|
||||
unless ARGV.any? {|a| a =~ /^gems/}
|
||||
|
||||
begin
|
||||
require 'spec/rake/spectask'
|
||||
rescue MissingSourceFile
|
||||
module Spec
|
||||
module Rake
|
||||
class SpecTask
|
||||
def initialize(name)
|
||||
task name do
|
||||
# if rspec-rails is a configured gem, this will output helpful material and exit ...
|
||||
require File.expand_path(File.join(File.dirname(__FILE__),"..","..","config","environment"))
|
||||
|
||||
# ... otherwise, do this:
|
||||
raise <<-MSG
|
||||
|
||||
#{"*" * 80}
|
||||
* You are trying to run an rspec rake task defined in
|
||||
* #{__FILE__},
|
||||
* but rspec can not be found in vendor/gems, vendor/plugins or system gems.
|
||||
#{"*" * 80}
|
||||
MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Rake.application.instance_variable_get('@tasks').delete('default')
|
||||
|
||||
spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop
|
||||
task :noop do
|
||||
|
|
@ -31,33 +70,33 @@ namespace :spec do
|
|||
IO.readlines("#{RAILS_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc "Print Specdoc for all specs (excluding plugin specs)"
|
||||
Spec::Rake::SpecTask.new(:doc) do |t|
|
||||
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
||||
t.spec_files = FileList['spec/**/*_spec.rb']
|
||||
end
|
||||
|
||||
desc "Print Specdoc for all plugin specs"
|
||||
desc "Print Specdoc for all plugin examples"
|
||||
Spec::Rake::SpecTask.new(:plugin_doc) do |t|
|
||||
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
||||
t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*')
|
||||
end
|
||||
|
||||
[:models, :controllers, :views, :helpers, :lib].each do |sub|
|
||||
desc "Run the specs under spec/#{sub}"
|
||||
[:models, :controllers, :views, :helpers, :lib, :integration].each do |sub|
|
||||
desc "Run the code examples in spec/#{sub}"
|
||||
Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
|
||||
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
|
||||
t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
|
||||
end
|
||||
end
|
||||
|
||||
desc "Run the specs under vendor/plugins (except RSpec's own)"
|
||||
|
||||
desc "Run the code examples in vendor/plugins (except RSpec's own)"
|
||||
Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t|
|
||||
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
|
||||
t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec-rails/*")
|
||||
end
|
||||
|
||||
|
||||
namespace :plugins do
|
||||
desc "Runs the examples for rspec_on_rails"
|
||||
Spec::Rake::SpecTask.new(:rspec_on_rails) do |t|
|
||||
|
|
@ -74,59 +113,32 @@ namespace :spec do
|
|||
::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
|
||||
::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers')
|
||||
::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
|
||||
::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing')
|
||||
::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration')
|
||||
::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
|
||||
::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
|
||||
::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
|
||||
::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers')
|
||||
::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
|
||||
::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
|
||||
::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing')
|
||||
::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration')
|
||||
end
|
||||
|
||||
namespace :db do
|
||||
namespace :fixtures do
|
||||
desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
||||
desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z."
|
||||
task :load => :environment do
|
||||
ActiveRecord::Base.establish_connection(Rails.env)
|
||||
base_dir = File.join(Rails.root, 'spec', 'fixtures')
|
||||
fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir
|
||||
|
||||
require 'active_record/fixtures'
|
||||
ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
|
||||
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
||||
Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
|
||||
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir.glob(File.join(fixtures_dir, '*.{yml,csv}'))).each do |fixture_file|
|
||||
Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :server do
|
||||
daemonized_server_pid = File.expand_path("spec_server.pid", RAILS_ROOT + "/tmp")
|
||||
|
||||
desc "start spec_server."
|
||||
task :start do
|
||||
if File.exist?(daemonized_server_pid)
|
||||
$stderr.puts "spec_server is already running."
|
||||
else
|
||||
$stderr.puts "Starting up spec server."
|
||||
system("ruby", "script/spec_server", "--daemon", "--pid", daemonized_server_pid)
|
||||
end
|
||||
end
|
||||
|
||||
desc "stop spec_server."
|
||||
task :stop do
|
||||
unless File.exist?(daemonized_server_pid)
|
||||
$stderr.puts "No server running."
|
||||
else
|
||||
$stderr.puts "Shutting down spec_server."
|
||||
system("kill", "-s", "TERM", File.read(daemonized_server_pid).strip) &&
|
||||
File.delete(daemonized_server_pid)
|
||||
end
|
||||
end
|
||||
|
||||
desc "reload spec_server."
|
||||
task :restart do
|
||||
unless File.exist?(daemonized_server_pid)
|
||||
$stderr.puts "No server running."
|
||||
else
|
||||
$stderr.puts "Reloading down spec_server."
|
||||
system("kill", "-s", "USR2", File.read(daemonized_server_pid).strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,5 +11,17 @@ module Tracks
|
|||
def self.openid_enabled?
|
||||
auth_schemes.include?('open_id')
|
||||
end
|
||||
|
||||
def self.cas_enabled?
|
||||
auth_schemes.include?('cas')
|
||||
end
|
||||
|
||||
def self.prefered_auth?
|
||||
if SITE_CONFIG['prefered_auth']
|
||||
SITE_CONFIG['prefered_auth']
|
||||
else
|
||||
auth_schemes.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -187,11 +187,11 @@ function project_defaults(){
|
|||
function enable_rich_interaction(){
|
||||
$('input.Date').datepicker({'dateFormat': dateFormat});
|
||||
/* Autocomplete */
|
||||
$('input[name=context_name]').autocomplete(contextNames, {matchContains: true});
|
||||
$('input[name=project[default_context_name]]').autocomplete(contextNames, {matchContains: true});
|
||||
$('input[name=project_name]').autocomplete(projectNames, {matchContains: true});
|
||||
$('input[name=tag_list]').autocomplete(tagNames, {multiple: true,multipleSeparator:',',matchContains:true});
|
||||
$('input[name=predecessor_list]').autocomplete('/todos/auto_complete_for_predecessor',
|
||||
$('input[name=context_name]:not(.ac_input)').autocomplete(contextNames, {matchContains: true});
|
||||
$('input[name=project[default_context_name]]:not(.ac_input)').autocomplete(contextNames, {matchContains: true});
|
||||
$('input[name=project_name]:not(.ac_input)').autocomplete(projectNames, {matchContains: true});
|
||||
$('input[name=tag_list]:not(.ac_input)').autocomplete(tagNames, {multiple: true,multipleSeparator:',',matchContains:true});
|
||||
$('input[name=predecessor_list]:not(.ac_input)').autocomplete('/todos/auto_complete_for_predecessor',
|
||||
{multiple: true,multipleSeparator:','});
|
||||
|
||||
/* have to bind on keypress because of limitataions of live() */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
||||
ENV['RSPEC'] = 'true' # allows autotest to discover rspec
|
||||
ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux
|
||||
system (RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV
|
||||
system((RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV) ||
|
||||
$stderr.puts("Unable to find autotest. Please install ZenTest or fix your PATH")
|
||||
|
|
|
|||
16
script/cucumber
Normal file → Executable file
16
script/cucumber
Normal file → Executable file
|
|
@ -1,8 +1,10 @@
|
|||
#!/usr/bin/env ruby
|
||||
begin
|
||||
load File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/cucumber/bin/cucumber")
|
||||
rescue LoadError => e
|
||||
raise unless e.to_s =~ /cucumber/
|
||||
require "rubygems"
|
||||
load File.join(Gem.bindir, "cucumber")
|
||||
end
|
||||
|
||||
vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
|
||||
if vendored_cucumber_bin
|
||||
load File.expand_path(vendored_cucumber_bin)
|
||||
else
|
||||
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
||||
require 'cucumber'
|
||||
load Cucumber::BINARY
|
||||
end
|
||||
|
|
|
|||
13
script/spec
13
script/spec
|
|
@ -1,5 +1,10 @@
|
|||
#!/usr/bin/env ruby
|
||||
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib"))
|
||||
require 'rubygems'
|
||||
require 'spec'
|
||||
exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT))
|
||||
if ARGV.any? {|arg| %w[--drb -X --generate-options -G --help -h --version -v].include?(arg)}
|
||||
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
||||
else
|
||||
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT)
|
||||
end
|
||||
require 'spec/autorun'
|
||||
exit ::Spec::Runner::CommandLine.run
|
||||
|
|
|
|||
11
spec/fixtures/todos.yml
vendored
11
spec/fixtures/todos.yml
vendored
|
|
@ -55,3 +55,14 @@ buymilk:
|
|||
due: ~
|
||||
completed_at: <%= today %>
|
||||
user: admin_user
|
||||
|
||||
callmom:
|
||||
id: 5
|
||||
context_id: 3 # call
|
||||
project_id: ~
|
||||
description: Call mom
|
||||
notes: Remember her birthday
|
||||
state: active
|
||||
due: ~
|
||||
completed_at: ~
|
||||
user: admin_user
|
||||
|
|
|
|||
|
|
@ -51,37 +51,37 @@ describe Context do
|
|||
end
|
||||
|
||||
describe 'when finding by namepart' do
|
||||
scenario :todos
|
||||
fixtures :todos, :contexts
|
||||
|
||||
it 'finds with exact match' do
|
||||
Context.find_by_namepart('errand').should == contexts(:errand)
|
||||
Context.find_by_namepart('agenda').should == contexts(:agenda)
|
||||
end
|
||||
|
||||
it 'finds with partial match' do
|
||||
Context.find_by_namepart('err').should == contexts(:errand)
|
||||
Context.find_by_namepart('age').should == contexts(:agenda)
|
||||
end
|
||||
|
||||
it 'deletes todos within context when context deleted' do
|
||||
contexts(:call).should have(2).todos
|
||||
call_todos = contexts(:call).todos
|
||||
contexts(:call).destroy
|
||||
contexts(:agenda).should have(3).todos
|
||||
call_todos = contexts(:agenda).todos
|
||||
contexts(:agenda).destroy
|
||||
Todo.find(:all).should_not include(call_todos)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when counting todos' do
|
||||
scenario :todos
|
||||
fixtures :todos, :contexts, :users, :preferences
|
||||
|
||||
it 'returns correct number of completed todos' do
|
||||
contexts(:call).should_not have(:any).done_todos
|
||||
contexts(:call).done_todos.should_not have(:any).items
|
||||
contexts(:call).todos.first.complete!
|
||||
contexts(:call).should have(1).done_todos
|
||||
Context.find(contexts(:call).id).done_todos.should have(1).items
|
||||
end
|
||||
|
||||
it 'returns correct number of not done todos' do
|
||||
contexts(:call).should have(2).not_done_todos
|
||||
contexts(:call).todos.last.complete!
|
||||
contexts(:call).should have(1).not_done_todos
|
||||
contexts(:agenda).todos.not_completed.should have(2).items
|
||||
contexts(:agenda).todos.last.complete!
|
||||
contexts(:agenda).todos.not_completed.should have(1).items
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ describe Todo do
|
|||
def valid_attributes(attributes={})
|
||||
{
|
||||
:description => "don't forget the milk",
|
||||
:context => mock_model(Context, :name => 'errands')
|
||||
:context => mock_model(Context, :name => 'errands', :destroyed? => false)
|
||||
}.merge(attributes)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
--exclude "spec/*,gems/*"
|
||||
--exclude "spec/*,gems/*"
|
||||
--rails
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
class ContextsScenario < Scenario::Base
|
||||
uses :users
|
||||
|
||||
def load
|
||||
%w(Call Email Errand Someday).each_with_index do |context, index|
|
||||
create_context context, index+1
|
||||
end
|
||||
end
|
||||
|
||||
def create_context(name, position)
|
||||
create_model :context, name.downcase.to_sym,
|
||||
:name => name,
|
||||
:position => position,
|
||||
:hide => name == 'Someday' ? true : false,
|
||||
:created_at => Time.now,
|
||||
:updated_at => Time.now,
|
||||
:user_id => user_id(:sean)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
class ProjectsScenario < Scenario::Base
|
||||
def load
|
||||
create_project :build_time_machine, 'Build a working time machine'
|
||||
create_project :make_more_money, 'Make more money than Billy Gates'
|
||||
create_project :evict_dinosaurs, 'Evict dinosaurs from the garden'
|
||||
create_project :attend_railsconf, 'Attend RailsConf'
|
||||
end
|
||||
|
||||
def create_project(identifier, name)
|
||||
attributes = {
|
||||
:name => name,
|
||||
:state => 'active',
|
||||
:created_at => 4.day.ago,
|
||||
:updated_at => 1.minute.ago
|
||||
}
|
||||
create_model :project,
|
||||
identifier || attributes[:name].split.first.downcase.to_sym,
|
||||
attributes
|
||||
end
|
||||
end
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
class TodosScenario < Scenario::Base
|
||||
uses :contexts, :projects, :users
|
||||
|
||||
def load
|
||||
create_todo :bill,
|
||||
:description => 'Call Bill Gates to find out how much he makes per day',
|
||||
:user => :sean,
|
||||
:context => :call,
|
||||
:project => :make_more_money
|
||||
create_todo :bank,
|
||||
:description => 'Call my bank',
|
||||
:user => :sean,
|
||||
:context => :call,
|
||||
:project => :make_more_money
|
||||
end
|
||||
|
||||
def create_todo(identifier, options={})
|
||||
context = options.delete(:context)
|
||||
project = options.delete(:project)
|
||||
user = options.delete(:user)
|
||||
attributes = {
|
||||
:state => 'active',
|
||||
:created_at => 1.week.ago,
|
||||
:context_id => context_id(context),
|
||||
:project_id => project_id(project),
|
||||
:user_id => user_id(user)
|
||||
}.merge(options)
|
||||
create_model :todo, identifier, attributes
|
||||
end
|
||||
end
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
class UsersScenario < Scenario::Base
|
||||
def load
|
||||
create_user :login => 'johnny', :first_name => 'Johnny', :last_name => 'Smith'
|
||||
create_user :login => 'jane', :first_name => 'Jane', :last_name => 'Pilbeam'
|
||||
create_user :login => 'sean', :first_name => 'Sean', :last_name => 'Pallmer'
|
||||
end
|
||||
|
||||
def create_user(attributes={})
|
||||
password = attributes[:login] + Time.now.to_s
|
||||
attributes = {
|
||||
:password => password,
|
||||
:password_confirmation => password,
|
||||
:is_admin => attributes[:is_admin] || false,
|
||||
}.merge(attributes)
|
||||
identifier = attributes[:login].downcase.to_sym
|
||||
user = create_model :user, identifier, attributes
|
||||
Preference.create(:show_number_completed => 5, :user => user)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,37 +1,14 @@
|
|||
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
||||
# from the project root directory.
|
||||
ENV["RAILS_ENV"] = "test"
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
||||
require 'spec'
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment'))
|
||||
require 'spec/autorun'
|
||||
require 'spec/rails'
|
||||
require 'skinny_spec'
|
||||
require 'scenarios'
|
||||
|
||||
module LuckySneaks
|
||||
module ModelSpecHelpers
|
||||
module ExampleGroupLevelMethods
|
||||
def it_should_validate_length_of(attribute, options={})
|
||||
maximum = options[:maximum] || (options[:within] || []).last || false
|
||||
minimum = options[:minimum] || (options[:within] || []).first || false
|
||||
raise ArgumentError unless maximum || minimum
|
||||
|
||||
it "should not be valid if #{attribute} length is more than #{maximum}" do
|
||||
instance.send "#{attribute}=", 'x'*(maximum+1)
|
||||
instance.errors_on(attribute).should include(
|
||||
options[:message_too_long] || I18n.t('activerecord.errors.messages.too_long', :count => maximum)
|
||||
)
|
||||
end if maximum
|
||||
|
||||
it "should not be valid if #{attribute} length is less than #{minimum}" do
|
||||
instance.send "#{attribute}=", 'x'*(minimum-1)
|
||||
instance.errors_on(attribute).should include(
|
||||
options[:message_to_short] || I18n.t('activerecord.errors.messages.too_short', :count => minimum)
|
||||
)
|
||||
end if minimum
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# Requires supporting files with custom matchers and macros, etc,
|
||||
# in ./support/ and its subdirectories.
|
||||
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
||||
|
||||
Spec::Runner.configure do |config|
|
||||
# If you're not using ActiveRecord you should remove these
|
||||
|
|
@ -70,6 +47,6 @@ Spec::Runner.configure do |config|
|
|||
# config.mock_with :rr
|
||||
#
|
||||
# == Notes
|
||||
#
|
||||
# For more information take a look at Spec::Example::Configuration and Spec::Runner
|
||||
#
|
||||
# For more information take a look at Spec::Runner::Configuration and Spec::Runner
|
||||
end
|
||||
|
|
|
|||
25
spec/support/should_validate_length_of.rb
Normal file
25
spec/support/should_validate_length_of.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
module LuckySneaks
|
||||
module ModelSpecHelpers
|
||||
module ExampleGroupLevelMethods
|
||||
def it_should_validate_length_of(attribute, options={})
|
||||
maximum = options[:maximum] || (options[:within] || []).last || false
|
||||
minimum = options[:minimum] || (options[:within] || []).first || false
|
||||
raise ArgumentError unless maximum || minimum
|
||||
|
||||
it "should not be valid if #{attribute} length is more than #{maximum}" do
|
||||
instance.send "#{attribute}=", 'x'*(maximum+1)
|
||||
instance.errors_on(attribute).should include(
|
||||
options[:message_too_long] || I18n.t('activerecord.errors.messages.too_long', :count => maximum)
|
||||
)
|
||||
end if maximum
|
||||
|
||||
it "should not be valid if #{attribute} length is less than #{minimum}" do
|
||||
instance.send "#{attribute}=", 'x'*(minimum-1)
|
||||
instance.errors_on(attribute).should include(
|
||||
options[:message_to_short] || I18n.t('activerecord.errors.messages.too_short', :count => minimum)
|
||||
)
|
||||
end if minimum
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
18
test/fixtures/contexts.yml
vendored
18
test/fixtures/contexts.yml
vendored
|
|
@ -131,3 +131,21 @@ anothercontext:
|
|||
user_id: 4
|
||||
created_at: <%= today %>
|
||||
updated_at: <%= today %>
|
||||
|
||||
inbox:
|
||||
id: 15
|
||||
name: Inbox
|
||||
position: 1
|
||||
hide: false
|
||||
user_id: 5
|
||||
created_at: <%= today %>
|
||||
updated_at: <%= today %>
|
||||
|
||||
anothercontext:
|
||||
id: 16
|
||||
name: anothercontext
|
||||
position: 2
|
||||
hide: false
|
||||
user_id: 5
|
||||
created_at: <%= today %>
|
||||
updated_at: <%= today %>
|
||||
3
test/fixtures/dependencies.yml
vendored
Normal file
3
test/fixtures/dependencies.yml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
buy_stock_then_email_broker:
|
||||
successor_id: 19
|
||||
predecessor_id: 11
|
||||
20
test/fixtures/preferences.yml
vendored
20
test/fixtures/preferences.yml
vendored
|
|
@ -53,4 +53,22 @@ sms_user_prefs:
|
|||
verbose_action_descriptors: false
|
||||
show_project_on_todo_done: true
|
||||
sms_email: 5555555555@tmomail.net
|
||||
sms_context_id: 13
|
||||
sms_context_id: 13
|
||||
|
||||
other_user_prefs:
|
||||
id: 4
|
||||
user_id: 5
|
||||
staleness_starts: 7
|
||||
date_format: "%d/%m/%Y"
|
||||
title_date_format: "%A, %d %B %Y"
|
||||
show_number_completed: 5
|
||||
show_completed_projects_in_sidebar: true
|
||||
show_hidden_contexts_in_sidebar: true
|
||||
show_hidden_projects_in_sidebar: true
|
||||
admin_email: butshesagirl@rousette.org.uk
|
||||
week_starts: 1
|
||||
due_style: 0
|
||||
refresh: 0
|
||||
time_zone: "Los_Angeles"
|
||||
verbose_action_descriptors: false
|
||||
show_project_on_todo_done: true
|
||||
|
|
|
|||
11
test/fixtures/todos.yml
vendored
11
test/fixtures/todos.yml
vendored
|
|
@ -243,4 +243,13 @@ call_bill_gates_every_day:
|
|||
due: <%= last_week %>
|
||||
completed_at: ~
|
||||
show_from: ~
|
||||
recurring_todo_id: 1
|
||||
recurring_todo_id: 1
|
||||
|
||||
email_broker:
|
||||
id: 19
|
||||
user_id: 1
|
||||
context_id: 3
|
||||
description: Ask about better stocks
|
||||
notes: ~
|
||||
state: pending
|
||||
|
||||
|
|
|
|||
12
test/fixtures/users.yml
vendored
12
test/fixtures/users.yml
vendored
|
|
@ -37,4 +37,14 @@ sms_user:
|
|||
is_admin: false
|
||||
first_name: SMS
|
||||
last_name: Tester
|
||||
auth_type: database
|
||||
auth_type: database
|
||||
|
||||
ldap_user:
|
||||
id: 5
|
||||
login: john
|
||||
crypted_password: test
|
||||
token: <%= Digest::SHA1.hexdigest("internationalSun Feb 19 14:42:45 GMT 20060.408173979260027") %>
|
||||
is_admin: false
|
||||
first_name: International
|
||||
last_name: Harvester
|
||||
auth_type: CAS
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class LoginControllerTest < ActionController::TestCase
|
|||
def test_should_delete_token_on_logout
|
||||
login_as :other_user
|
||||
get :logout
|
||||
assert_equal @response.cookies["auth_token"], []
|
||||
assert_nil @response.cookies["auth_token"]
|
||||
end
|
||||
|
||||
def test_should_login_with_cookie
|
||||
|
|
@ -110,7 +110,7 @@ class LoginControllerTest < ActionController::TestCase
|
|||
|
||||
def test_should_fail_cookie_login
|
||||
users(:other_user).remember_me
|
||||
@request.cookies["auth_token"] = CGI::Cookie.new('name' => 'auth_token', 'value' => 'invalid_auth_token')
|
||||
@request.cookies["auth_token"] = 'invalid_auth_token'
|
||||
get :login
|
||||
assert !@controller.send(:logged_in?)
|
||||
end
|
||||
|
|
@ -139,7 +139,7 @@ class LoginControllerTest < ActionController::TestCase
|
|||
private
|
||||
|
||||
def auth_token_cookie_for(user)
|
||||
CGI::Cookie.new('name' => 'auth_token', 'value' => users(user).remember_token)
|
||||
users(user).remember_token
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class StatsControllerTest < ActionController::TestCase
|
|||
assert_equal 3, assigns['projects'].count
|
||||
assert_equal 3, assigns['projects'].count(:conditions => "state = 'active'")
|
||||
assert_equal 10, assigns['contexts'].count
|
||||
assert_equal 16, assigns['actions'].count
|
||||
assert_equal 17, assigns['actions'].count
|
||||
assert_equal 4, assigns['tags_count']
|
||||
assert_equal 2, assigns['unique_tags_count']
|
||||
assert_equal 2.week.ago.at_midnight, assigns['first_action'].created_at.at_midnight
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class TodosControllerTest < ActionController::TestCase
|
|||
end
|
||||
|
||||
def test_create_todo
|
||||
assert_difference Todo, :count do
|
||||
assert_difference 'Todo.count' do
|
||||
login_as(:admin_user)
|
||||
put :create, :_source_view => 'todo', "context_name"=>"library", "project_name"=>"Build a working time machine", "todo"=>{"notes"=>"", "description"=>"Call Warren Buffet to find out how much he makes per day", "due"=>"30/11/2006"}, "tag_list"=>"foo bar"
|
||||
end
|
||||
|
|
@ -82,32 +82,12 @@ class TodosControllerTest < ActionController::TestCase
|
|||
|
||||
def test_create_todo_via_xml
|
||||
login_as(:admin_user)
|
||||
assert_difference Todo, :count do
|
||||
assert_difference 'Todo.count' do
|
||||
put :create, :format => "xml", "request" => { "context_name"=>"library", "project_name"=>"Build a working time machine", "todo"=>{"notes"=>"", "description"=>"Call Warren Buffet to find out how much he makes per day", "due"=>"30/11/2006"}, "tag_list"=>"foo bar" }
|
||||
assert_response 201
|
||||
end
|
||||
end
|
||||
|
||||
def test_create_todo_via_xml_show_from
|
||||
login_as(:admin_user)
|
||||
|
||||
assert_difference Todo, :count do
|
||||
xml = "<todo><description>Call Warren Buffet to find out how much he makes per day</description><project_id>#{projects(:timemachine).id}</project_id><context_id>#{contexts(:agenda).id}</context_id><show-from type=\"datetime\">#{1.week.from_now.xmlschema}</show-from></todo>"
|
||||
|
||||
# p parse_xml_body(xml)
|
||||
post :create, parse_xml_body(xml).update(:format => "xml")
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
|
||||
def parse_xml_body(body)
|
||||
env = { 'rack.input' => StringIO.new(body),
|
||||
'HTTP_X_POST_DATA_FORMAT' => 'xml',
|
||||
'CONTENT_LENGTH' => body.size.to_s }
|
||||
ActionController::RackRequest.new(env).request_parameters
|
||||
end
|
||||
|
||||
|
||||
def test_fail_to_create_todo_via_xml
|
||||
login_as(:admin_user)
|
||||
# #try to create with no context, which is not valid
|
||||
|
|
@ -466,10 +446,8 @@ class TodosControllerTest < ActionController::TestCase
|
|||
# check that the new_todo is in the tickler to show next month
|
||||
assert !new_todo.show_from.nil?
|
||||
|
||||
# use Time.zone.local and not today+1.month because the latter messes up
|
||||
# the timezone.
|
||||
next_month = Time.zone.local(today.year, today.month+1, today.day)
|
||||
assert_equal next_month.to_s(:db), new_todo.show_from.to_s(:db)
|
||||
next_month = today + 1.month
|
||||
assert_equal next_month.utc.to_date.to_s(:db), new_todo.show_from.utc.to_date.to_s(:db)
|
||||
end
|
||||
|
||||
def test_check_for_next_todo
|
||||
|
|
@ -532,4 +510,55 @@ class TodosControllerTest < ActionController::TestCase
|
|||
assert_select("a[href=#{url}]")
|
||||
end
|
||||
|
||||
def test_format_note_normal
|
||||
login_as(:admin_user)
|
||||
todo = users(:admin_user).todos.first
|
||||
todo.notes = "A normal description."
|
||||
todo.save!
|
||||
get :index
|
||||
assert_select("div#notes_todo_#{todo.id}", "A normal description.")
|
||||
end
|
||||
|
||||
def test_format_note_markdown
|
||||
login_as(:admin_user)
|
||||
todo = users(:admin_user).todos.first
|
||||
todo.notes = "A *bold description*."
|
||||
todo.save!
|
||||
get :index
|
||||
assert_select("div#notes_todo_#{todo.id}", "A bold description.")
|
||||
assert_select("div#notes_todo_#{todo.id} strong", "bold description")
|
||||
end
|
||||
|
||||
def test_format_note_link
|
||||
login_as(:admin_user)
|
||||
todo = users(:admin_user).todos.first
|
||||
todo.notes = "A link to http://github.com/."
|
||||
todo.save!
|
||||
get :index
|
||||
assert_select("div#notes_todo_#{todo.id}", 'A link to http://github.com/.')
|
||||
assert_select("div#notes_todo_#{todo.id} a[href=http://github.com/]", 'http://github.com/')
|
||||
end
|
||||
|
||||
def test_format_note_link_message
|
||||
login_as(:admin_user)
|
||||
todo = users(:admin_user).todos.first
|
||||
todo.notes = "A Mail.app message://<ABCDEF-GHADB-123455-FOO-BAR@example.com> link"
|
||||
todo.save!
|
||||
get :index
|
||||
# puts css_select("div#notes_todo_#{todo.id}")
|
||||
assert_select("div#notes_todo_#{todo.id}", 'A Mail.app message://<ABCDEF-GHADB-123455-FOO-BAR@example.com> link')
|
||||
assert_select("div#notes_todo_#{todo.id} a", 'message://<ABCDEF-GHADB-123455-FOO-BAR@example.com>')
|
||||
assert_select("div#notes_todo_#{todo.id} a[href=message://<ABCDEF-GHADB-123455-FOO-BAR@example.com>]", 'message://<ABCDEF-GHADB-123455-FOO-BAR@example.com>')
|
||||
end
|
||||
|
||||
def test_format_note_link_onenote
|
||||
login_as(:admin_user)
|
||||
todo = users(:admin_user).todos.first
|
||||
todo.notes = ' "link me to onenote":onenote:///E:\OneNote\dir\notes.one#PAGE§ion-id={FD597D3A-3793-495F-8345-23D34A00DD3B}&page-id={1C95A1C7-6408-4804-B3B5-96C28426022B}&end'
|
||||
todo.save!
|
||||
get :index
|
||||
assert_select("div#notes_todo_#{todo.id}", 'link me to onenote')
|
||||
assert_select("div#notes_todo_#{todo.id} a", 'link me to onenote')
|
||||
assert_select("div#notes_todo_#{todo.id} a[href=onenote:///E:\\OneNote\\dir\\notes.one#PAGE&section-id={FD597D3A-3793-495F-8345-23D34A00DD3B}&page-id={1C95A1C7-6408-4804-B3B5-96C28426022B}&end]", 'link me to onenote')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class UsersControllerTest < ActionController::TestCase
|
|||
|
||||
def test_create_adds_a_user
|
||||
login_as :admin_user
|
||||
assert_difference(User, :count) do
|
||||
assert_difference 'User.count' do
|
||||
post :create, :user => {:login => 'newbie', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
|
||||
end
|
||||
end
|
||||
|
|
@ -132,7 +132,7 @@ class UsersControllerTest < ActionController::TestCase
|
|||
#
|
||||
def test_create_by_non_admin
|
||||
login_as :other_user
|
||||
assert_no_difference(User, :count) do
|
||||
assert_no_difference 'User.count' do
|
||||
post :create, :user => {:login => 'newbie2', :password => 'newbiepass2', :password_confirmation => 'newbiepass2'}
|
||||
end
|
||||
assert_response :success
|
||||
|
|
@ -145,7 +145,7 @@ class UsersControllerTest < ActionController::TestCase
|
|||
|
||||
def test_create_with_invalid_password_does_not_add_a_new_user
|
||||
login_as :admin_user
|
||||
assert_no_difference(User, :count) do
|
||||
assert_no_difference 'User.count' do
|
||||
post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''}
|
||||
end
|
||||
end
|
||||
|
|
@ -170,7 +170,7 @@ class UsersControllerTest < ActionController::TestCase
|
|||
|
||||
def test_create_with_duplicate_login_does_not_add_a_new_user
|
||||
login_as :admin_user
|
||||
assert_no_difference(User, :count) do
|
||||
assert_no_difference 'User.count' do
|
||||
post :create, :user => {:login => 'jane', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,12 +13,7 @@ class ContextXmlApiTest < ActionController::IntegrationTest
|
|||
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
|
||||
# Fails too hard for test to catch
|
||||
# authenticated_post_xml_to_context_create "<foo></bar>"
|
||||
|
|
@ -56,7 +51,7 @@ class ContextXmlApiTest < ActionController::IntegrationTest
|
|||
end
|
||||
|
||||
def test_creates_new_context
|
||||
assert_difference Context, :count do
|
||||
assert_difference 'Context.count' do
|
||||
authenticated_post_xml_to_context_create
|
||||
assert_response 201
|
||||
end
|
||||
|
|
@ -74,4 +69,4 @@ class ContextXmlApiTest < ActionController::IntegrationTest
|
|||
assert_response_and_body 400, "Expected post format is valid xml like so: <request><context><name>context name</name></context></request>."
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,12 +13,7 @@ class ProjectXmlApiTest < ActionController::IntegrationTest
|
|||
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
|
||||
#Fails too hard for test to catch
|
||||
# authenticated_post_xml_to_project_create "<foo></bar>"
|
||||
|
|
@ -50,7 +45,7 @@ class ProjectXmlApiTest < ActionController::IntegrationTest
|
|||
end
|
||||
|
||||
def test_creates_new_project
|
||||
assert_difference Project, :count do
|
||||
assert_difference 'Project.count' do
|
||||
authenticated_post_xml_to_project_create
|
||||
assert_response :created
|
||||
end
|
||||
|
|
@ -68,4 +63,4 @@ class ProjectXmlApiTest < ActionController::IntegrationTest
|
|||
assert_response_and_body 404, "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
8
test/selenium/dependencies/assign_dependency.rsel
Normal file
8
test/selenium/dependencies/assign_dependency.rsel
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
setup :fixtures => :all
|
||||
login :as => 'admin'
|
||||
open "/"
|
||||
drag_todo_to 18, 9
|
||||
wait_for_visible 'css=#todo_9 a.show_successors img'
|
||||
click 'css=#todo_9 a.show_successors img'
|
||||
assert_visible 'successors_todo_9'
|
||||
assert_visible 'css=#successors_todo_9 #successor_todo_18'
|
||||
8
test/selenium/dependencies/unhide_hidden_context.rsel
Normal file
8
test/selenium/dependencies/unhide_hidden_context.rsel
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Test for issue #964
|
||||
setup :fixtures => :all
|
||||
login :as => 'admin'
|
||||
Todo.create(:context => Context.find(3), :description => 'foo')
|
||||
open "/"
|
||||
click "css=#successor_todo_19 img.delete_item"
|
||||
wait_for_visible 'flash'
|
||||
assert_visible 'c3'
|
||||
7
test/selenium/login/_cas_first_admin.rsel
Normal file
7
test/selenium/login/_cas_first_admin.rsel
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
open :controller => 'login'
|
||||
type "username", username
|
||||
type "password", password
|
||||
click "//input[@value='Login']"
|
||||
wait_for_page_to_load "30000"
|
||||
click "signup"
|
||||
wait_for_page_to_load "30000"
|
||||
11
test/selenium/login/_cas_first_normal_user.rsel
Normal file
11
test/selenium/login/_cas_first_normal_user.rsel
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
open :controller => 'login'
|
||||
click "link=Login"
|
||||
wait_for_page_to_load "30000"
|
||||
type "username", username
|
||||
type "password", password
|
||||
click "//input[@value='Login']"
|
||||
wait_for_page_to_load "30000"
|
||||
click "link=Request Account"
|
||||
wait_for_page_to_load "30000"
|
||||
click "signup"
|
||||
wait_for_page_to_load "30000"
|
||||
6
test/selenium/login/_cas_normal_user_login.rsel
Normal file
6
test/selenium/login/_cas_normal_user_login.rsel
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
open :controller => 'login'
|
||||
click "link=Login"
|
||||
wait_for_page_to_load "30000"
|
||||
type "username", username
|
||||
type "password", password
|
||||
click "//input[@value='Login']"
|
||||
|
|
@ -31,5 +31,5 @@ wait_for_text 'css=h1 span.count', '2'
|
|||
|
||||
# just test the navigation.
|
||||
click_and_wait "link=Tickler"
|
||||
wait_for_text 'css=h1 span.count', '0'
|
||||
wait_for_text 'css=h1 span.count', '1'
|
||||
click_and_wait "link=Feeds"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ type "todo_description", "test1"
|
|||
click "css=#todo-form-new-action .submit_box button"
|
||||
|
||||
wait_for_visible "flash"
|
||||
wait_for_not_visible "flash"
|
||||
|
||||
type "todo_description", "test2"
|
||||
click "css=#todo-form-new-action .submit_box button"
|
||||
|
|
|
|||
7
test/selenium/tags/complete_last_todo.rsel
Normal file
7
test/selenium/tags/complete_last_todo.rsel
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#Test for issue #952
|
||||
setup :fixtures => :all
|
||||
login :as => 'admin'
|
||||
open "/todos/tag/foo"
|
||||
click "css=#line_todo_2 .item-checkbox"
|
||||
wait_for_element_not_present "css=#c2 #line_todo_2"
|
||||
wait_for_not_visible "c2"
|
||||
8
test/selenium/tags/create_todo_in_hidden_context.rsel
Normal file
8
test/selenium/tags/create_todo_in_hidden_context.rsel
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
setup :fixtures => :all
|
||||
login :as => 'admin'
|
||||
open "/todos/tag/foo"
|
||||
type "todo_description", "run around"
|
||||
type "todo_context_name", "freetime"
|
||||
click "todo_new_action_submit"
|
||||
wait_for_visible "flash"
|
||||
assert_text "css=#c7items div.description span", "run around"
|
||||
|
|
@ -44,6 +44,13 @@ module SeleniumOnRails::TestBuilderAccessors
|
|||
command command_name, expected_count
|
||||
end
|
||||
end
|
||||
|
||||
def drag_todo_to(id1, id2)
|
||||
mouse_down_at "css=#line_todo_#{id1} img.grip", "4,4"
|
||||
mouse_move_at "line_todo_#{id2}", '20,3'
|
||||
mouse_over "line_todo_#{id2}"
|
||||
mouse_up_at "line_todo_#{id2}", '20,3'
|
||||
end
|
||||
|
||||
def assert_context_count_incremented(&block)
|
||||
store_context_count 'initial_context_count'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
ENV["RAILS_ENV"] = "test"
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../app/controllers/application")
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../app/controllers/application_controller")
|
||||
require 'test_help'
|
||||
require 'flexmock/test_unit' #and the flexmock gem, too!
|
||||
require 'action_web_service/test_invoke'
|
||||
|
|
|
|||
|
|
@ -55,54 +55,54 @@ class UserTest < ActiveSupport::TestCase
|
|||
# Test a password shorter than 5 characters
|
||||
#
|
||||
def test_validate_short_password
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :password => generate_random_string(4)
|
||||
assert_error_on u, :password, "is too short (minimum is 5 characters)"
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_long_password
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :password => generate_random_string(41)
|
||||
assert_error_on u, :password, "is too long (maximum is 40 characters)"
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_correct_length_password
|
||||
assert_difference User, :count do
|
||||
assert_difference 'User.count' do
|
||||
create_user :password => generate_random_string(6)
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_missing_password
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :password => ''
|
||||
assert_errors_on u, :password, ["can't be blank", "is too short (minimum is 5 characters)"]
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_short_login
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :login => 'ba'
|
||||
assert_error_on u, :login, "is too short (minimum is 3 characters)"
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_long_login
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :login => generate_random_string(81)
|
||||
assert_error_on u, :login, "is too long (maximum is 80 characters)"
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_correct_length_login
|
||||
assert_difference User, :count do
|
||||
assert_difference 'User.count' do
|
||||
create_user :login => generate_random_string(6)
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_missing_login
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user :login => ''
|
||||
assert_errors_on u, :login, ["can't be blank", "is too short (minimum is 3 characters)"]
|
||||
end
|
||||
|
|
@ -272,28 +272,28 @@ class UserTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
def test_should_create_user
|
||||
assert_difference User, :count do
|
||||
assert_difference 'User.count' do
|
||||
user = create_user
|
||||
assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_require_login
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user(:login => nil)
|
||||
assert u.errors.on(:login)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_require_password
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user(:password => nil)
|
||||
assert u.errors.on(:password)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_require_password_confirmation
|
||||
assert_no_difference User, :count do
|
||||
assert_no_difference 'User.count' do
|
||||
u = create_user(:password_confirmation => nil)
|
||||
assert u.errors.on(:password_confirmation)
|
||||
end
|
||||
|
|
|
|||
172
vendor/gems/datanoise-actionwebservice-2.3.2/.specification
vendored
Normal file
172
vendor/gems/datanoise-actionwebservice-2.3.2/.specification
vendored
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
--- !ruby/object:Gem::Specification
|
||||
name: datanoise-actionwebservice
|
||||
version: !ruby/object:Gem::Version
|
||||
version: 2.3.2
|
||||
platform: ruby
|
||||
authors:
|
||||
- Leon Breedt, Kent Sibilev
|
||||
autorequire:
|
||||
bindir: bin
|
||||
cert_chain: []
|
||||
|
||||
date: 2009-03-29 00:00:00 -04:00
|
||||
default_executable:
|
||||
dependencies:
|
||||
- !ruby/object:Gem::Dependency
|
||||
name: actionpack
|
||||
type: :runtime
|
||||
version_requirement:
|
||||
version_requirements: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - "="
|
||||
- !ruby/object:Gem::Version
|
||||
version: 2.3.2
|
||||
version:
|
||||
- !ruby/object:Gem::Dependency
|
||||
name: activerecord
|
||||
type: :runtime
|
||||
version_requirement:
|
||||
version_requirements: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - "="
|
||||
- !ruby/object:Gem::Version
|
||||
version: 2.3.2
|
||||
version:
|
||||
description: Adds WSDL/SOAP and XML-RPC web service support to Action Pack
|
||||
email: bitserf@gmail.com, ksibilev@yahoo.com
|
||||
executables: []
|
||||
|
||||
extensions: []
|
||||
|
||||
extra_rdoc_files: []
|
||||
|
||||
files:
|
||||
- Rakefile
|
||||
- setup.rb
|
||||
- README
|
||||
- TODO
|
||||
- CHANGELOG
|
||||
- MIT-LICENSE
|
||||
- examples/googlesearch
|
||||
- examples/googlesearch/autoloading
|
||||
- examples/googlesearch/autoloading/google_search_api.rb
|
||||
- examples/googlesearch/autoloading/google_search_controller.rb
|
||||
- examples/googlesearch/delegated
|
||||
- examples/googlesearch/delegated/google_search_service.rb
|
||||
- examples/googlesearch/delegated/search_controller.rb
|
||||
- examples/googlesearch/direct
|
||||
- examples/googlesearch/direct/google_search_api.rb
|
||||
- examples/googlesearch/direct/search_controller.rb
|
||||
- examples/googlesearch/README
|
||||
- examples/metaWeblog
|
||||
- examples/metaWeblog/apis
|
||||
- examples/metaWeblog/apis/blogger_api.rb
|
||||
- examples/metaWeblog/apis/blogger_service.rb
|
||||
- examples/metaWeblog/apis/meta_weblog_api.rb
|
||||
- examples/metaWeblog/apis/meta_weblog_service.rb
|
||||
- examples/metaWeblog/controllers
|
||||
- examples/metaWeblog/controllers/xmlrpc_controller.rb
|
||||
- examples/metaWeblog/README
|
||||
- lib/action_web_service
|
||||
- lib/action_web_service/api.rb
|
||||
- lib/action_web_service/base.rb
|
||||
- lib/action_web_service/casting.rb
|
||||
- lib/action_web_service/client
|
||||
- lib/action_web_service/client/base.rb
|
||||
- lib/action_web_service/client/soap_client.rb
|
||||
- lib/action_web_service/client/xmlrpc_client.rb
|
||||
- lib/action_web_service/client.rb
|
||||
- lib/action_web_service/container
|
||||
- lib/action_web_service/container/action_controller_container.rb
|
||||
- lib/action_web_service/container/delegated_container.rb
|
||||
- lib/action_web_service/container/direct_container.rb
|
||||
- lib/action_web_service/container.rb
|
||||
- lib/action_web_service/dispatcher
|
||||
- lib/action_web_service/dispatcher/abstract.rb
|
||||
- lib/action_web_service/dispatcher/action_controller_dispatcher.rb
|
||||
- lib/action_web_service/dispatcher.rb
|
||||
- lib/action_web_service/invocation.rb
|
||||
- lib/action_web_service/protocol
|
||||
- lib/action_web_service/protocol/abstract.rb
|
||||
- lib/action_web_service/protocol/discovery.rb
|
||||
- lib/action_web_service/protocol/soap_protocol
|
||||
- lib/action_web_service/protocol/soap_protocol/marshaler.rb
|
||||
- lib/action_web_service/protocol/soap_protocol.rb
|
||||
- lib/action_web_service/protocol/xmlrpc_protocol.rb
|
||||
- lib/action_web_service/protocol.rb
|
||||
- lib/action_web_service/scaffolding.rb
|
||||
- lib/action_web_service/struct.rb
|
||||
- lib/action_web_service/support
|
||||
- lib/action_web_service/support/class_inheritable_options.rb
|
||||
- lib/action_web_service/support/signature_types.rb
|
||||
- lib/action_web_service/templates
|
||||
- lib/action_web_service/templates/scaffolds
|
||||
- lib/action_web_service/templates/scaffolds/layout.html.erb
|
||||
- lib/action_web_service/templates/scaffolds/methods.html.erb
|
||||
- lib/action_web_service/templates/scaffolds/parameters.html.erb
|
||||
- lib/action_web_service/templates/scaffolds/result.html.erb
|
||||
- lib/action_web_service/test_invoke.rb
|
||||
- lib/action_web_service/version.rb
|
||||
- lib/action_web_service.rb
|
||||
- lib/actionwebservice.rb
|
||||
- test/abstract_client.rb
|
||||
- test/abstract_dispatcher.rb
|
||||
- test/abstract_unit.rb
|
||||
- test/api_test.rb
|
||||
- test/apis
|
||||
- test/apis/auto_load_api.rb
|
||||
- test/apis/broken_auto_load_api.rb
|
||||
- test/base_test.rb
|
||||
- test/casting_test.rb
|
||||
- test/client_soap_test.rb
|
||||
- test/client_xmlrpc_test.rb
|
||||
- test/container_test.rb
|
||||
- test/dispatcher_action_controller_soap_test.rb
|
||||
- test/dispatcher_action_controller_xmlrpc_test.rb
|
||||
- test/fixtures
|
||||
- test/fixtures/db_definitions
|
||||
- test/fixtures/db_definitions/mysql.sql
|
||||
- test/fixtures/users.yml
|
||||
- test/gencov
|
||||
- test/invocation_test.rb
|
||||
- test/run
|
||||
- test/scaffolded_controller_test.rb
|
||||
- test/struct_test.rb
|
||||
- test/test_invoke_test.rb
|
||||
- generators/web_service
|
||||
- generators/web_service/templates
|
||||
- generators/web_service/templates/api_definition.rb
|
||||
- generators/web_service/templates/controller.rb
|
||||
- generators/web_service/templates/functional_test.rb
|
||||
- generators/web_service/USAGE
|
||||
- generators/web_service/web_service_generator.rb
|
||||
has_rdoc: true
|
||||
homepage: http://www.rubyonrails.org
|
||||
licenses: []
|
||||
|
||||
post_install_message:
|
||||
rdoc_options: []
|
||||
|
||||
require_paths:
|
||||
- lib
|
||||
required_ruby_version: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - ">="
|
||||
- !ruby/object:Gem::Version
|
||||
version: "0"
|
||||
version:
|
||||
required_rubygems_version: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - ">="
|
||||
- !ruby/object:Gem::Version
|
||||
version: "0"
|
||||
version:
|
||||
requirements:
|
||||
- none
|
||||
rubyforge_project: aws
|
||||
rubygems_version: 1.3.5
|
||||
signing_key:
|
||||
specification_version: 2
|
||||
summary: Web service support for Action Pack.
|
||||
test_files: []
|
||||
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
*SVN*
|
||||
*2.1.0*
|
||||
|
||||
* Porting to Rails 2.1.0 [Kent Sibilev]
|
||||
|
||||
* Documentation for ActionWebService::API::Base. Closes #7275. [zackchandler]
|
||||
|
||||
|
|
@ -12,27 +14,80 @@
|
|||
|
||||
* Removed deprecated @request and @response usages. [Kent Sibilev]
|
||||
|
||||
* Removed deprecated end_form_tag helper. [Kent Sibilev]
|
||||
|
||||
* Removed deprecated @request and @response usages. [Kent Sibilev]
|
||||
|
||||
*1.2.6* (November 24th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.6
|
||||
|
||||
* Depend on Active Record 1.15.6
|
||||
|
||||
|
||||
*1.2.5* (October 12th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.5
|
||||
|
||||
* Depend on Active Record 1.15.5
|
||||
|
||||
|
||||
*1.2.4* (October 4th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.4
|
||||
|
||||
* Depend on Active Record 1.15.4
|
||||
|
||||
|
||||
*1.2.3* (March 12th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.3
|
||||
|
||||
|
||||
*1.2.2* (Feburary 4th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.2
|
||||
|
||||
|
||||
*1.2.1* (January 16th, 2007)
|
||||
|
||||
* Depend on Action Pack 1.13.1
|
||||
|
||||
|
||||
*1.2.0* (January 16th, 2007)
|
||||
|
||||
* Removed invocation of deprecated before_action and around_action filter methods. Corresponding before_invocation and after_invocation methods should be used instead. #6275 [Kent Sibilev]
|
||||
|
||||
* Provide access to the underlying SOAP driver. #6212 [bmilekic, Kent Sibilev]
|
||||
|
||||
* Deprecation: update docs. #5998 [jakob@mentalized.net, Kevin Clark]
|
||||
|
||||
* ActionWebService WSDL generation ignores HTTP_X_FORWARDED_HOST [Paul Butcher <paul@paulbutcher.com>]
|
||||
|
||||
* Tighten rescue clauses. #5985 [james@grayproductions.net]
|
||||
|
||||
* Fixed XMLRPC multicall when one of the called methods returns a struct object. [Kent Sibilev]
|
||||
|
||||
* Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
|
||||
|
||||
* Fix invoke_layered since api_method didn't declare :expects. Closes #4720. [Kevin Ballard <kevin@sb.org>, Kent Sibilev]
|
||||
|
||||
* Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.]
|
||||
|
||||
* Replace Ruby's deprecated append_features in favor of included. [Marcel Molina Jr.]
|
||||
*1.1.6* (August 10th, 2006)
|
||||
|
||||
* Rely on Action Pack 1.12.5
|
||||
|
||||
|
||||
*1.1.5* (August 8th, 2006)
|
||||
|
||||
* Rely on Action Pack 1.12.4 and Active Record 1.14.4
|
||||
|
||||
|
||||
*1.1.4* (June 29th, 2006)
|
||||
|
||||
* Rely on Action Pack 1.12.3
|
||||
|
||||
|
||||
*1.1.3* (June 27th, 2006)
|
||||
|
||||
* Rely on Action Pack 1.12.2 and Active Record 1.14.3
|
||||
|
||||
* Fix test database name typo. [Marcel Molina Jr.]
|
||||
|
||||
*1.1.2* (April 9th, 2006)
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions
|
|||
|
||||
desc 'Build the MySQL test database'
|
||||
task :build_database do
|
||||
%x( mysqladmin create actionwebservice_unittest )
|
||||
%x( mysql actionwebservice_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
|
||||
%x( mysqladmin -uroot create actionwebservice_unittest )
|
||||
%x( mysql -uroot actionwebservice_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -67,23 +67,24 @@ spec = Gem::Specification.new do |s|
|
|||
s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack}
|
||||
s.version = PKG_VERSION
|
||||
|
||||
s.author = "Leon Breedt"
|
||||
s.email = "bitserf@gmail.com"
|
||||
s.author = "Leon Breedt, Kent Sibilev"
|
||||
s.email = "bitserf@gmail.com, ksibilev@yahoo.com"
|
||||
s.rubyforge_project = "aws"
|
||||
s.homepage = "http://www.rubyonrails.org"
|
||||
|
||||
s.add_dependency('actionpack', '= 1.13.5' + PKG_BUILD)
|
||||
s.add_dependency('activerecord', '= 1.15.5' + PKG_BUILD)
|
||||
s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)
|
||||
s.add_dependency('activerecord', '= 2.3.2' + PKG_BUILD)
|
||||
|
||||
s.has_rdoc = true
|
||||
s.requirements << 'none'
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'action_web_service'
|
||||
s.autorequire = 'actionwebservice'
|
||||
|
||||
s.files = [ "Rakefile", "setup.rb", "README", "TODO", "CHANGELOG", "MIT-LICENSE" ]
|
||||
s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
|
||||
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
|
||||
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
|
||||
s.files = s.files + Dir.glob( "generators/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
|
||||
end
|
||||
Rake::GemPackageTask.new(spec) do |p|
|
||||
p.gem_spec = spec
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue