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.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `activePeriodEnd` | String | Active period end time for the on-call rotation. |
| `activePeriodStart` | String | Active period start time for the on-call rotation. |
| `activePeriod` | OncallRotationActivePeriodType | Active period for the on-call rotation. |
| `endsAt` | Time | End date and time 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. |
......@@ -2805,6 +2804,15 @@ The rotation participant and color palette.
| `id` | IncidentManagementOncallParticipantID! | ID of the on-call participant. |
| `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
Autogenerated return type of OncallRotationCreate.
......
......@@ -4,7 +4,7 @@ module Types
module IncidentManagement
# rubocop: disable Graphql/AuthorizeTypes
class OncallRotationActivePeriodInputType < BaseInputObject
graphql_name 'OncallRotationActivePeriodType'
graphql_name 'OncallRotationActivePeriodInputType'
description 'Active period time range for on-call rotation'
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
null: true,
description: 'Unit of the on-call rotation length.'
field :active_period_start,
GraphQL::STRING_TYPE,
null: true,
description: 'Active period start time for the on-call rotation.'
field :active_period_end,
GraphQL::STRING_TYPE,
field :active_period,
Types::IncidentManagement::OncallRotationActivePeriodType,
null: true,
description: 'Active period end time for the on-call rotation.'
description: 'Active period for the on-call rotation.'
field :participants,
::Types::IncidentManagement::OncallParticipantType.connection_type,
......
......@@ -4,6 +4,23 @@ module IncidentManagement
class OncallRotation < ApplicationRecord
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'
enum length_unit: {
......@@ -59,28 +76,12 @@ module IncidentManagement
weeks? ? (7 * length) : length
end
def has_shift_active_period?
return false if hours?
active_period_start.present?
def active_period
ActivePeriod.new(active_period_start, active_period_end)
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
def active_period(date)
[
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)
]
def has_shift_active_period?
!hours? && active_period.present?
end
private
......@@ -90,11 +91,10 @@ module IncidentManagement
end
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'))
end
errors.add(:active_period_end, _('must be later than active period start'))
end
def no_active_period_for_hourly_shifts
......
......@@ -130,7 +130,7 @@ module IncidentManagement
# 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, 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))
end
......
......@@ -16,8 +16,7 @@ RSpec.describe GitlabSchema.types['IncidentManagementOncallRotation'] do
length
length_unit
participants
active_period_start
active_period_end
active_period
shifts
]
......
......@@ -83,7 +83,7 @@ RSpec.describe IncidentManagement::OncallRotation do
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
subject.active_period_start = '17: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