Make the API reject changes to closed notes
authorTom Hughes <tom@compton.nu>
Tue, 5 Feb 2013 18:08:42 +0000 (18:08 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 5 Feb 2013 18:08:42 +0000 (18:08 +0000)
app/controllers/notes_controller.rb
app/models/note.rb
lib/osm.rb
test/functional/notes_controller_test.rb

index a7fa03a..0544f87 100644 (file)
@@ -94,6 +94,7 @@ class NotesController < ApplicationController
     @note = Note.find(id)
     raise OSM::APINotFoundError unless @note
     raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
 
     # Add a comment to the note
     Note.transaction do
@@ -121,6 +122,7 @@ class NotesController < ApplicationController
     @note = Note.find_by_id(id)
     raise OSM::APINotFoundError unless @note
     raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
 
     # Close the note and add a comment
     Note.transaction do
index 801e1f3..bb56c5c 100644 (file)
@@ -52,6 +52,11 @@ class Note < ActiveRecord::Base
     status != "hidden"
   end
 
+  # Check if a note is closed
+  def closed?
+    not closed_at.nil?
+  end
+
   # Return the author object, derived from the first comment
   def author
     self.comments.first.author
index 3da9671..393011d 100644 (file)
@@ -281,6 +281,23 @@ module OSM
     end
   end
 
+  # Raised when the note provided is already closed
+  class APINoteAlreadyClosedError < APIError
+    def initialize(note)
+      @note = note
+    end
+
+    attr_reader :note
+
+    def status
+      :conflict
+    end
+
+    def to_s
+      "The note #{@note.id} was closed at #{@note.closed_at}"
+    end
+  end
+
   # Helper methods for going to/from mercator and lat/lng.
   class Mercator
     include Math
index 1c0ded3..6e6a3c1 100644 (file)
@@ -236,6 +236,11 @@ class NotesControllerTest < ActionController::TestCase
       post :comment, {:id => notes(:hidden_note_with_comment).id, :text => "This is an additional comment"}
     end
     assert_response :gone
+
+    assert_no_difference('NoteComment.count') do
+      post :comment, {:id => notes(:closed_note_with_comment).id, :text => "This is an additional comment"}
+    end
+    assert_response :conflict
   end
 
   def test_note_close_success
@@ -273,6 +278,9 @@ class NotesControllerTest < ActionController::TestCase
 
     post :close, {:id => notes(:hidden_note_with_comment).id}
     assert_response :gone
+
+    post :close, {:id => notes(:closed_note_with_comment).id}
+    assert_response :conflict
   end
 
   def test_note_read_success