|
244 | 244 | end |
245 | 245 | end |
246 | 246 |
|
| 247 | + context 'filtering by global activity' do |
| 248 | + let(:project_activity) do |
| 249 | + FactoryBot.create(:time_entry_activity, |
| 250 | + parent: activity, |
| 251 | + project: project) |
| 252 | + end |
| 253 | + let(:other_project_activity) do |
| 254 | + FactoryBot.create(:time_entry_activity, |
| 255 | + parent: activity, |
| 256 | + project: other_project) |
| 257 | + end |
| 258 | + let(:another_project_activity) do |
| 259 | + FactoryBot.create(:time_entry_activity, |
| 260 | + parent: FactoryBot.create(:time_entry_activity), |
| 261 | + project: project) |
| 262 | + end |
| 263 | + let(:shared_activity) do |
| 264 | + FactoryBot.create(:time_entry_activity, |
| 265 | + parent: nil) |
| 266 | + end |
| 267 | + let!(:time_entry) do |
| 268 | + FactoryBot.create(:time_entry, |
| 269 | + project: project, |
| 270 | + work_package: work_package, |
| 271 | + user: current_user, |
| 272 | + activity: project_activity) |
| 273 | + end |
| 274 | + let!(:other_time_entry) do |
| 275 | + FactoryBot.create(:time_entry, |
| 276 | + project: other_project, |
| 277 | + work_package: other_work_package, |
| 278 | + user: current_user, |
| 279 | + activity: other_project_activity) |
| 280 | + end |
| 281 | + let!(:another_time_entry) do |
| 282 | + FactoryBot.create(:time_entry, |
| 283 | + project: project, |
| 284 | + work_package: work_package, |
| 285 | + user: current_user, |
| 286 | + activity: another_project_activity) |
| 287 | + end |
| 288 | + let!(:shared_time_entry) do |
| 289 | + FactoryBot.create(:time_entry, |
| 290 | + project: project, |
| 291 | + work_package: work_package, |
| 292 | + user: current_user, |
| 293 | + activity: shared_activity) |
| 294 | + end |
| 295 | + |
| 296 | + before do |
| 297 | + FactoryBot.create(:member, |
| 298 | + roles: [role], |
| 299 | + project: other_project, |
| 300 | + user: current_user) |
| 301 | + get path |
| 302 | + end |
| 303 | + |
| 304 | + let(:path) do |
| 305 | + filter = [ |
| 306 | + { |
| 307 | + 'activity_id' => { |
| 308 | + 'operator' => '=', |
| 309 | + 'values' => [activity.id, shared_activity.id] |
| 310 | + } |
| 311 | + } |
| 312 | + ] |
| 313 | + |
| 314 | + "#{api_v3_paths.time_entries}?#{{ filters: filter.to_json }.to_query}&sortBy=#{[%w(id asc)].to_json}" |
| 315 | + end |
| 316 | + |
| 317 | + it 'contains only the filtered time entries in the response' do |
| 318 | + expect(subject.body) |
| 319 | + .to be_json_eql('3') |
| 320 | + .at_path('total') |
| 321 | + |
| 322 | + expect(subject.body) |
| 323 | + .to be_json_eql(time_entry.id.to_json) |
| 324 | + .at_path('_embedded/elements/0/id') |
| 325 | + |
| 326 | + expect(subject.body) |
| 327 | + .to be_json_eql(other_time_entry.id.to_json) |
| 328 | + .at_path('_embedded/elements/1/id') |
| 329 | + |
| 330 | + expect(subject.body) |
| 331 | + .to be_json_eql(shared_time_entry.id.to_json) |
| 332 | + .at_path('_embedded/elements/2/id') |
| 333 | + end |
| 334 | + end |
| 335 | + |
247 | 336 | context 'invalid filter' do |
248 | 337 | let(:path) do |
249 | 338 | filter = [{ 'bogus' => { |
|
333 | 422 | } |
334 | 423 | } |
335 | 424 | end |
336 | | - let(:additional_setup) { ->{} } |
| 425 | + let(:additional_setup) { -> {} } |
337 | 426 |
|
338 | 427 | before do |
339 | 428 | work_package |
|
445 | 534 |
|
446 | 535 | let(:params) do |
447 | 536 | { |
448 | | - "hours": 'PT10H' |
| 537 | + "hours": 'PT10H', |
| 538 | + "activity": { |
| 539 | + "href": api_v3_paths.time_entries_activity(activity.id) |
| 540 | + } |
449 | 541 | } |
450 | 542 | end |
451 | 543 |
|
| 544 | + let(:additional_setup) { -> {} } |
| 545 | + |
452 | 546 | before do |
453 | 547 | time_entry |
454 | 548 | custom_value |
455 | 549 |
|
| 550 | + additional_setup.call |
| 551 | + |
456 | 552 | patch path, params.to_json, 'CONTENT_TYPE' => 'application/json' |
457 | 553 | end |
458 | 554 |
|
|
461 | 557 |
|
462 | 558 | time_entry.reload |
463 | 559 | expect(time_entry.hours).to eq 10 |
| 560 | + |
| 561 | + expect(time_entry.activity).to eq activity |
464 | 562 | end |
465 | 563 |
|
466 | 564 | context 'when lacking permissions' do |
|
472 | 570 | end |
473 | 571 | end |
474 | 572 |
|
| 573 | + context 'when sending an activity the project overrides' do |
| 574 | + let(:project_activity) do |
| 575 | + params = activity.attributes.except('id') |
| 576 | + params['parent_id'] = activity.id |
| 577 | + project.create_time_entry_activity_if_needed(params) |
| 578 | + |
| 579 | + project.time_entry_activities.first |
| 580 | + end |
| 581 | + |
| 582 | + let(:additional_setup) { -> { project_activity } } |
| 583 | + |
| 584 | + it 'creates the time entry with the project activity' do |
| 585 | + time_entry.reload |
| 586 | + |
| 587 | + expect(time_entry.activity) |
| 588 | + .to eql project_activity |
| 589 | + end |
| 590 | + end |
| 591 | + |
475 | 592 | context 'when sending invalid params' do |
476 | 593 | let(:params) do |
477 | 594 | { |
|
0 commit comments