21 |
22 |
23 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Dailystamp::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the webserver when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.consider_all_requests_local = true
14 | config.action_view.debug_rjs = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Don't care if the mailer can't send
18 | config.action_mailer.raise_delivery_errors = false
19 |
20 | # Print deprecation notices to the Rails logger
21 | config.active_support.deprecation = :log
22 |
23 | # Only use best-standards-support built into browsers
24 | config.action_dispatch.best_standards_support = :builtin
25 | end
26 |
27 |
--------------------------------------------------------------------------------
/vendor/plugins/table_builder/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008 Petrik de Heus
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV["RAILS_ENV"] ||= 'test'
3 | require File.expand_path("../../config/environment", __FILE__)
4 | require 'rspec/rails'
5 | require 'authlogic/test_case'
6 |
7 | # Requires supporting ruby files with custom matchers and macros, etc,
8 | # in spec/support/ and its subdirectories.
9 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
10 |
11 | RSpec.configure do |config|
12 | # == Mock Framework
13 | #
14 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
15 | #
16 | # config.mock_with :mocha
17 | # config.mock_with :flexmock
18 | # config.mock_with :rr
19 | config.mock_with :mocha
20 |
21 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
22 | config.fixture_path = "#{::Rails.root}/spec/fixtures"
23 |
24 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
25 | # examples within a transaction, remove the following line or assign false
26 | # instead of true.
27 | config.use_transactional_fixtures = true
28 |
29 | config.include Authlogic::TestCase
30 | end
31 |
--------------------------------------------------------------------------------
/db/migrate/20090823035809_create_delayed_jobs.rb:
--------------------------------------------------------------------------------
1 | class CreateDelayedJobs < ActiveRecord::Migration
2 | def self.up
3 | create_table :delayed_jobs, :force => true do |table|
4 | table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
5 | table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
6 | table.text :handler # YAML-encoded string of the object that will do work
7 | table.text :last_error # reason for last failure (See Note below)
8 | table.datetime :run_at # When to run. Could be Time.now for immediately, or sometime in the future.
9 | table.datetime :locked_at # Set when a client is working on this object
10 | table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11 | table.string :locked_by # Who is working on this object (if locked)
12 | table.timestamps
13 | end
14 |
15 | end
16 |
17 | def self.down
18 | drop_table :delayed_jobs
19 | end
20 | end
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Daily Stamp
2 |
3 | This is an entry for Rails Rumble 2009 by Ryan Bates.
4 |
5 | --
6 |
7 | Copyright (c) 2009 Ryan Bates
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining
10 | a copy of this software and associated documentation files (the
11 | "Software"), to deal in the Software without restriction, including
12 | without limitation the rights to use, copy, modify, merge, publish,
13 | distribute, sublicense, and/or sell copies of the Software, and to
14 | permit persons to whom the Software is furnished to do so, subject to
15 | the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be
18 | included in all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
--------------------------------------------------------------------------------
/app/models/score_tracker.rb:
--------------------------------------------------------------------------------
1 | class ScoreTracker
2 | attr_reader :score, :position, :positive_points, :negative_points
3 |
4 | def initialize(options = {})
5 | @score = options[:score] || 0
6 | @positive_points = options[:positive_points] || 0
7 | @negative_points = options[:negative_points] || 0
8 | @position = options[:position] || 0
9 | end
10 |
11 | def mark
12 | if @negative_points > 0
13 | @negative_points = 0
14 | @position = 0
15 | end
16 | if @position >= @positive_points
17 | @positive_points += 1
18 | @position = 0
19 | end
20 | @position += 1
21 | @score += @positive_points
22 | @positive_points
23 | end
24 |
25 | def skip
26 | # keep scores as they are
27 | 0
28 | end
29 |
30 | def miss
31 | @position = 0 if @negative_points.zero?
32 | if @position == @negative_points
33 | @positive_points -= 1 unless @positive_points.zero?
34 | @negative_points += 1
35 | @position = 0
36 | end
37 | @position += 1
38 | if @score < @negative_points
39 | @position = 0
40 | @negative_points = @score
41 | end
42 | @score -= @negative_points
43 | -@negative_points
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe User do
4 | it "should not have validations for guest user" do
5 | User.new(:guest => true).should be_valid
6 | end
7 |
8 | it "should not have username/email validations for openid user" do
9 | User.new(:openid_identifier => "http://myopenid.com").should be_valid
10 | end
11 |
12 | it "should validate email format for openid identifier" do
13 | User.new(:openid_identifier => "http://myopenid.com", :email => "bad email").should have(1).error_on(:email)
14 | end
15 |
16 | it "should validate username format for openid identifier" do
17 | User.new(:openid_identifier => "http://myopenid.com", :username => "x").should have(1).error_on(:username)
18 | end
19 |
20 | it "should require username when password is given" do
21 | User.new(:password => "secret", :password_confirmation => "secret").should have(1).error_on(:username)
22 | end
23 |
24 | it "should require username when password is given" do
25 | User.new(:password => "secret", :password_confirmation => "secret").should_not be_valid
26 | end
27 |
28 | it "should require username when password when nothing given" do
29 | user = User.new
30 | user.should_not be_valid
31 | user.errors[:username].to_s.should =~ /too short/
32 | user.errors[:password].to_s.should =~ /too short/
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/spec/models/mark_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe Mark do
4 | it "should clear score cache of stamp when creating" do
5 | stamp = Factory(:stamp)
6 | stamp.update_attribute(:score_cache, 123)
7 | stamp.marks.create!(:marked_on => Time.zone.today)
8 | stamp.reload.score_cache.should be_nil
9 | end
10 |
11 | it "should clear score cache of stamp when destroying" do
12 | stamp = Factory(:stamp)
13 | stamp.marks.create!(:marked_on => Time.zone.today)
14 | stamp.update_attribute(:score_cache, 123)
15 | stamp.marks.first.destroy
16 | stamp.reload.score_cache.should be_nil
17 | end
18 |
19 | it "image_path should use stamp image" do
20 | stamp = Stamp.new(:color => "blue")
21 | stamp_image = stamp.build_stamp_image(:photo_file_name => "foo.jpg")
22 | mark = stamp.marks.build
23 | mark.stamp = stamp
24 | mark.image_path.should == stamp_image.photo.url("blue").sub(/[^\.]+$/, "png")
25 | end
26 |
27 | it "should clear future month cache of stamp when creating" do
28 | stamp = Factory(:stamp)
29 | cache1 = stamp.month_caches.create!(:for_month => 2.months.ago)
30 | cache2 = stamp.month_caches.create!(:for_month => Time.now.beginning_of_month)
31 | stamp.marks.create!(:marked_on => Time.zone.today)
32 | MonthCache.exists?(cache1).should be_true
33 | MonthCache.exists?(cache2).should be_false
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/vendor/plugins/table_builder/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake'
2 | require 'rake/testtask'
3 | require 'rake/rdoctask'
4 |
5 | desc 'Default: run unit tests.'
6 | task :default => :test
7 |
8 | desc 'Test the table_builder plugin.'
9 | Rake::TestTask.new(:test) do |t|
10 | t.libs << 'lib'
11 | t.pattern = 'test/**/*_test.rb'
12 | t.verbose = true
13 | end
14 |
15 | desc 'Generate documentation for the table_builder plugin.'
16 | Rake::RDocTask.new(:rdoc) do |rdoc|
17 | rdoc.rdoc_dir = 'rdoc'
18 | rdoc.title = 'TableBuilder'
19 | rdoc.options << '--line-numbers' << '--inline-source'
20 | rdoc.rdoc_files.include('README')
21 | rdoc.rdoc_files.include('lib/**/*.rb')
22 | end
23 |
24 |
25 | begin
26 | require 'jeweler'
27 | Jeweler::Tasks.new do |gem|
28 | gem.name = "table_builder"
29 | gem.summary = %Q{Rails builder for creating tables and calendars inspired by ActionView's FormBuilder.}
30 | gem.description = %Q{Rails builder for creating tables and calendars inspired by ActionView's FormBuilder.}
31 | gem.email = ""
32 | gem.homepage = "http://github.com/maca/table_builder"
33 | gem.authors = ["Petrik de Heus"]
34 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
35 | end
36 | Jeweler::GemcutterTasks.new
37 | rescue LoadError
38 | puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
39 | end
40 |
--------------------------------------------------------------------------------
/spec/controllers/favorites_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe FavoritesController, "as guest" do
4 | fixtures :all
5 | render_views
6 |
7 | it "index action should redirect to login" do
8 | get :index
9 | response.should redirect_to(login_path)
10 | end
11 |
12 | it "create action should redirect to login" do
13 | post :create
14 | response.should redirect_to(login_path)
15 | end
16 |
17 | it "destroy action should redirect to login" do
18 | delete :destroy, :id => Favorite.first
19 | response.should redirect_to(login_path)
20 | end
21 | end
22 |
23 | describe FavoritesController, "as owner" do
24 | fixtures :all
25 | render_views
26 |
27 | before(:each) do
28 | activate_authlogic
29 | UserSession.create(Favorite.first.user)
30 | end
31 |
32 | it "index action should render index template" do
33 | get :index
34 | response.should render_template(:index)
35 | end
36 |
37 | it "create action should redirect to index" do
38 | post :create, :stamp_id => Stamp.first
39 | response.should redirect_to(favorites_url)
40 | end
41 |
42 | it "destroy action should destroy model and redirect to index action" do
43 | favorite = Favorite.first
44 | delete :destroy, :id => favorite
45 | response.should redirect_to(favorites_url)
46 | Favorite.exists?(favorite.id).should be_false
47 | end
48 | end
49 |
50 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Dailystamp::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Log error messages when you accidentally call methods on nil.
11 | config.whiny_nils = true
12 |
13 | # Show full error reports and disable caching
14 | config.consider_all_requests_local = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Raise exceptions instead of rendering exception templates
18 | config.action_dispatch.show_exceptions = false
19 |
20 | # Disable request forgery protection in test environment
21 | config.action_controller.allow_forgery_protection = false
22 |
23 | # Tell Action Mailer not to deliver emails to the real world.
24 | # The :test delivery method accumulates sent emails in the
25 | # ActionMailer::Base.deliveries array.
26 | config.action_mailer.delivery_method = :test
27 |
28 | # Use SQL instead of Active Record's schema dumper when creating the test database.
29 | # This is necessary if your schema can't be completely dumped by the schema dumper,
30 | # like if you have constraints or database-specific column types
31 | # config.active_record.schema_format = :sql
32 |
33 | # Print deprecation notices to the stderr
34 | config.active_support.deprecation = :stderr
35 | end
36 |
--------------------------------------------------------------------------------
/app/views/favorites/index.html.erb:
--------------------------------------------------------------------------------
1 | <% title "Watched Stamps" %>
2 | <% stylesheet "favorites" %>
3 |
4 | <% if @favorites.empty? %>
5 |
6 | You currently are not watching any stamps.
7 | Ask your friends to share their stamp URL with you.
8 |
9 | <% else %>
10 | <% for favorite in @favorites %>
11 | <% if favorite.stamp && !favorite.stamp.private? %>
12 |
13 |
14 |
score <%=h favorite.stamp.score %>
15 |
16 |
17 | <% (7.days.ago.to_date..Time.zone.today).each do |date| %>
18 |
Or <%= link_to "add your own stamp", new_stamp_image_path, :id => "new_stamp_image_link" %>
36 |
37 |
<%= f.submit "Submit" %> or <%= link_to "cancel", @stamp %>
38 | <% end %>
39 |
--------------------------------------------------------------------------------
/spec/controllers/users_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe UsersController, "as a guest" do
4 | fixtures :all
5 | render_views
6 |
7 | it "new action should render new template" do
8 | get :new
9 | response.should render_template(:new)
10 | end
11 |
12 | it "create action should render new template when model is invalid" do
13 | User.any_instance.stubs(:valid?).returns(false)
14 | post :create
15 | response.should render_template(:new)
16 | end
17 |
18 | it "create action should redirect when model is valid" do
19 | User.any_instance.stubs(:valid?).returns(true)
20 | post :create
21 | response.should redirect_to(root_url)
22 | end
23 |
24 | it "edit action should redirect to login" do
25 | get :edit, :id => "current"
26 | response.should redirect_to(login_url)
27 | end
28 |
29 | it "update action should redirect to login" do
30 | put :update, :id => "current"
31 | response.should redirect_to(login_url)
32 | end
33 | end
34 |
35 | describe UsersController, "as a user" do
36 | fixtures :all
37 | render_views
38 |
39 | before(:each) do
40 | activate_authlogic
41 | UserSession.create(User.first)
42 | end
43 |
44 | it "edit action should render edit template" do
45 | get :edit, :id => "current"
46 | response.should render_template(:edit)
47 | end
48 |
49 | it "update action should render edit template when model is invalid" do
50 | User.any_instance.stubs(:valid?).returns(false)
51 | put :update, :id => "current"
52 | response.should render_template(:edit)
53 | end
54 |
55 | it "create action should redirect when model is valid" do
56 | User.any_instance.stubs(:valid?).returns(false)
57 | put :update, :id => "current"
58 | response.should render_template(:edit)
59 | end
60 | end
--------------------------------------------------------------------------------
/vendor/plugins/table_builder/table_builder.gemspec:
--------------------------------------------------------------------------------
1 | # Generated by jeweler
2 | # DO NOT EDIT THIS FILE DIRECTLY
3 | # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4 | # -*- encoding: utf-8 -*-
5 |
6 | Gem::Specification.new do |s|
7 | s.name = %q{table_builder}
8 | s.version = "0.2.0"
9 |
10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11 | s.authors = ["Petrik de Heus"]
12 | s.date = %q{2010-07-03}
13 | s.description = %q{Rails builder for creating tables and calendars inspired by ActionView's FormBuilder.}
14 | s.email = %q{}
15 | s.extra_rdoc_files = [
16 | "README.rdoc"
17 | ]
18 | s.files = [
19 | ".autotest",
20 | ".gitignore",
21 | "MIT-LICENSE",
22 | "README.rdoc",
23 | "Rakefile",
24 | "VERSION",
25 | "init.rb",
26 | "lib/table_builder.rb",
27 | "lib/table_builder/calendar_helper.rb",
28 | "lib/table_builder/table_builder.rb",
29 | "lib/tasks/table_builder_tasks.rake",
30 | "table_builder.gemspec",
31 | "test/calendar_helper_test.rb",
32 | "test/table_builder_test.rb",
33 | "test/test_helper.rb"
34 | ]
35 | s.homepage = %q{http://github.com/maca/table_builder}
36 | s.rdoc_options = ["--charset=UTF-8"]
37 | s.require_paths = ["lib"]
38 | s.rubygems_version = %q{1.3.7}
39 | s.summary = %q{Rails builder for creating tables and calendars inspired by ActionView's FormBuilder.}
40 | s.test_files = [
41 | "test/calendar_helper_test.rb",
42 | "test/table_builder_test.rb",
43 | "test/test_helper.rb"
44 | ]
45 |
46 | if s.respond_to? :specification_version then
47 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48 | s.specification_version = 3
49 |
50 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51 | else
52 | end
53 | else
54 | end
55 | end
56 |
57 |
--------------------------------------------------------------------------------
/app/controllers/stamps_controller.rb:
--------------------------------------------------------------------------------
1 | class StampsController < ApplicationController
2 | before_filter :login_required, :only => [:new, :edit, :edit_goal, :update, :destroy]
3 |
4 | def index
5 | if !params[:no_redirect] && current_user && current_user.current_stamp
6 | redirect_to current_user.current_stamp
7 | else
8 | @stamp = Stamp.new
9 | end
10 | end
11 |
12 | def show
13 | @stamp = Stamp.find(params[:id])
14 | @date = params[:month] ? Date.new(*params[:month].split("-").map(&:to_i)) : Time.zone.today
15 | raise "Date is too far in the future" if @date.to_time > 5.years.from_now
16 | if current_user && @stamp.user_id == current_user.id
17 | current_user.current_stamp_id = @stamp.id
18 | current_user.save!
19 | elsif @stamp.private?
20 | flash[:error] = "You are not authorized to access that stamp."
21 | redirect_to login_url
22 | end
23 | end
24 |
25 | def new
26 | @stamp = Stamp.new
27 | @stamp.color = current_user.unused_color
28 | render :action => "index"
29 | end
30 |
31 | def create
32 | @stamp = Stamp.new(params[:stamp])
33 | @stamp.stamp_image ||= StampImage.first
34 | @stamp.user = current_user_or_guest
35 | if @stamp.save
36 | redirect_to @stamp
37 | else
38 | render :action => "index"
39 | end
40 | end
41 |
42 | def edit
43 | @stamp = current_user.stamps.find(params[:id])
44 | end
45 |
46 | def edit_goal
47 | @stamp = current_user.stamps.find(params[:id])
48 | end
49 |
50 | def update
51 | @stamp = current_user.stamps.find(params[:id])
52 | if @stamp.update_attributes(params[:stamp])
53 | redirect_to @stamp
54 | else
55 | render :action => 'edit'
56 | end
57 | end
58 |
59 | def destroy
60 | @stamp = current_user.stamps.find(params[:id])
61 | @stamp.destroy
62 | redirect_to(current_user.stamps.first || root_url)
63 | end
64 | end
65 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Dailystamp::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # The production environment is meant for finished, "live" apps.
5 | # Code is not reloaded between requests
6 | config.cache_classes = true
7 |
8 | # Full error reports are disabled and caching is turned on
9 | config.consider_all_requests_local = false
10 | config.action_controller.perform_caching = true
11 |
12 | # Specifies the header that your server uses for sending files
13 | config.action_dispatch.x_sendfile_header = "X-Sendfile"
14 |
15 | # For nginx:
16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
17 |
18 | # If you have no front-end server that supports something like X-Sendfile,
19 | # just comment this out and Rails will serve the files
20 |
21 | # See everything in the log (default is :info)
22 | # config.log_level = :debug
23 |
24 | # Use a different logger for distributed setups
25 | # config.logger = SyslogLogger.new
26 |
27 | # Use a different cache store in production
28 | # config.cache_store = :mem_cache_store
29 |
30 | # Disable Rails's static asset server
31 | # In production, Apache or nginx will already do this
32 | config.serve_static_assets = false
33 |
34 | # Enable serving of images, stylesheets, and javascripts from an asset server
35 | # config.action_controller.asset_host = "http://assets.example.com"
36 |
37 | # Disable delivery errors, bad email addresses will be ignored
38 | # config.action_mailer.raise_delivery_errors = false
39 |
40 | # Enable threaded mode
41 | # config.threadsafe!
42 |
43 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44 | # the I18n.default_locale when a translation can not be found)
45 | config.i18n.fallbacks = true
46 |
47 | # Send deprecation notices to registered listeners
48 | config.active_support.deprecation = :notify
49 | end
50 |
--------------------------------------------------------------------------------
/spec/controllers/marks_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe MarksController, "as guest" do
4 | fixtures :all
5 | render_views
6 |
7 | it "create action should redirect to login" do
8 | post :create
9 | response.should redirect_to(login_path)
10 | end
11 |
12 | it "destroy action should redirect to login" do
13 | delete :destroy, :id => Mark.first
14 | response.should redirect_to(login_path)
15 | end
16 | end
17 |
18 | describe MarksController, "as stamp owner" do
19 | fixtures :all
20 | render_views
21 |
22 | before(:each) do
23 | activate_authlogic
24 | UserSession.create(Stamp.first.user)
25 | end
26 |
27 | it "create action should create mark with given stamp id and date" do
28 | post :create, :stamp_id => Stamp.first.id, :date => "2009-02-01", :x => 123, :y => 456
29 | response.should redirect_to(root_url)
30 | mark = Mark.last
31 | mark.marked_on.should == Date.parse("2009-02-01")
32 | mark.stamp_id.should == Stamp.first.id
33 | mark.position_x.should == 123
34 | mark.position_y.should == 456
35 | end
36 |
37 | it "create action should create mark with skip" do
38 | post :create, :stamp_id => Stamp.first.id, :date => "2009-02-01", :skip => "true"
39 | response.should redirect_to(root_url)
40 | mark = Mark.last
41 | mark.skip.should be_true
42 | end
43 |
44 | it "create action should render template when js action" do
45 | post :create, :format => "js", :stamp_id => Stamp.first.id, :date => "2009-02-01"
46 | response.should render_template("create")
47 | end
48 |
49 | it "destroy action should destroy model and redirect to index action" do
50 | mark = Mark.first
51 | delete :destroy, :id => mark
52 | response.should redirect_to(root_url)
53 | Mark.exists?(mark.id).should be_false
54 | end
55 |
56 | it "destroy action should render template when js action" do
57 | mark = Mark.first
58 | delete :destroy, :id => mark, :format => "js"
59 | response.should render_template("destroy")
60 | end
61 | end
62 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # If you have a Gemfile, require the gems listed there, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(:default, Rails.env) if defined?(Bundler)
8 |
9 | module Dailystamp
10 | class Application < Rails::Application
11 | # Settings in config/environments/* take precedence over those specified here.
12 | # Application configuration should go into files in config/initializers
13 | # -- all .rb files in that directory are automatically loaded.
14 |
15 | # Custom directories with classes and modules you want to be autoloadable.
16 | config.autoload_paths += %W(#{config.root}/lib)
17 |
18 | # Only load the plugins named here, in the order given (default is alphabetical).
19 | # :all can be used as a placeholder for all plugins not explicitly named.
20 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
21 |
22 | # Activate observers that should always be running.
23 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
24 |
25 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
26 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
27 | # config.time_zone = 'Central Time (US & Canada)'
28 | config.time_zone = "Pacific Time (US & Canada)"
29 |
30 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
31 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
32 | # config.i18n.default_locale = :de
33 |
34 | # JavaScript files you want as :defaults (application.js is always included).
35 | # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
36 |
37 | # Configure the default encoding used in templates for Ruby 1.9.
38 | config.encoding = "utf-8"
39 |
40 | # Configure sensitive parameters which will be filtered from the log file.
41 | config.filter_parameters += [:password]
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/config/deploy.rb:
--------------------------------------------------------------------------------
1 | require "bundler/capistrano"
2 |
3 | set :application, "beta.dailystamp.com"
4 | role :app, application
5 | role :web, application
6 | role :db, application, :primary => true
7 |
8 | set :user, "rbates"
9 | set :deploy_to, "/var/apps/dailystamp"
10 | set :deploy_via, :remote_cache
11 | set :use_sudo, false
12 |
13 | set :scm, "git"
14 | set :repository, "git://github.com/ryanb/dailystamp.git"
15 | set :branch, "master"
16 |
17 | namespace :deploy do
18 | desc "Tell Passenger to restart."
19 | task :restart, :roles => :web do
20 | run "touch #{deploy_to}/current/tmp/restart.txt"
21 | end
22 |
23 | desc "Do nothing on startup so we don't get a script/spin error."
24 | task :start do
25 | puts "You may need to restart Apache."
26 | end
27 |
28 | desc "Symlink extra configs and folders."
29 | task :symlink_extras do
30 | run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
31 | run "ln -nfs #{shared_path}/config/session_secret.txt #{release_path}/config/session_secret.txt"
32 | run "ln -nfs #{shared_path}/assets #{release_path}/public/assets"
33 | end
34 |
35 | desc "Setup shared directory."
36 | task :setup_shared do
37 | run "mkdir #{shared_path}/assets"
38 | run "mkdir #{shared_path}/config"
39 | run "mkdir #{shared_path}/db"
40 | put File.read("config/database.example.yml"), "#{shared_path}/config/database.yml"
41 | put File.read("config/session_secret.example.txt"), "#{shared_path}/config/session_secret.txt"
42 | puts "Now edit the config files and fill assets folder in #{shared_path}."
43 | end
44 |
45 | desc "Make sure there is something to deploy"
46 | task :check_revision, :roles => :web do
47 | unless `git rev-parse HEAD` == `git rev-parse origin/master`
48 | puts "WARNING: HEAD is not the same as origin/master"
49 | puts "Run `git push` to sync changes."
50 | exit
51 | end
52 | end
53 | end
54 |
55 | before "deploy", "deploy:check_revision"
56 | after "deploy", "deploy:cleanup" # keeps only last 5 releases
57 | after "deploy:setup", "deploy:setup_shared"
58 | after "deploy:update_code", "deploy:symlink_extras"
59 |
--------------------------------------------------------------------------------
/vendor/plugins/open_id_authentication/CHANGELOG:
--------------------------------------------------------------------------------
1 | * Dump heavy lifting off to rack-openid gem. OpenIdAuthentication is just a simple controller concern.
2 |
3 | * Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek]
4 |
5 | * OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek]
6 |
7 | * Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler]
8 |
9 | * Add Timeout protection [Rick]
10 |
11 | * An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block.
12 |
13 | * Allow a return_to option to be used instead of the requested url [Josh Peek]
14 |
15 | * Updated plugin to use Ruby OpenID 2.x.x [Josh Peek]
16 |
17 | * Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH]
18 |
19 | * Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb]
20 |
21 | * Allow -'s in #normalize_url [Rick]
22 |
23 | * remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport. Fix Timeout test [Rick]
24 |
25 | * Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH]
26 |
27 | * Just use the path for the return URL, so extra query parameters don't interfere [DHH]
28 |
29 | * Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH]
30 |
31 | * Added normalize_url and applied it to all operations going through the plugin [DHH]
32 |
33 | * Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH]
34 |
35 | * Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH]
36 |
37 | * Stop relying on root_url being defined, we can just grab the current url instead [DHH]
--------------------------------------------------------------------------------
/spec/controllers/stamp_images_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe StampImagesController, "as guest" do
4 | it "create action should redirect to login" do
5 | post :create
6 | response.should redirect_to(login_path)
7 | end
8 |
9 | it "destroy action should redirect to login" do
10 | delete :destroy, :id => StampImage.first, :format => "js"
11 | response.should redirect_to(login_path)
12 | end
13 |
14 | it "new action should redirect to login" do
15 | get :new
16 | response.should redirect_to(login_path)
17 | end
18 | end
19 |
20 | describe StampImagesController, "as user" do
21 | fixtures :all
22 | render_views
23 |
24 | before(:each) do
25 | activate_authlogic
26 | @current_user = User.first
27 | UserSession.create(@current_user)
28 | end
29 |
30 | it "create action should render new template when model is invalid" do
31 | StampImage.any_instance.stubs(:valid?).returns(false)
32 | post :create
33 | response.should render_template(:new)
34 | end
35 |
36 | it "create action should redirect to current stamp edit form" do
37 | @current_user.current_stamp = Stamp.first
38 | @current_user.save!
39 | StampImage.any_instance.stubs(:valid?).returns(true)
40 | StampImage.any_instance.expects(:generate_graphics)
41 | post :create
42 | response.should redirect_to(edit_stamp_path(Stamp.first))
43 | end
44 |
45 | it "destroy action should destroy model and redirect to index action" do
46 | stamp_image = StampImage.first
47 | delete :destroy, :id => stamp_image.id
48 | response.should redirect_to(root_url)
49 | StampImage.exists?(stamp_image.id).should be_false
50 | end
51 |
52 | it "destroy action should destroy model and render js template" do
53 | stamp_image = StampImage.first
54 | delete :destroy, :id => stamp_image.id, :format => "js"
55 | response.should render_template(:destroy)
56 | StampImage.exists?(stamp_image.id).should be_false
57 | end
58 |
59 | it "new action should render new template" do
60 | get :new
61 | response.should render_template(:new)
62 | end
63 |
64 | it "new action should render new template with js format" do
65 | get :new, :format => "js"
66 | response.should render_template(:new)
67 | end
68 | end
69 |
--------------------------------------------------------------------------------
/spec/models/score_tracker_spec.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../spec_helper'
2 |
3 | describe ScoreTracker do
4 | before(:each) do
5 | @tracker = ScoreTracker.new
6 | end
7 |
8 | it "should be zero by default" do
9 | @tracker.score.should be_zero
10 | end
11 |
12 | it "marks should build up" do
13 | (1..4).map { @tracker.mark }.should == [1, 2, 2, 3]
14 | end
15 |
16 | it "stay at zero when missing" do
17 | (1..4).map { @tracker.miss }.should == [0, 0, 0, 0]
18 | end
19 |
20 | it "misses should detract points" do
21 | 4.times { @tracker.mark }
22 | (1..5).map { @tracker.miss }.should == [-1, -2, -2, -3, 0]
23 | end
24 |
25 | it "should slowly deduct positive points when misses" do
26 | 4.times { @tracker.mark }
27 | 2.times { @tracker.miss }
28 | @tracker.mark.should == 1
29 | end
30 |
31 | it "should reset position when mark is after misses" do
32 | 4.times { @tracker.miss }
33 | @tracker.mark.should == 1
34 | end
35 |
36 | it "should alternate misses and marks properly" do
37 | [@tracker.mark, @tracker.miss, @tracker.mark, @tracker.miss].should == [1, -1, 1, -1]
38 | end
39 |
40 | it "should handle complex scenarios" do
41 | [@tracker.mark, @tracker.mark, @tracker.mark, @tracker.miss, @tracker.mark, @tracker.mark,
42 | @tracker.miss, @tracker.miss, @tracker.miss, @tracker.miss, @tracker.mark].should ==
43 | [1, 2, 2, -1, 1, 2, -1, -2, -2, -2, 1]
44 | end
45 |
46 | it "skip should continue on as if nothing happened" do
47 | [@tracker.mark, @tracker.skip, @tracker.skip, @tracker.mark].should == [1, 0, 0, 2]
48 | end
49 |
50 | it "should prefix options with those passed" do
51 | tracker = ScoreTracker.new(:score => 123)
52 | tracker.score.should == 123
53 | end
54 |
55 | it "should remove remaining points from score (don't go past zero)" do
56 | tracker = ScoreTracker.new(:score => 1, :negative_points => 3)
57 | tracker.miss.should == -1
58 | tracker.score.should == 0
59 | end
60 |
61 | it "should go down one positive point when missing a day" do
62 | tracker = ScoreTracker.new(:score => 1, :positive_points => 4, :position => 2)
63 | tracker.miss.should == -1
64 | tracker.mark.should == 3
65 | tracker.positive_points.should == 3
66 | tracker.position.should == 1
67 | end
68 | end
69 |
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | <%= content_for?(:title) ? yield(:title) : "Untitled" %>
6 | <%= stylesheet_link_tag "application" %>
7 | <%= javascript_include_tag :defaults %>
8 | <%= csrf_meta_tag %>
9 | <%= yield(:head) %>
10 |
11 |
12 |
13 |
14 |
15 | <%- if logged_in? -%>
16 | <%- if current_user.guest? -%>
17 |
18 | You are currently logged in as a guest.
19 | Please <%= link_to "setup your account", edit_user_path(:current) %> to save your <%= link_to_if(current_user.current_stamp && !current_page?(current_user.current_stamp), "stamps", current_user.current_stamp) %>.
20 |
)
80 | assert_dom_equal expected, output
81 | end
82 |
83 | def test_body
84 | output = table_for([@drummer3, @drummer4]) do |t|
85 | t.body do |e|
86 | t.r do
87 | concat t.d(e.id)
88 | concat t.d(e.name)
89 | end
90 | end
91 | end
92 | expected = %(
) <<
93 | %() <<
94 | %(
) <<
95 | %(
3
) <<
96 | %(
Peter "James" Bond
) <<
97 | %(
) <<
98 | %(
) <<
99 | %(
4
) <<
100 | %(
Mick Shrimpton (R. J. "Ric" Parnell)
) <<
101 | %(
) <<
102 | %() <<
103 | %(
)
104 | assert_dom_equal expected, output
105 | end
106 |
107 | def test_body_r
108 | output = table_for([@drummer3, @drummer4]) do |t|
109 | t.body_r do |e|
110 | concat t.d(e.id)
111 | concat t.d(e.name)
112 | end
113 | end
114 | expected = %(
) <<
115 | %() <<
116 | %(
) <<
117 | %(
3
) <<
118 | %(
Peter "James" Bond
) <<
119 | %(
) <<
120 | %(
) <<
121 | %(
4
) <<
122 | %(
Mick Shrimpton (R. J. "Ric" Parnell)
) <<
123 | %(
) <<
124 | %() <<
125 | %(
)
126 | assert_dom_equal expected, output
127 | end
128 |
129 | def test_td_with_options
130 | output = table_for([@drummer1]) do |t|
131 | t.body_r do |e|
132 | output_buffer.concat t.d(e.name, :class => 'class')
133 | end
134 | end
135 | expected = %(
) <<
136 | %() <<
137 | %(
) <<
138 | %(
John "Stumpy" Pepys
) <<
139 | %(
) <<
140 | %() <<
141 | %(
)
142 | assert_dom_equal expected, output
143 | end
144 |
145 | def test_td_with_block
146 | output = table_for([@drummer1]) do |t|
147 | t.body_r do |e|
148 | t.d do
149 | concat 'content'
150 | end
151 | end
152 | end
153 | expected = %(
) <<
154 | %() <<
155 | %(
) <<
156 | %(
content
) <<
157 | %(
) <<
158 | %() <<
159 | %(
)
160 | assert_dom_equal expected, output
161 | end
162 |
163 | def test_td_with_block_and_options
164 | output = table_for([@drummer1]) do |t|
165 | t.body_r do |e|
166 | t.d(:class => 'class') do
167 | concat 'content'
168 | end
169 | end
170 | end
171 | expected = %(
) <<
172 | %() <<
173 | %(
) <<
174 | %(
content
) <<
175 | %(
) <<
176 | %() <<
177 | %(
)
178 | assert_dom_equal expected, output
179 | end
180 |
181 | end
182 |
183 | class Drummer < Struct.new(:id, :name); end
184 |
--------------------------------------------------------------------------------
/public/javascripts/rails.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jquery-ujs
3 | *
4 | * http://github.com/rails/jquery-ujs/blob/master/src/rails.js
5 | *
6 | * This rails.js file supports jQuery 1.4.3 and 1.4.4 .
7 | *
8 | */
9 |
10 | jQuery(function ($) {
11 | var csrf_token = $('meta[name=csrf-token]').attr('content'),
12 | csrf_param = $('meta[name=csrf-param]').attr('content');
13 |
14 | $.fn.extend({
15 | /**
16 | * Triggers a custom event on an element and returns the event result
17 | * this is used to get around not being able to ensure callbacks are placed
18 | * at the end of the chain.
19 | *
20 | * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
21 | * own events and placing ourselves at the end of the chain.
22 | */
23 | triggerAndReturn: function (name, data) {
24 | var event = new $.Event(name);
25 | this.trigger(event, data);
26 |
27 | return event.result !== false;
28 | },
29 |
30 | /**
31 | * Handles execution of remote calls. Provides following callbacks:
32 | *
33 | * - ajax:before - is execute before the whole thing begings
34 | * - ajax:loading - is executed before firing ajax call
35 | * - ajax:success - is executed when status is success
36 | * - ajax:complete - is execute when status is complete
37 | * - ajax:failure - is execute in case of error
38 | * - ajax:after - is execute every single time at the end of ajax call
39 | */
40 | callRemote: function () {
41 | var el = this,
42 | method = el.attr('method') || el.attr('data-method') || 'GET',
43 | url = el.attr('action') || el.attr('href'),
44 | dataType = el.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
45 |
46 | if (url === undefined) {
47 | throw "No URL specified for remote call (action or href must be present).";
48 | } else {
49 | if (el.triggerAndReturn('ajax:before')) {
50 | var data = el.is('form') ? el.serializeArray() : [];
51 | $.ajax({
52 | url: url,
53 | data: data,
54 | dataType: dataType,
55 | type: method.toUpperCase(),
56 | beforeSend: function (xhr) {
57 | xhr.setRequestHeader("Accept", "text/javascript");
58 | el.trigger('ajax:loading', xhr);
59 | },
60 | success: function (data, status, xhr) {
61 | el.trigger('ajax:success', [data, status, xhr]);
62 | },
63 | complete: function (xhr) {
64 | el.trigger('ajax:complete', xhr);
65 | },
66 | error: function (xhr, status, error) {
67 | el.trigger('ajax:failure', [xhr, status, error]);
68 | }
69 | });
70 | }
71 |
72 | el.trigger('ajax:after');
73 | }
74 | }
75 | });
76 |
77 | /**
78 | * confirmation handler
79 | */
80 |
81 | $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
82 | var el = $(this);
83 | if (el.triggerAndReturn('confirm')) {
84 | if (!confirm(el.attr('data-confirm'))) {
85 | return false;
86 | }
87 | }
88 | });
89 |
90 |
91 |
92 | /**
93 | * remote handlers
94 | */
95 | $('form[data-remote]').live('submit.rails', function (e) {
96 | $(this).callRemote();
97 | e.preventDefault();
98 | });
99 |
100 | $('a[data-remote],input[data-remote]').live('click.rails', function (e) {
101 | $(this).callRemote();
102 | e.preventDefault();
103 | });
104 |
105 | /**
106 | * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %>
107 | *
108 | * Delete
109 | */
110 | $('a[data-method]:not([data-remote])').live('click.rails', function (e){
111 | var link = $(this),
112 | href = link.attr('href'),
113 | method = link.attr('data-method'),
114 | form = $(''),
115 | metadata_input = '';
116 |
117 | if (csrf_param !== undefined && csrf_token !== undefined) {
118 | metadata_input += '';
119 | }
120 |
121 | form.hide()
122 | .append(metadata_input)
123 | .appendTo('body');
124 |
125 | e.preventDefault();
126 | form.submit();
127 | });
128 |
129 | /**
130 | * disable-with handlers
131 | */
132 | var disable_with_input_selector = 'input[data-disable-with]',
133 | disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')',
134 | disable_with_form_not_remote_selector = 'form:not([data-remote]):has(' + disable_with_input_selector + ')';
135 |
136 | var disable_with_input_function = function () {
137 | $(this).find(disable_with_input_selector).each(function () {
138 | var input = $(this);
139 | input.data('enable-with', input.val())
140 | .attr('value', input.attr('data-disable-with'))
141 | .attr('disabled', 'disabled');
142 | });
143 | };
144 |
145 | $(disable_with_form_remote_selector).live('ajax:before.rails', disable_with_input_function);
146 | $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function);
147 |
148 | $(disable_with_form_remote_selector).live('ajax:complete.rails', function () {
149 | $(this).find(disable_with_input_selector).each(function () {
150 | var input = $(this);
151 | input.removeAttr('disabled')
152 | .val(input.data('enable-with'));
153 | });
154 | });
155 |
156 | var jqueryVersion = $().jquery;
157 |
158 | if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){
159 | alert('This rails.js does not support the jQuery version you are using. Please read documentation.');
160 | }
161 |
162 |
163 | });
164 |
--------------------------------------------------------------------------------
/vendor/plugins/open_id_authentication/README:
--------------------------------------------------------------------------------
1 | OpenIdAuthentication
2 | ====================
3 |
4 | Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
5 |
6 | gem install ruby-openid
7 |
8 | To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
9 | from that gem.
10 |
11 | The specification used is http://openid.net/specs/openid-authentication-2_0.html.
12 |
13 |
14 | Prerequisites
15 | =============
16 |
17 | OpenID authentication uses the session, so be sure that you haven't turned that off.
18 |
19 | Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
20 |
21 | OpenIdAuthentication.store = :file
22 |
23 | This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
24 | If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb.
25 |
26 | The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
27 |
28 | map.root :controller => 'articles'
29 |
30 | This plugin relies on Rails Edge revision 6317 or newer.
31 |
32 |
33 | Example
34 | =======
35 |
36 | This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
37 | salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
38 | not a destination.
39 |
40 | Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
41 | model you are using for authentication.
42 |
43 | Also of note is the following code block used in the example below:
44 |
45 | authenticate_with_open_id do |result, identity_url|
46 | ...
47 | end
48 |
49 | In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
50 | If you are storing just 'example.com' with your user, the lookup will fail.
51 |
52 | There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
53 |
54 | OpenIdAuthentication.normalize_url(user.identity_url)
55 |
56 | The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
57 | It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
58 | Use the above code in your User model and validate OpenID URLs before saving them.
59 |
60 | config/routes.rb
61 |
62 | map.root :controller => 'articles'
63 | map.resource :session
64 |
65 |
66 | app/views/sessions/new.erb
67 |
68 | <% form_tag(session_url) do %>
69 |
91 | <% end %>
92 |
93 | app/controllers/sessions_controller.rb
94 | class SessionsController < ApplicationController
95 | def create
96 | if using_open_id?
97 | open_id_authentication
98 | else
99 | password_authentication(params[:name], params[:password])
100 | end
101 | end
102 |
103 |
104 | protected
105 | def password_authentication(name, password)
106 | if @current_user = @account.users.authenticate(params[:name], params[:password])
107 | successful_login
108 | else
109 | failed_login "Sorry, that username/password doesn't work"
110 | end
111 | end
112 |
113 | def open_id_authentication
114 | authenticate_with_open_id do |result, identity_url|
115 | if result.successful?
116 | if @current_user = @account.users.find_by_identity_url(identity_url)
117 | successful_login
118 | else
119 | failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
120 | end
121 | else
122 | failed_login result.message
123 | end
124 | end
125 | end
126 |
127 |
128 | private
129 | def successful_login
130 | session[:user_id] = @current_user.id
131 | redirect_to(root_url)
132 | end
133 |
134 | def failed_login(message)
135 | flash[:error] = message
136 | redirect_to(new_session_url)
137 | end
138 | end
139 |
140 |
141 |
142 | If you're fine with the result messages above and don't need individual logic on a per-failure basis,
143 | you can collapse the case into a mere boolean:
144 |
145 | def open_id_authentication
146 | authenticate_with_open_id do |result, identity_url|
147 | if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
148 | successful_login
149 | else
150 | failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
151 | end
152 | end
153 | end
154 |
155 |
156 | Simple Registration OpenID Extension
157 | ====================================
158 |
159 | Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension
160 |
161 | You can support it in your app by changing #open_id_authentication
162 |
163 | def open_id_authentication(identity_url)
164 | # Pass optional :required and :optional keys to specify what sreg fields you want.
165 | # Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
166 | authenticate_with_open_id(identity_url,
167 | :required => [ :nickname, :email ],
168 | :optional => :fullname) do |result, identity_url, registration|
169 | case result.status
170 | when :missing
171 | failed_login "Sorry, the OpenID server couldn't be found"
172 | when :invalid
173 | failed_login "Sorry, but this does not appear to be a valid OpenID"
174 | when :canceled
175 | failed_login "OpenID verification was canceled"
176 | when :failed
177 | failed_login "Sorry, the OpenID verification failed"
178 | when :successful
179 | if @current_user = @account.users.find_by_identity_url(identity_url)
180 | assign_registration_attributes!(registration)
181 |
182 | if current_user.save
183 | successful_login
184 | else
185 | failed_login "Your OpenID profile registration failed: " +
186 | @current_user.errors.full_messages.to_sentence
187 | end
188 | else
189 | failed_login "Sorry, no user by that identity URL exists"
190 | end
191 | end
192 | end
193 | end
194 |
195 | # registration is a hash containing the valid sreg keys given above
196 | # use this to map them to fields of your user model
197 | def assign_registration_attributes!(registration)
198 | model_to_registration_mapping.each do |model_attribute, registration_attribute|
199 | unless registration[registration_attribute].blank?
200 | @current_user.send("#{model_attribute}=", registration[registration_attribute])
201 | end
202 | end
203 | end
204 |
205 | def model_to_registration_mapping
206 | { :login => 'nickname', :email => 'email', :display_name => 'fullname' }
207 | end
208 |
209 | Attribute Exchange OpenID Extension
210 | ===================================
211 |
212 | Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
213 |
214 | Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example:
215 |
216 | authenticate_with_open_id(identity_url,
217 | :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration|
218 |
219 | This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate'
220 |
221 |
222 |
223 | Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
--------------------------------------------------------------------------------
/vendor/plugins/table_builder/test/calendar_helper_test.rb:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(__FILE__), 'test_helper.rb')
2 |
3 | class CalendarHelperTest < ActionView::TestCase
4 | include ActionView::Helpers::TextHelper
5 | include ActionView::Helpers::TagHelper
6 | include CalendarHelper
7 | attr_accessor :output_buffer
8 |
9 | def setup
10 | @events = [Event.new(3, 'Jimmy Page', Date.civil(2008, 12, 26)),
11 | Event.new(4, 'Robert Plant', Date.civil(2008, 12, 26))]
12 | end
13 |
14 | def test_calendar_for
15 | output = calendar_for(@events, :html => { :id => 'id', :style => 'style', :class => 'class'}) do |t|
16 | end
17 | expected = %(
) <<
18 | %(
)
19 | assert_dom_equal expected, output
20 | end
21 |
22 | def test_calendar_for_without_an_array
23 | self.output_buffer = ''
24 | assert_raises(ArgumentError) do
25 | calendar_for('a') {|t| }
26 | end
27 | end
28 |
29 | def test_calendar_for_with_empty_array
30 | output = calendar_for([], :year=> 2008, :month => 12) do |c|
31 | c.day do |day, events|
32 | concat(events.collect{|e| e.id}.join)
33 | end
34 | end
35 | expected = %(