1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
# frozen_string_literal: true
RSpec.shared_examples 'an unauthorized API user' do
it { is_expected.to eq(403) }
end
RSpec.shared_examples 'API user with insufficient permissions' do
context 'with non member that is the author' do
before do
issuable.update!(author: non_member) # an external author can't admin issuable
end
it_behaves_like 'an unauthorized API user'
end
end
RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
let(:non_member) { create(:user) }
issuable_collection_name = issuable_name.pluralize
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_estimate" do
subject(:set_time_estimate) do
post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: duration })
end
let(:duration) { '2h' }
context 'with an unauthorized user' do
let(:user) { non_member }
it_behaves_like 'an unauthorized API user'
it_behaves_like 'API user with insufficient permissions'
end
context 'with an authorized user' do
it "sets the time estimate for #{issuable_name}" do
set_time_estimate
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['time_estimate']).to eq(7200)
end
end
describe 'updating the current estimate' do
before do
post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '2h' })
end
using RSpec::Parameterized::TableSyntax
where(:updated_duration, :expected_http_status, :expected_time_estimate) do
'foo' | :bad_request | 7200
'-1' | :bad_request | 7200
'1h' | :ok | 3600
'0' | :ok | 0
end
with_them do
let(:duration) { updated_duration }
it 'returns expected HTTP status and time estimate' do
set_time_estimate
expect(response).to have_gitlab_http_status(expected_http_status)
expect(issuable.reload.time_estimate).to eq(expected_time_estimate)
end
end
end
end
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/reset_time_estimate" do
context 'with an unauthorized user' do
subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_time_estimate", non_member)) }
it_behaves_like 'an unauthorized API user'
it_behaves_like 'API user with insufficient permissions'
end
it "resets the time estimate for #{issuable_name}" do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_time_estimate", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['time_estimate']).to eq(0)
end
end
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/add_spent_time" do
context 'with an unauthorized user' do
subject do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", non_member), params: { duration: '2h' }
end
it_behaves_like 'an unauthorized API user'
it_behaves_like 'API user with insufficient permissions'
end
it "add spent time for #{issuable_name}" do
travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' }
end.to change { issuable.reload.updated_at }
end
expect(response).to have_gitlab_http_status(:created)
expect(json_response['human_total_time_spent']).to eq('2h')
end
context 'when subtracting time' do
it 'subtracts time of the total spent time' do
travel_to(2.minutes.from_now) do
expect do
issuable.update!(spend_time: { duration: 7200, user_id: user.id })
end.to change { issuable.reload.updated_at }
end
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1h' }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['total_time_spent']).to eq(3600)
end
end
context 'when time to subtract is greater than the total spent time' do
it 'does not modify the total time spent' do
issuable.update!(spend_time: { duration: 7200, user_id: user.id })
travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1w' }
end.not_to change { issuable.reload.updated_at }
end
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']['base'].first).to eq(_('Time to subtract exceeds the total time spent'))
end
end
if issuable_name == 'merge_request'
it 'calls update service with :use_specialized_service param' do
expect(::MergeRequests::UpdateService).to receive(:new).with(
project: project,
current_user: user,
params: hash_including(
use_specialized_service: true,
spend_time: hash_including(duration: 7200, summary: 'summary')))
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h', summary: 'summary' }
end
end
if issuable_name == 'issue'
it 'calls update service without :use_specialized_service param' do
expect(::Issues::UpdateService).to receive(:new).with(
container: project,
current_user: user,
params: { spend_time: { duration: 3600, summary: 'summary', user_id: user.id } })
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '1h', summary: 'summary' }
end
end
end
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/reset_spent_time" do
context 'with an unauthorized user' do
subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_spent_time", non_member)) }
it_behaves_like 'an unauthorized API user'
it_behaves_like 'API user with insufficient permissions'
end
it "resets spent time for #{issuable_name}" do
issuable.update!(spend_time: { duration: 60, user_id: user.id })
travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_spent_time", user)
end.to change { issuable.reload.updated_at }
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_time_spent']).to eq(0)
end
end
describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do
it "returns the time stats for #{issuable_name}" do
issuable.update!(spend_time: { duration: 1800, user_id: user.id }, time_estimate: 3600)
get api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_stats", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_time_spent']).to eq(1800)
expect(json_response['time_estimate']).to eq(3600)
end
end
end
|