Commit aeea7a72 authored by Sean Arnold's avatar Sean Arnold

Use active period type, local ActivePeriod class

- Update specs, graphql types and docs
parent 38ddae95
...@@ -2096,8 +2096,7 @@ Describes an incident management on-call rotation. ...@@ -2096,8 +2096,7 @@ Describes an incident management on-call rotation.
| Field | Type | Description | | Field | Type | Description |
| ----- | ---- | ----------- | | ----- | ---- | ----------- |
| `activePeriodEnd` | String | Active period end time for the on-call rotation. | | `activePeriod` | OncallRotationActivePeriodType | Active period for the on-call rotation. |
| `activePeriodStart` | String | Active period start time for the on-call rotation. |
| `endsAt` | Time | End date and time of the on-call rotation. | | `endsAt` | Time | End date and time of the on-call rotation. |
| `id` | IncidentManagementOncallRotationID! | ID of the on-call rotation. | | `id` | IncidentManagementOncallRotationID! | ID of the on-call rotation. |
| `length` | Int | Length of the on-call schedule, in the units specified by lengthUnit. | | `length` | Int | Length of the on-call schedule, in the units specified by lengthUnit. |
...@@ -2805,6 +2804,15 @@ The rotation participant and color palette. ...@@ -2805,6 +2804,15 @@ The rotation participant and color palette.
| `id` | IncidentManagementOncallParticipantID! | ID of the on-call participant. | | `id` | IncidentManagementOncallParticipantID! | ID of the on-call participant. |
| `user` | User! | The user who is participating. | | `user` | User! | The user who is participating. |
### OncallRotationActivePeriodType
Active period time range for on-call rotation.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `from` | String | The start of the rotation interval. |
| `to` | String | The end of the rotation interval. |
### OncallRotationCreatePayload ### OncallRotationCreatePayload
Autogenerated return type of OncallRotationCreate. Autogenerated return type of OncallRotationCreate.
......
...@@ -4,7 +4,7 @@ module Types ...@@ -4,7 +4,7 @@ module Types
module IncidentManagement module IncidentManagement
# rubocop: disable Graphql/AuthorizeTypes # rubocop: disable Graphql/AuthorizeTypes
class OncallRotationActivePeriodInputType < BaseInputObject class OncallRotationActivePeriodInputType < BaseInputObject
graphql_name 'OncallRotationActivePeriodType' graphql_name 'OncallRotationActivePeriodInputType'
description 'Active period time range for on-call rotation' description 'Active period time range for on-call rotation'
argument :from, GraphQL::STRING_TYPE, argument :from, GraphQL::STRING_TYPE,
......
# frozen_string_literal: true
module Types
module IncidentManagement
# rubocop: disable Graphql/AuthorizeTypes
class OncallRotationActivePeriodType < BaseObject
graphql_name 'OncallRotationActivePeriodType'
description 'Active period time range for on-call rotation'
field :from, GraphQL::STRING_TYPE,
null: true,
description: 'The start of the rotation interval.',
method: :start_time
field :to, GraphQL::STRING_TYPE,
null: true,
description: 'The end of the rotation interval.',
method: :end_time
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
...@@ -38,15 +38,10 @@ module Types ...@@ -38,15 +38,10 @@ module Types
null: true, null: true,
description: 'Unit of the on-call rotation length.' description: 'Unit of the on-call rotation length.'
field :active_period_start, field :active_period,
GraphQL::STRING_TYPE, Types::IncidentManagement::OncallRotationActivePeriodType,
null: true,
description: 'Active period start time for the on-call rotation.'
field :active_period_end,
GraphQL::STRING_TYPE,
null: true, null: true,
description: 'Active period end time for the on-call rotation.' description: 'Active period for the on-call rotation.'
field :participants, field :participants,
::Types::IncidentManagement::OncallParticipantType.connection_type, ::Types::IncidentManagement::OncallParticipantType.connection_type,
......
...@@ -4,6 +4,23 @@ module IncidentManagement ...@@ -4,6 +4,23 @@ module IncidentManagement
class OncallRotation < ApplicationRecord class OncallRotation < ApplicationRecord
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
ActivePeriod = Struct.new(:start_time, :end_time) do
def present?
start_time && end_time
end
def end_after_start?
end_time > start_time if present?
end
def for_date(date)
[
date.change(hour: start_time.hour, min: start_time.min),
date.change(hour: end_time.hour, min: end_time.min)
]
end
end
self.table_name = 'incident_management_oncall_rotations' self.table_name = 'incident_management_oncall_rotations'
enum length_unit: { enum length_unit: {
...@@ -59,28 +76,12 @@ module IncidentManagement ...@@ -59,28 +76,12 @@ module IncidentManagement
weeks? ? (7 * length) : length weeks? ? (7 * length) : length
end end
def has_shift_active_period? def active_period
return false if hours? ActivePeriod.new(active_period_start, active_period_end)
active_period_start.present?
end
def active_period_times
return unless has_shift_active_period?
strong_memoize(:active_period_times) do
{
start: active_period_start,
end: active_period_end
}
end
end end
def active_period(date) def has_shift_active_period?
[ !hours? && active_period.present?
date.change(hour: active_period_times[:start].hour, min: active_period_times[:start].min),
date.change(hour: active_period_times[:end].hour, min: active_period_times[:end].min)
]
end end
private private
...@@ -90,12 +91,11 @@ module IncidentManagement ...@@ -90,12 +91,11 @@ module IncidentManagement
end end
def active_period_end_after_start def active_period_end_after_start
return unless active_period_start && active_period_end return unless active_period.present?
return if active_period.end_after_start?
unless active_period_end > active_period_start
errors.add(:active_period_end, _('must be later than active period start')) errors.add(:active_period_end, _('must be later than active period start'))
end end
end
def no_active_period_for_hourly_shifts def no_active_period_for_hourly_shifts
if active_period_start || active_period_end if active_period_start || active_period_end
......
...@@ -130,7 +130,7 @@ module IncidentManagement ...@@ -130,7 +130,7 @@ module IncidentManagement
# shift_count = 2 -> we're calculating the shift for the 3rd day # shift_count = 2 -> we're calculating the shift for the 3rd day
# starts_at = Monday 00:00:00 + 8.hours + 2.days => Thursday 08:00:00 # starts_at = Monday 00:00:00 + 8.hours + 2.days => Thursday 08:00:00
starts_at, ends_at = rotation.active_period(shift_cycle_starts_at + shift_count.days) starts_at, ends_at = rotation.active_period.for_date(shift_cycle_starts_at + shift_count.days)
shift_for(participant, starts_at, limit_end_time(ends_at)) shift_for(participant, starts_at, limit_end_time(ends_at))
end end
......
...@@ -16,8 +16,7 @@ RSpec.describe GitlabSchema.types['IncidentManagementOncallRotation'] do ...@@ -16,8 +16,7 @@ RSpec.describe GitlabSchema.types['IncidentManagementOncallRotation'] do
length length
length_unit length_unit
participants participants
active_period_start active_period
active_period_end
shifts shifts
] ]
......
...@@ -83,7 +83,7 @@ RSpec.describe IncidentManagement::OncallRotation do ...@@ -83,7 +83,7 @@ RSpec.describe IncidentManagement::OncallRotation do
end end
end end
context 'end time after start time' do context 'end time before start time' do
it 'raises a validation error if an active period is set' do it 'raises a validation error if an active period is set' do
subject.active_period_start = '17:00' subject.active_period_start = '17:00'
subject.active_period_end = '08:00' subject.active_period_end = '08:00'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment