public
Description: BrainBuster - a logic captcha for Rails
Homepage: http://opensource.thinkrelevance.com/wiki/BrainBuster
Clone URL: git://github.com/rsanheim/brain_buster.git
brain_buster / examples / lib / brain_buster_functional_example.rb
100644 149 lines (111 sloc) 5.126 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
require File.join(File.dirname(__FILE__), *%w[.. example_helper])
require 'micronaut-rails'
 
ActionController::Routing::Routes.draw { |map| map.connect ':controller/:action/:id' }
 
# Fake controller so we can test BrainBuster functionally
class PagesController < ActionController::Base
  self.append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views"))
  # hack the plugin view path onto the controller
  self.append_view_path File.expand_path(File.join(File.dirname(__FILE__), "..", "views", "brain_busters"))
  
  before_filter :create_brain_buster, :only => [:new]
  before_filter :validate_brain_buster, :only => [:create]
 
  def new
    render :template => "/new"
  end
  
  def create
    render :text => "Success!"
  end
  
  def rescue_action(e)
    raise e
  end
  
end
 
describe PagesController do
 
  before(:all) { setup_database }
  after(:all) { teardown_database }
  
  before(:each) { controller.brain_buster_salt = [Array.new(32){rand(256).chr}.join].pack("m").chomp }
  
  describe "configuration" do
 
    it "should add the plugin view path to the view path" do
      plugin_view_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "views", "brain_busters"))
      controller.class.view_paths.should include(plugin_view_path)
    end
 
    it "should raise an exception if the salt doesnt get set to something" do
      controller.brain_buster_salt = nil
      lambda { get(:new) }.should raise_error(RuntimeError)
    end
 
    it "should add brain_buster_salt class instance variable method to ActionController::Base" do
      ActionController::Base.should respond_to(:brain_buster_salt)
      controller.should respond_to(:brain_buster_salt)
    end
 
    it "should alias captcha_passed? method" do
      controller.should respond_to(:captcha_passed?)
      controller.should respond_to(:captcha_previously_passed?)
      controller.captcha_passed?.should == controller.captcha_previously_passed?
    end
    
  end
 
  describe "retrieving brain buster (via new)" do
 
  
    it "should create captcha for first request" do
      brain_buster = stub("brain_buster")
      BrainBuster.expects(:find).returns(brain_buster)
      get :new
      assigns(:captcha).should == brain_buster
    end
 
    it "should retrieve same captcha for second request" do
      brain_buster = stub("brain_buster")
      BrainBuster.expects(:find_random_or_previous).with('1').returns(brain_buster)
      get :new, :captcha_id => '1'
      assigns(:captcha).should == brain_buster
    end
    
  end
  
  describe "validate filter" do
 
    it "should ignore filters if brain buster is not enabled" do
      begin
        controller.brain_buster_enabled = false
        BrainBuster.expects(:find_random_or_previous).never
        post :create
        response.body.should == "Success!"
      ensure
        controller.brain_buster_enabled = true
      end
    end
 
    it "should fail validation and halt action if captcha is missing" do
      post :create
      flash[:error].should == controller.brain_buster_failure_message
      response.body.should == controller.brain_buster_failure_message
    end
 
    it "should indicate previous captcha attempt failed" do
      stub_default_brain_buster
 
      post :create, :captcha_id => '1', :captcha_answer => "5"
      flash[:error].should == controller.brain_buster_failure_message
      cookies['captcha_status'].should == BrainBusterSystem.encrypt("failed", controller.brain_buster_salt)
    end
 
    it "should fail validation and render failure message text if captcha answer is wrong" do
      stub_default_brain_buster
      post :create, :captcha_id => '1', :captcha_answer => "5"
      flash[:error].should == controller.brain_buster_failure_message
      response.body.should == controller.brain_buster_failure_message
    end
 
    focused "should validate captcha answer and continue action on success" do
      brain_buster = BrainBuster.create!(:question => "what is 2 + 2?", :answer => "4")
      post :create, :captcha_id => brain_buster.id, :captcha_answer => "Four"
      assigns(:captcha).id.should == brain_buster.id.to_s
      response.body.should == "Success!"
    end
 
    it "should bypass captcha and never hit the database if it has been previously passed" do
      BrainBuster.expects(:find_random_or_previous).never
      # < Rails 2.3
      # @request.cookies["captcha_status"] = CGI::Cookie.new('captcha_status', BrainBusterSystem.encrypt("passed", @controller.brain_buster_salt))
      # > Rails 2.3
      request.cookies["captcha_status"] = BrainBusterSystem.encrypt("passed", controller.brain_buster_salt)
      post :create
      response.body.should == "Success!"
    end
    
    
  end
end
 
describe "Validate filter", ActionController::TestCase do
  
  describe "User manually deletes a record from the db", ActionController::TestCase do
    
    pending "successfully returns a record when the requested id does not exist in the db" do
      # BrainBuster.expects(:smart_find).with('123789')
      
      get :new, :captcha_id => '123789'
      assigns(:captcha).should.not.be nil
    end
    
  end
  
end