diff options
author | Jan Provaznik <jprovaznik@gitlab.com> | 2018-02-28 10:48:23 +0300 |
---|---|---|
committer | Jan Provaznik <jprovaznik@gitlab.com> | 2018-03-07 14:27:50 +0300 |
commit | dcdfa04b322db3905f6871a6857e7055c556547f (patch) | |
tree | b3d006e8410b7182c63bfd620b99a71392c77aff /spec/support | |
parent | 8a0052c037f025b64159ca8cfe0d3451261c1edb (diff) |
Add discussion API
* adds basic discussions API for issues and snippets
* reorganizes notes specs (so same tests can be used for all noteable types - issues, MRs, snippets)
Diffstat (limited to 'spec/support')
-rw-r--r-- | spec/support/shared_examples/requests/api/discussions.rb | 169 | ||||
-rw-r--r-- | spec/support/shared_examples/requests/api/notes.rb | 206 |
2 files changed, 375 insertions, 0 deletions
diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb new file mode 100644 index 00000000000..b6aeb30d69c --- /dev/null +++ b/spec/support/shared_examples/requests/api/discussions.rb @@ -0,0 +1,169 @@ +shared_examples 'discussions API' do |parent_type, noteable_type, id_name| + describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do + it "returns an array of discussions" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['id']).to eq(note.discussion_id) + end + + it "returns a 404 error when noteable id not found" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/12345/discussions", user) + + expect(response).to have_gitlab_http_status(404) + end + + it "returns 404 when not authorized" do + parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", private_user) + + expect(response).to have_gitlab_http_status(404) + end + end + + describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id" do + it "returns a discussion by id" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions/#{note.discussion_id}", user) + + expect(response).to have_gitlab_http_status(200) + expect(json_response['id']).to eq(note.discussion_id) + expect(json_response['notes'].first['body']).to eq(note.note) + end + + it "returns a 404 error if discussion not found" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions/12345", user) + + expect(response).to have_gitlab_http_status(404) + end + end + + describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do + it "creates a new note" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!' + + expect(response).to have_gitlab_http_status(201) + expect(json_response['notes'].first['body']).to eq('hi!') + expect(json_response['notes'].first['author']['username']).to eq(user.username) + end + + it "returns a 400 bad request error if body not given" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user) + + expect(response).to have_gitlab_http_status(400) + end + + it "returns a 401 unauthorized error if user not authenticated" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), body: 'hi!' + + expect(response).to have_gitlab_http_status(401) + end + + context 'when an admin or owner makes the request' do + it 'accepts the creation date to be set' do + creation_time = 2.weeks.ago + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), + body: 'hi!', created_at: creation_time + + expect(response).to have_gitlab_http_status(201) + expect(json_response['notes'].first['body']).to eq('hi!') + expect(json_response['notes'].first['author']['username']).to eq(user.username) + expect(Time.parse(json_response['notes'].first['created_at'])).to be_like_time(creation_time) + end + end + + context 'when user does not have access to read the discussion' do + before do + parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + end + + it 'responds with 404' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", private_user), + body: 'Foo' + + expect(response).to have_gitlab_http_status(404) + end + end + end + + describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes" do + it 'adds a new note to the discussion' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes", user), body: 'Hello!' + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('Hello!') + expect(json_response['type']).to eq('DiscussionNote') + end + + it 'returns a 400 bad request error if body not given' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes", user) + + expect(response).to have_gitlab_http_status(400) + end + + it "returns a 400 bad request error if discussion is individual note" do + note.update_attribute(:type, nil) + + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes", user), body: 'hi!' + + expect(response).to have_gitlab_http_status(400) + end + end + + describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do + it 'returns modified note' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/#{note.id}", user), body: 'Hello!' + + expect(response).to have_gitlab_http_status(200) + expect(json_response['body']).to eq('Hello!') + end + + it 'returns a 404 error when note id not found' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/12345", user), + body: 'Hello!' + + expect(response).to have_gitlab_http_status(404) + end + + it 'returns a 400 bad request error if body not given' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/#{note.id}", user) + + expect(response).to have_gitlab_http_status(400) + end + end + + describe "DELETE /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do + it 'deletes a note' do + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/#{note.id}", user) + + expect(response).to have_gitlab_http_status(204) + # Check if note is really deleted + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/#{note.id}", user) + expect(response).to have_gitlab_http_status(404) + end + + it 'returns a 404 error when note id not found' do + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/12345", user) + + expect(response).to have_gitlab_http_status(404) + end + + it_behaves_like '412 response' do + let(:request) do + api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "discussions/#{note.discussion_id}/notes/#{note.id}", user) + end + end + end +end diff --git a/spec/support/shared_examples/requests/api/notes.rb b/spec/support/shared_examples/requests/api/notes.rb new file mode 100644 index 00000000000..79b2196660c --- /dev/null +++ b/spec/support/shared_examples/requests/api/notes.rb @@ -0,0 +1,206 @@ +shared_examples 'noteable API' do |parent_type, noteable_type, id_name| + describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do + context 'sorting' do + before do + params = { noteable: noteable, author: user } + params[:project] = parent if parent.is_a?(Project) + + create_list(:note, 3, params) + end + + it 'sorts by created_at in descending order by default' do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user) + + response_dates = json_response.map { |note| note['created_at'] } + + expect(json_response.length).to eq(4) + expect(response_dates).to eq(response_dates.sort.reverse) + end + + it 'sorts by ascending order when requested' do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?sort=asc", user) + + response_dates = json_response.map { |note| note['created_at'] } + + expect(json_response.length).to eq(4) + expect(response_dates).to eq(response_dates.sort) + end + + it 'sorts by updated_at in descending order when requested' do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at", user) + + response_dates = json_response.map { |note| note['updated_at'] } + + expect(json_response.length).to eq(4) + expect(response_dates).to eq(response_dates.sort.reverse) + end + + it 'sorts by updated_at in ascending order when requested' do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at&sort=asc", user) + + response_dates = json_response.map { |note| note['updated_at'] } + + expect(json_response.length).to eq(4) + expect(response_dates).to eq(response_dates.sort) + end + end + + it "returns an array of notes" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['body']).to eq(note.note) + end + + it "returns a 404 error when noteable id not found" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/12345/notes", user) + + expect(response).to have_gitlab_http_status(404) + end + + it "returns 404 when not authorized" do + parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user) + + expect(response).to have_gitlab_http_status(404) + end + end + + describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do + it "returns a note by id" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user) + + expect(response).to have_gitlab_http_status(200) + expect(json_response['body']).to eq(note.note) + end + + it "returns a 404 error if note not found" do + get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/12345", user) + + expect(response).to have_gitlab_http_status(404) + end + end + + describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do + it "creates a new note" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!' + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + end + + it "returns a 400 bad request error if body not given" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user) + + expect(response).to have_gitlab_http_status(400) + end + + it "returns a 401 unauthorized error if user not authenticated" do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"), body: 'hi!' + + expect(response).to have_gitlab_http_status(401) + end + + it "creates an activity event when a note is created" do + expect(Event).to receive(:create!) + + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!' + end + + context 'when an admin or owner makes the request' do + it 'accepts the creation date to be set' do + creation_time = 2.weeks.ago + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), + body: 'hi!', created_at: creation_time + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + end + end + + context 'when the user is posting an award emoji on a noteable created by someone else' do + it 'creates a new note' do + parent.add_developer(private_user) + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), body: ':+1:' + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq(':+1:') + end + end + + context 'when the user is posting an award emoji on his/her own noteable' do + it 'creates a new note' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: ':+1:' + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq(':+1:') + end + end + + context 'when user does not have access to read the noteable' do + before do + parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + end + + it 'responds with 404' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), + body: 'Foo' + + expect(response).to have_gitlab_http_status(404) + end + end + end + + describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do + it 'returns modified note' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "notes/#{note.id}", user), body: 'Hello!' + + expect(response).to have_gitlab_http_status(200) + expect(json_response['body']).to eq('Hello!') + end + + it 'returns a 404 error when note id not found' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/12345", user), + body: 'Hello!' + + expect(response).to have_gitlab_http_status(404) + end + + it 'returns a 400 bad request error if body not given' do + put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "notes/#{note.id}", user) + + expect(response).to have_gitlab_http_status(400) + end + end + + describe "DELETE /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do + it 'deletes a note' do + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "notes/#{note.id}", user) + + expect(response).to have_gitlab_http_status(204) + # Check if note is really deleted + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\ + "notes/#{note.id}", user) + expect(response).to have_gitlab_http_status(404) + end + + it 'returns a 404 error when note id not found' do + delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/12345", user) + + expect(response).to have_gitlab_http_status(404) + end + + it_behaves_like '412 response' do + let(:request) { api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user) } + end + end +end |