diff options
-rw-r--r-- | app/controllers/api_controller.rb | 81 | ||||
-rw-r--r-- | app/models/incoming_message.rb | 2 | ||||
-rw-r--r-- | app/models/info_request.rb | 8 | ||||
-rw-r--r-- | spec/controllers/api_controller_spec.rb | 60 |
4 files changed, 150 insertions, 1 deletions
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index e5b66e7c3..9bcd82632 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -57,6 +57,7 @@ class ApiController < ApplicationController # Save the request, and add the corresponding InfoRequestEvent request.save! request.log_event("sent", + :api => true, :email => nil, :outgoing_message_id => outgoing_message.id, :smtp_message_id => nil @@ -71,7 +72,87 @@ class ApiController < ApplicationController end def add_correspondence + request = InfoRequest.find(params[:id]) + json = ActiveSupport::JSON.decode(params[:correspondence_json]) + direction = json["direction"] + body = json["body"] + sent_at_str = json["sent_at"] + + errors = [] + + if !request.is_external? + raise ActiveRecord::RecordNotFound.new("Request #{params[:id]} cannot be updated using the API") + end + + if request.public_body_id != @public_body.id + raise ActiveRecord::RecordNotFound.new("You do not own request #{params[:id]}") + end + + if !["request", "response"].include?(direction) + errors << "The direction parameter must be 'request' or 'response'" + end + + if body.nil? + errors << "The 'body' is missing" + elsif body.empty? + errors << "The 'body' is empty" + end + + begin + sent_at = Time.iso8601(sent_at_str) + rescue ArgumentError + errors << "Failed to parse 'sent_at' field as ISO8601 time: #{sent_at_str}" + end + + if !errors.empty? + render :json => { "errors" => errors } + return + end + + if direction == "request" + # In the 'request' direction, i.e. what we (Alaveteli) regard as outgoing + + outgoing_message = OutgoingMessage.new( + :info_request => request, + :status => 'ready', + :message_type => 'followup', + :body => body, + :last_sent_at => sent_at, + :what_doing => 'normal_sort' + ) + request.outgoing_messages << outgoing_message + request.save! + request.log_event("followup_sent", + :api => true, + :email => nil, + :outgoing_message_id => outgoing_message.id, + :smtp_message_id => nil + ) + else + # In the 'response' direction, i.e. what we (Alaveteli) regard as incoming + + raw_email = RawEmail.new + incoming_message = IncomingMessage.new( + :info_request => request, + :raw_email => raw_email, + :sent_at => sent_at + ) + raw_email.incoming_message = incoming_message + raw_email.save! + raw_email.data = "From external\nFrom: <none@example.org>\nTo: <none@example.org>\nDate: #{sent_at.rfc2822}\nSubject: Response\n\n" + body + + request.incoming_messages << incoming_message + request.save! + request.log_event("response", + :api => true, + :email => nil, + :incoming_message_id => incoming_message.id, + :smtp_message_id => nil + ) + end + + head :no_content end protected diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index 3419956d6..593590fb8 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -344,7 +344,7 @@ class IncomingMessage < ActiveRecord::Base # Lotus notes quoting yeuch! def remove_lotus_quoting(text, replacement = "FOLDED_QUOTED_SECTION") text = text.dup - name = Regexp.escape(self.info_request.user.name) + name = Regexp.escape(self.info_request.user_name) # To end of message sections # http://www.whatdotheyknow.com/request/university_investment_in_the_arm diff --git a/app/models/info_request.rb b/app/models/info_request.rb index 2f1270a95..8d9d92b0d 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -120,6 +120,14 @@ class InfoRequest < ActiveRecord::Base errors.add(:external_url, "must be null for an internal request") if !external_url.nil? end end + + def is_external? + !external_url.nil? + end + + def user_name + is_external? ? external_user_name : user.name + end @@custom_states_loaded = false begin diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb index 9d072e359..9d9d95215 100644 --- a/spec/controllers/api_controller_spec.rb +++ b/spec/controllers/api_controller_spec.rb @@ -1,6 +1,23 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe ApiController, "when using the API" do + it "should check the API key" do + request_data = { + "title" => "Tell me about your chickens", + "body" => "Dear Sir,\n\nI should like to know about your chickens.\n\nYours in faith,\nBob\n", + + "external_url" => "http://www.example.gov.uk/foi/chickens_23", + "external_user_name" => "Bob Smith", + } + + number_of_requests = InfoRequest.count + expect { + post :create_request, :k => "This is not really an API key", :request_json => request_data.to_json + }.to raise_error ApplicationController::PermissionDenied + + InfoRequest.count.should == number_of_requests + end + it "should create a new request from a POST" do geraldine = public_bodies(:geraldine_public_body) number_of_requests = InfoRequest.count(:conditions => ["public_body_id = ?", geraldine.id]) @@ -31,5 +48,48 @@ describe ApiController, "when using the API" do new_request.title.should == request_data["title"] new_request.last_event_forming_initial_request.outgoing_message.body.should == request_data["body"].strip + + new_request.public_body_id.should == geraldine.id + end + + it "should add a response to a request" do + geraldine = public_bodies(:geraldine_public_body) + + # First we need to create a request + post :create_request, :k => geraldine.api_key, :request_json => { + "title" => "Tell me about your chickens", + "body" => "Dear Sir,\n\nI should like to know about your chickens.\n\nYours in faith,\nBob\n", + + "external_url" => "http://www.example.gov.uk/foi/chickens_23", + "external_user_name" => "Bob Smith", + }.to_json + response.content_type.should == "application/json" + request_id = ActiveSupport::JSON.decode(response.body)["id"] + IncomingMessage.count(:conditions => ["info_request_id = ?", request_id]).should == 0 + + # Now add a response + sent_at = "2012-05-28T12:35:39+01:00" + response_body = "Thank you for your request for information, which we are handling in accordance with the Freedom of Information Act 2000. You will receive a response within 20 working days or before the next full moon, whichever is sooner.\n\nYours sincerely,\nJohn Gandermulch,\nExample Council FOI Officer\n" + post :add_correspondence, :k => geraldine.api_key, :id => request_id, :correspondence_json => { + "direction" => "response", + "sent_at" => sent_at, + "body" => response_body + }.to_json + + response.should be_success + incoming_messages = IncomingMessage.all(:conditions => ["info_request_id = ?", request_id]) + incoming_messages.count.should == 1 + incoming_message = incoming_messages[0] + + incoming_message.sent_at.should == Time.iso8601(sent_at) + incoming_message.get_main_body_text_folded.should == response_body + end + + it "should allow attachments to be uploaded" do + + end + + it "should show information about a request" do + end end |