diff --git a/lib/api.rb b/lib/api.rb index 7a1845443e7..99e2074f306 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -19,5 +19,6 @@ module Gitlab mount Milestones mount Session mount MergeRequests + mount Notes end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 9e605a607a2..0c44f621b08 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -70,8 +70,10 @@ module Gitlab end class Note < Grape::Entity + expose :id + expose :note, as: :body expose :author, using: Entities::UserBasic - expose :note + expose :updated_at, :created_at end end end diff --git a/lib/api/notes.rb b/lib/api/notes.rb new file mode 100644 index 00000000000..d2857f3d2c7 --- /dev/null +++ b/lib/api/notes.rb @@ -0,0 +1,38 @@ +module Gitlab + # Notes API + class Notes < Grape::API + before { authenticate! } + + NOTEABLE_TYPES = [Issue, Snippet] + + resource :projects do + # Get a list of project wall notes + # + # Parameters: + # id (required) - The ID or code name of a project + # Example Request: + # GET /projects/:id/notes + get ":id/notes" do + @notes = user_project.common_notes + present paginate(@notes), with: Entities::Note + end + + NOTEABLE_TYPES.each do |noteable_type| + noteables_str = noteable_type.to_s.underscore.pluralize + noteable_id_str = "#{noteable_type.to_s.underscore}_id" + + # Get a list of project +noteable+ notes + # + # Parameters: + # id (required) - The ID or code name of a project + # noteable_id (required) - The ID of an issue or snippet + # Example Request: + # GET /projects/:id/noteable/:noteable_id/notes + get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do + @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) + present paginate(@noteable.notes), with: Entities::Note + end + end + end + end +end diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb new file mode 100644 index 00000000000..1d42921f00c --- /dev/null +++ b/spec/requests/api/notes_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe Gitlab::API do + include ApiHelpers + + let(:user) { create(:user) } + let!(:project) { create(:project, owner: user) } + let!(:issue) { create(:issue, project: project, author: user) } + let!(:snippet) { create(:snippet, project: project, author: user) } + let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) } + let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) } + let!(:wall_note) { create(:note, project: project, author: user) } + before { project.add_access(user, :read) } + + describe "GET /projects/:id/notes" do + context "when unauthenticated" do + it "should return authentication error" do + get api("/projects/#{project.id}/notes") + response.status.should == 401 + end + end + + context "when authenticated" do + it "should return project wall notes" do + get api("/projects/#{project.id}/notes", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['body'].should == wall_note.note + end + end + end + + describe "GET /projects/:id/noteable/:noteable_id/notes" do + context "when noteable is an Issue" do + it "should return an array of notes" do + get api("/projects/#{project.id}/issues/#{issue.id}/notes", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['body'].should == issue_note.note + end + end + + context "when noteable is a Snippet" do + it "should return an array of notes" do + get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['body'].should == snippet_note.note + end + end + end +end