Skip to content

Commit

Permalink
A general purpose Session object allows us to send POST/GET requests …
Browse files Browse the repository at this point in the history
…to the Co-Op website whilst keeping track of the security token used to validate requests
  • Loading branch information
Luke Redpath committed Apr 9, 2008
1 parent d5e4f9d commit ed05c8c
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
53 changes: 53 additions & 0 deletions lib/coopexport/interface/session.rb
@@ -0,0 +1,53 @@
require 'net/http'

module CoopExport
module Interface
class Session
attr_reader :security_token

SECURITY_TOKEN_KEY = 'org.apache.struts.taglib.html.TOKEN'

def initialize(connection, response_parser = ResponseParser.new)
@connection = connection
@security_token = nil
@response_parser = response_parser
end

def request(request_object)
response = @connection.request(request_object)
if response.code == '200'
@security_token = @response_parser.find_security_token(response.body)
end
return response
end

def get(path, params)
query_string = query_string_from_params( secure_params(params) )
request_uri = URI::HTTP.build(:path => path, :query => query_string).request_uri
get_request = Net::HTTP::Get.new(request_uri)
request(get_request)
end

def post(path, params)
post_request = Net::HTTP::Post.new(path)
post_request.set_form_data(secure_params(params))
request(post_request)
end

private
def secure_params(params)
params.merge(SECURITY_TOKEN_KEY => security_token)
end

def query_string_from_params(param_hash)
param_hash.inject([]) { |params, (key, value)| params << "#{key}=#{value}" }.sort.join('&')
end
end

class ResponseParser
def find_security_token(html_content)

end
end
end
end
57 changes: 57 additions & 0 deletions spec/interface/session_spec.rb
@@ -0,0 +1,57 @@
require File.join(File.dirname(__FILE__), *%w[.. spec_helper])

require 'coopexport/interface/session'

describe "A new session" do
before :each do
@session = CoopExport::Interface::Session.new(stub('connection'))
end

it "should have no security token" do
@session.security_token.should be_nil
end
end

describe "A session, when sending a request" do
before :each do
@connection = mock('connection')
@response_parser = stub('response parser')
@session = CoopExport::Interface::Session.new(@connection, @response_parser)
end

it "should send the specified request using the available connection" do
request = stub('request')
@connection.expects(:request).with(request).returns(stub_everything('response'))
@session.request(request)
end

it "should parse the response body and store the new security token if a 200 response is returned" do
response = stub('http response', :body => 'html content', :code => '200')
@connection.stubs(:request).returns(response)
@response_parser.stubs(:find_security_token).with('html content').returns('NEW_SECURITY_TOKEN')
@session.request(stub)
@session.security_token.should == 'NEW_SECURITY_TOKEN'
end
end

describe "A session, in general" do
before :each do
@session = CoopExport::Interface::Session.new(stub('connection'))
@session.stubs(:security_token).returns('CURRENT_TOKEN')
end

it "should append the current security token to form data when sending POST" do
post_params = {'param_one' => 'foo', 'param_two' => 'bar'}
Net::HTTP::Post.stubs(:new).with('/path').returns(post_request = stub)
post_request.expects(:set_form_data).with(post_params.merge('org.apache.struts.taglib.html.TOKEN' => 'CURRENT_TOKEN'))
@session.expects(:request).with(post_request)
@session.post('/path', post_params)
end

it "should append the current security token to query parameters when sending GET" do
get_params = {'a' => 'foo', 'b' => 'bar'}
Net::HTTP::Get.stubs(:new).with('/path?a=foo&b=bar&org.apache.struts.taglib.html.TOKEN=CURRENT_TOKEN').returns(get_request = stub)
@session.expects(:request).with(get_request)
@session.get('/path', get_params)
end
end

0 comments on commit ed05c8c

Please sign in to comment.