提交 58d02520 编写于 作者: M Mark Fletcher

Ensure validation messages are shown within the milestone form

* Remove call to Milestone#save! instead just Milestone#save
* Add safety specs to stop a regression

Fixes #22033
上级 62516461
...@@ -139,6 +139,7 @@ v 8.12.0 (unreleased) ...@@ -139,6 +139,7 @@ v 8.12.0 (unreleased)
- Use default clone protocol on "check out, review, and merge locally" help page URL - Use default clone protocol on "check out, review, and merge locally" help page URL
- API for Ci Lint !5953 (Katarzyna Kobierska Urszula Budziszewska) - API for Ci Lint !5953 (Katarzyna Kobierska Urszula Budziszewska)
- Allow bulk update merge requests from merge requests index page - Allow bulk update merge requests from merge requests index page
- Ensure validation messages are shown within the milestone form
- Add notification_settings API calls !5632 (mahcsig) - Add notification_settings API calls !5632 (mahcsig)
- Remove duplication between project builds and admin builds view !5680 (Katarzyna Kobierska Ula Budziszewska) - Remove duplication between project builds and admin builds view !5680 (Katarzyna Kobierska Ula Budziszewska)
- Fix URLs with anchors in wiki !6300 (houqp) - Fix URLs with anchors in wiki !6300 (houqp)
......
...@@ -3,7 +3,7 @@ module Milestones ...@@ -3,7 +3,7 @@ module Milestones
def execute def execute
milestone = project.milestones.new(params) milestone = project.milestones.new(params)
if milestone.save! if milestone.save
event_service.open_milestone(milestone, current_user) event_service.open_milestone(milestone, current_user)
end end
......
...@@ -3,9 +3,8 @@ require 'rails_helper' ...@@ -3,9 +3,8 @@ require 'rails_helper'
feature 'Milestone', feature: true do feature 'Milestone', feature: true do
include WaitForAjax include WaitForAjax
let(:project) { create(:project, :public) } let(:project) { create(:empty_project, :public) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project, title: 8.7) }
before do before do
project.team << [user, :master] project.team << [user, :master]
...@@ -13,7 +12,7 @@ feature 'Milestone', feature: true do ...@@ -13,7 +12,7 @@ feature 'Milestone', feature: true do
end end
feature 'Create a milestone' do feature 'Create a milestone' do
scenario 'shows an informative message for a new issue' do scenario 'shows an informative message for a new milestone' do
visit new_namespace_project_milestone_path(project.namespace, project) visit new_namespace_project_milestone_path(project.namespace, project)
page.within '.milestone-form' do page.within '.milestone-form' do
fill_in "milestone_title", with: '8.7' fill_in "milestone_title", with: '8.7'
...@@ -26,10 +25,26 @@ feature 'Milestone', feature: true do ...@@ -26,10 +25,26 @@ feature 'Milestone', feature: true do
feature 'Open a milestone with closed issues' do feature 'Open a milestone with closed issues' do
scenario 'shows an informative message' do scenario 'shows an informative message' do
milestone = create(:milestone, project: project, title: 8.7)
create(:issue, title: "Bugfix1", project: project, milestone: milestone, state: "closed") create(:issue, title: "Bugfix1", project: project, milestone: milestone, state: "closed")
visit namespace_project_milestone_path(project.namespace, project, milestone) visit namespace_project_milestone_path(project.namespace, project, milestone)
expect(find('.alert-success')).to have_content('All issues for this milestone are closed. You may close this milestone now.') expect(find('.alert-success')).to have_content('All issues for this milestone are closed. You may close this milestone now.')
end end
end end
feature 'Open a milestone with an existing title' do
scenario 'displays validation message' do
milestone = create(:milestone, project: project, title: 8.7)
visit new_namespace_project_milestone_path(project.namespace, project)
page.within '.milestone-form' do
fill_in "milestone_title", with: milestone.title
end
find('input[name="commit"]').click
expect(find('.alert-danger')).to have_content('Title has already been taken')
end
end
end end
...@@ -3,7 +3,7 @@ require 'spec_helper' ...@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::API, api: true do describe API::API, api: true do
include ApiHelpers include ApiHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:project) { create(:project, namespace: user.namespace ) } let!(:project) { create(:empty_project, namespace: user.namespace ) }
let!(:closed_milestone) { create(:closed_milestone, project: project) } let!(:closed_milestone) { create(:closed_milestone, project: project) }
let!(:milestone) { create(:milestone, project: project) } let!(:milestone) { create(:milestone, project: project) }
...@@ -12,6 +12,7 @@ describe API::API, api: true do ...@@ -12,6 +12,7 @@ describe API::API, api: true do
describe 'GET /projects/:id/milestones' do describe 'GET /projects/:id/milestones' do
it 'returns project milestones' do it 'returns project milestones' do
get api("/projects/#{project.id}/milestones", user) get api("/projects/#{project.id}/milestones", user)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(milestone.title) expect(json_response.first['title']).to eq(milestone.title)
...@@ -19,6 +20,7 @@ describe API::API, api: true do ...@@ -19,6 +20,7 @@ describe API::API, api: true do
it 'returns a 401 error if user not authenticated' do it 'returns a 401 error if user not authenticated' do
get api("/projects/#{project.id}/milestones") get api("/projects/#{project.id}/milestones")
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
...@@ -44,6 +46,7 @@ describe API::API, api: true do ...@@ -44,6 +46,7 @@ describe API::API, api: true do
describe 'GET /projects/:id/milestones/:milestone_id' do describe 'GET /projects/:id/milestones/:milestone_id' do
it 'returns a project milestone by id' do it 'returns a project milestone by id' do
get api("/projects/#{project.id}/milestones/#{milestone.id}", user) get api("/projects/#{project.id}/milestones/#{milestone.id}", user)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response['title']).to eq(milestone.title) expect(json_response['title']).to eq(milestone.title)
expect(json_response['iid']).to eq(milestone.iid) expect(json_response['iid']).to eq(milestone.iid)
...@@ -60,11 +63,13 @@ describe API::API, api: true do ...@@ -60,11 +63,13 @@ describe API::API, api: true do
it 'returns 401 error if user not authenticated' do it 'returns 401 error if user not authenticated' do
get api("/projects/#{project.id}/milestones/#{milestone.id}") get api("/projects/#{project.id}/milestones/#{milestone.id}")
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
it 'returns a 404 error if milestone id not found' do it 'returns a 404 error if milestone id not found' do
get api("/projects/#{project.id}/milestones/1234", user) get api("/projects/#{project.id}/milestones/1234", user)
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
end end
...@@ -72,6 +77,7 @@ describe API::API, api: true do ...@@ -72,6 +77,7 @@ describe API::API, api: true do
describe 'POST /projects/:id/milestones' do describe 'POST /projects/:id/milestones' do
it 'creates a new project milestone' do it 'creates a new project milestone' do
post api("/projects/#{project.id}/milestones", user), title: 'new milestone' post api("/projects/#{project.id}/milestones", user), title: 'new milestone'
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
expect(json_response['title']).to eq('new milestone') expect(json_response['title']).to eq('new milestone')
expect(json_response['description']).to be_nil expect(json_response['description']).to be_nil
...@@ -80,6 +86,7 @@ describe API::API, api: true do ...@@ -80,6 +86,7 @@ describe API::API, api: true do
it 'creates a new project milestone with description and due date' do it 'creates a new project milestone with description and due date' do
post api("/projects/#{project.id}/milestones", user), post api("/projects/#{project.id}/milestones", user),
title: 'new milestone', description: 'release', due_date: '2013-03-02' title: 'new milestone', description: 'release', due_date: '2013-03-02'
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
expect(json_response['description']).to eq('release') expect(json_response['description']).to eq('release')
expect(json_response['due_date']).to eq('2013-03-02') expect(json_response['due_date']).to eq('2013-03-02')
...@@ -87,6 +94,14 @@ describe API::API, api: true do ...@@ -87,6 +94,14 @@ describe API::API, api: true do
it 'returns a 400 error if title is missing' do it 'returns a 400 error if title is missing' do
post api("/projects/#{project.id}/milestones", user) post api("/projects/#{project.id}/milestones", user)
expect(response).to have_http_status(400)
end
it 'returns a 400 error if params are invalid (duplicate title)' do
post api("/projects/#{project.id}/milestones", user),
title: milestone.title, description: 'release', due_date: '2013-03-02'
expect(response).to have_http_status(400) expect(response).to have_http_status(400)
end end
end end
...@@ -95,6 +110,7 @@ describe API::API, api: true do ...@@ -95,6 +110,7 @@ describe API::API, api: true do
it 'updates a project milestone' do it 'updates a project milestone' do
put api("/projects/#{project.id}/milestones/#{milestone.id}", user), put api("/projects/#{project.id}/milestones/#{milestone.id}", user),
title: 'updated title' title: 'updated title'
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response['title']).to eq('updated title') expect(json_response['title']).to eq('updated title')
end end
...@@ -102,6 +118,7 @@ describe API::API, api: true do ...@@ -102,6 +118,7 @@ describe API::API, api: true do
it 'returns a 404 error if milestone id not found' do it 'returns a 404 error if milestone id not found' do
put api("/projects/#{project.id}/milestones/1234", user), put api("/projects/#{project.id}/milestones/1234", user),
title: 'updated title' title: 'updated title'
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
end end
...@@ -131,6 +148,7 @@ describe API::API, api: true do ...@@ -131,6 +148,7 @@ describe API::API, api: true do
end end
it 'returns project issues for a particular milestone' do it 'returns project issues for a particular milestone' do
get api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user) get api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.first['milestone']['title']).to eq(milestone.title) expect(json_response.first['milestone']['title']).to eq(milestone.title)
...@@ -138,11 +156,12 @@ describe API::API, api: true do ...@@ -138,11 +156,12 @@ describe API::API, api: true do
it 'returns a 401 error if user not authenticated' do it 'returns a 401 error if user not authenticated' do
get api("/projects/#{project.id}/milestones/#{milestone.id}/issues") get api("/projects/#{project.id}/milestones/#{milestone.id}/issues")
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
describe 'confidential issues' do describe 'confidential issues' do
let(:public_project) { create(:project, :public) } let(:public_project) { create(:empty_project, :public) }
let(:milestone) { create(:milestone, project: public_project) } let(:milestone) { create(:milestone, project: public_project) }
let(:issue) { create(:issue, project: public_project) } let(:issue) { create(:issue, project: public_project) }
let(:confidential_issue) { create(:issue, confidential: true, project: public_project) } let(:confidential_issue) { create(:issue, confidential: true, project: public_project) }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册