Class: PlanMyStuff::TestingProjectItem

Inherits:
BaseProjectItem show all
Defined in:
lib/plan_my_stuff/testing_project_item.rb

Overview

A project item belonging to a TestingProject. Extends BaseProjectItem with testing-specific field updaters and pass/fail sign-off logic.

Constant Summary collapse

DEFAULT_STATUS =

Default “Test Status” applied to newly-created testing items so they do not land in GitHub’s blank-status lane.

'Todo'
DEFAULT_PASS_MODE =

Default “Pass Mode” applied to newly-created testing items so sign-off semantics are defined up front (every tester must pass).

'all'

Instance Attribute Summary

Attributes inherited from ApplicationRecord

#github_response

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseProjectItem

#as_json, assign, #assign!, #body, build, #content_node_id, delete_item, #destroy!, #draft?, #field_values, #id, #issue, #issue=, #metadata, move_item, #move_to!, #number, #project, #raw_body, #repo, #state, #status, #title, #type, update_date_field!, update_field!, #update_field!, update_single_select_field!, #url

Methods inherited from ApplicationRecord

#destroyed?, #initialize, #new_record?, #persisted?, read_field

Constructor Details

This class inherits a constructor from PlanMyStuff::ApplicationRecord

Class Method Details

.create!(issue_or_title, draft: false, body: nil, project_number: nil, user: nil) ⇒ Object

Sets Test Status to DEFAULT_STATUS on the new item so it lands in the Todo column rather than the blank-status lane. Uses move_item directly (not item.move_to!) so the initial status does not fire a spurious project_item.status_changed event.

Also seeds Pass Mode to DEFAULT_PASS_MODE so sign-off semantics are defined from item creation forward.

See Also:

  • super


26
27
28
29
30
31
32
33
34
35
36
# File 'lib/plan_my_stuff/testing_project_item.rb', line 26

def create!(issue_or_title, draft: false, body: nil, project_number: nil, user: nil)
  item = super
  move_item(project_number: item.project.number, item_id: item.id, status: DEFAULT_STATUS)
  update_single_select_field!(
    project_number: item.project.number,
    item_id: item.id,
    field_name: 'Pass Mode',
    value: DEFAULT_PASS_MODE,
  )
  item
end

Instance Method Details

#mark_failed!(user, result_notes:) ⇒ void

This method returns an undefined value.

Records user_id as having failed this item, writes result_notes, and moves the item to the Failed status.

Parameters:

  • user (Object)

    PMS user object of the tester failing the item

  • result_notes (String)

    required explanation of the failure

Raises:



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/plan_my_stuff/testing_project_item.rb', line 168

def mark_failed!(user, result_notes:)
  raise(PMS::ValidationError, 'Result notes are required when failing an item.') if result_notes.blank?
  raise(PMS::ValidationError, 'No user configured for sign-off.') if user.blank?

  update_result_notes!(result_notes)

  user_id = PMS::UserResolver.user_id(user).to_s
  current = user_ids_from_field('Failed By')
  return if current.include?(user_id)

  new_failed_by = current + [user_id]
  update_failed_by!(new_failed_by)
  field_values['Failed By'] = new_failed_by.join(', ')

  move_to!('Failed')
end

#mark_passed!(user) ⇒ void

This method returns an undefined value.

Appends user_id to the Passed By field and, when the pass_mode condition is satisfied, moves the item to the Passed status.

pass_mode “all” - flips to Passed when every tester has signed off. pass_mode “any” - flips to Passed as soon as one tester signs off.

No-op when the user has already signed off on this item.

Parameters:

  • user (Object)

    PMS user object of the tester signing off

Raises:



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
# File 'lib/plan_my_stuff/testing_project_item.rb', line 131

def mark_passed!(user)
  raise(PMS::ValidationError, 'No user configured for sign-off.') if user.blank?

  user_id = PMS::UserResolver.user_id(user).to_s
  current = user_ids_from_field('Passed By')
  return if current.include?(user_id)

  new_passed_by = current + [user_id]
  update_passed_by!(new_passed_by)
  field_values['Passed By'] = new_passed_by.join(', ')

  testers = user_ids_from_field('Testers')
  pass_mode = field_values['Pass Mode']

  should_pass =
    case pass_mode
    when 'any' then true
    when 'all' then new_passed_by.sort == testers.sort
    else false
    end

  return unless should_pass

  update_passed_at!(Time.now.utc)
  move_to!('Passed')
end

#update_deadline_miss_reason!(reason) ⇒ Hash

Updates the Deadline Miss Reason field on this testing project item.

Parameters:

  • reason (String)

Returns:

  • (Hash)

    mutation result



115
116
117
# File 'lib/plan_my_stuff/testing_project_item.rb', line 115

def update_deadline_miss_reason!(reason)
  update_field!('Deadline Miss Reason', reason)
end

#update_due_date!(date) ⇒ Hash

Updates the due date field on this testing project item.

Parameters:

  • date (Date, String)

Returns:

  • (Hash)

    mutation result



60
61
62
63
64
65
66
67
# File 'lib/plan_my_stuff/testing_project_item.rb', line 60

def update_due_date!(date)
  self.class.update_date_field!(
    project_number: project.number,
    item_id: id,
    field_name: 'Due Date',
    date: date,
  )
end

#update_pass_mode!(value) ⇒ Hash

Updates the Pass Mode single-select field on this testing project item.

Parameters:

  • value (String)

    “all” or “any”

Returns:

  • (Hash)

    mutation result



45
46
47
48
49
50
51
52
# File 'lib/plan_my_stuff/testing_project_item.rb', line 45

def update_pass_mode!(value)
  self.class.update_single_select_field!(
    project_number: project.number,
    item_id: id,
    field_name: 'Pass Mode',
    value: value,
  )
end

#update_passed_at!(time) ⇒ Hash

Records the timestamp when this item was passed as an ISO 8601 string.

Parameters:

  • time (Time)

Returns:

  • (Hash)

    mutation result



105
106
107
# File 'lib/plan_my_stuff/testing_project_item.rb', line 105

def update_passed_at!(time)
  update_field!('Passed At', time.utc.iso8601)
end

#update_result_notes!(notes) ⇒ Hash

Updates the Result Notes field on this testing project item.

Parameters:

  • notes (String)

Returns:

  • (Hash)

    mutation result



95
96
97
# File 'lib/plan_my_stuff/testing_project_item.rb', line 95

def update_result_notes!(notes)
  update_field!('Result Notes', notes)
end

#update_testers!(user_ids) ⇒ Hash

Updates the Testers field (comma-joined user IDs) on this item.

Parameters:

  • user_ids (Integer, String, Array<Integer, String>)

Returns:

  • (Hash)

    mutation result



75
76
77
# File 'lib/plan_my_stuff/testing_project_item.rb', line 75

def update_testers!(user_ids)
  update_field!('Testers', Array.wrap(user_ids).join(', '))
end

#update_watchers!(user_ids) ⇒ Hash

Updates the Watchers field (comma-joined user IDs) on this item.

Parameters:

  • user_ids (Integer, String, Array<Integer, String>)

Returns:

  • (Hash)

    mutation result



85
86
87
# File 'lib/plan_my_stuff/testing_project_item.rb', line 85

def update_watchers!(user_ids)
  update_field!('Watchers', Array.wrap(user_ids).join(', '))
end