diff --git a/lib/coopexport/interface/session.rb b/lib/coopexport/interface/session.rb new file mode 100644 index 0000000..acc8541 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/spec/interface/session_spec.rb b/spec/interface/session_spec.rb new file mode 100644 index 0000000..902ec00 --- /dev/null +++ b/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 \ No newline at end of file