public
Description: A Ruby web application framework
Homepage: http://www.mackframework.com
Clone URL: git://github.com/markbates/mack.git
Click here to lend your support to: mack and make a donation at www.pledgie.com !
mack / lib / mack / testing / helpers.rb
100644 204 lines (172 sloc) 5.909 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
require "test/unit"
 
#--
module Mack
  module RunnerHelpers # :nodoc:
    class Session
      private
      def retrieve_session_id(request, response, cookies)
        $current_session_id
      end
    end # Session
  end # RunnerHelpers
end # Mack
#++
 
module Mack
  module Testing # :nodoc:
    module Helpers
    
      # Runs the given rake task. Takes an optional hash that mimics command line parameters.
      def rake_task(name, env = {}, tasks = [])
        # set up the Rake application
        rake = Rake::Application.new
        Rake.application = rake
      
        [File.join(File.dirname(__FILE__), "..", "..", "mack_tasks.rb"), tasks].flatten.each do |task|
          load(task)
        end
      
        # save the old ENV so we can revert it
        old_env = ENV.to_hash
        # add in the new ENV stuff
        env.each_pair {|k,v| ENV[k.to_s] = v}
      
        begin
          # run the rake task
          rake[name].invoke
        
          # yield for the tests
          yield if block_given?
        
        rescue Exception => e
          raise e
        ensure
          # empty out the ENV
          ENV.clear
          # revert to the ENV before the test started
          old_env.to_hash.each_pair {|k,v| ENV[k] = v}
 
          # get rid of the Rake application
          Rake.application = nil
        end
      end
    
      # Temporarily changes the application configuration. Changes are reverted after
      # the yield returns.
      def temp_app_config(options = {})
        app_config.load_hash(options, String.randomize)
        yield
        app_config.revert
      end
    
      def remote_test # :nodoc:
        if (app_config.run_remote_tests)
          yield
        end
      end
    
      # Retrieves an instance variable from the controller from a request.
      def assigns(key)
        $mack_app.instance_variable_get("@app").instance_variable_get("@response").instance_variable_get("@controller").instance_variable_get("@#{key}")
      end
 
      # Performs a 'get' request for the specified uri.
      def get(uri, options = {})
        build_response(request.get(uri, build_request_options(options)))
      end
    
      # Performs a 'put' request for the specified uri.
      def put(uri, options = {})
        build_response(request.put(uri, build_request_options({:input => options.to_params})))
      end
    
      # Performs a 'post' request for the specified uri.
      def post(uri, options = {})
        build_response(request.post(uri, build_request_options({:input => options.to_params})))
      end
    
      # Performs a 'delete' request for the specified uri.
      def delete(uri, options = {})
        build_response(request.delete(uri, build_request_options(options)))
      end
    
      # Returns a Rack::MockRequest. If there isn't one, a new one is created.
      def request
        @request ||= Rack::MockRequest.new(mack_app)
      end
    
      # Returns the last Rack::MockResponse that got generated by a call.
      def response
        @testing_response
      end
    
      # Returns all the Rack::MockResponse objects that get generated by a call.
      def responses
        @responses
      end
    
      # Returns a Mack::Session from the request.
      def session # :nodoc:
        Cachetastic::Caches::MackSessionCache.get($current_session_id) do
          id = String.randomize(40).downcase
          set_cookie(app_config.mack.session_id, id)
          sess = Mack::Session.new(id)
          Cachetastic::Caches::MackSessionCache.set(id, sess)
          $current_session_id = id
          sess
        end
      end
    
      # Used to create a 'session' around a block of code. This is great of 'integration' tests.
      def in_session
        @_mack_in_session = true
        clear_session
        $current_session_id = session.id
        yield
        $current_session_id = nil
        clear_session
        @_mack_in_session = false
      end
    
      # Clears all the sessions.
      def clear_session
        Cachetastic::Caches::MackSessionCache.expire_all
      end
    
      # Returns a Hash of cookies from the response.
      def cookies
        test_cookies
      end
    
      # Sets a cookie to be used for the next request
      def set_cookie(name, value)
        test_cookies[name] = value
      end
    
      # Removes a cookie.
      def remove_cookie(name)
        test_cookies.delete(name)
      end
    
      private
      def test_cookies
        @test_cookies = {} if @test_cookies.nil?
        @test_cookies
      end
    
      def mack_app
        if $mack_app.nil?
          $mack_app = Rack::Recursive.new(Mack::Runner.new)
        end
        $mack_app
      end
    
      def build_request_options(options)
        {"HTTP_COOKIE" => test_cookies.join("%s=%s", "; ")}.merge(options)
      end
    
      def build_response(res)
        @responses = [res]
        strip_cookies_from_response(res)
        # only retry if it's a redirect request
        if res.redirect?
          until res.successful?
            [res].flatten.each do |r|
              strip_cookies_from_response(r)
            end
            res = request.get(res["Location"])
            @responses << res
          end
        end
        @testing_response = Mack::Testing::Response.new(@responses)
      end
    
      def strip_cookies_from_response(res)
        unless res.original_headers["Set-Cookie"].nil?
          res.original_headers["Set-Cookie"].each do |ck|
            puts "ck: #{ck}"
            spt = ck.split("=")
            name = spt.first
            value = spt.last
            if name == app_config.mack.session_id
              value = nil unless @_mack_in_session
            end
            set_cookie(name, value)
          end
        end
      end
    
    end # Helpers
  end # Testing
end # Mack
 
Test::Unit::TestCase.send(:include, Mack::Testing::Helpers)