plan_my_stuff 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cf33c92cfa763f5ace87a1419cf8c7369f27e8adc10d1c092c044b99d151a4a
4
- data.tar.gz: 3b2a482534b9f9094d550385c064f50f4dc37db3c2a6361e4aa899d4b4dc5713
3
+ metadata.gz: 64667e99c4a5b732a987a483072636d81c8d36840433feaf83f4d89b71f96934
4
+ data.tar.gz: 4675d511991935756e77c8730c57588bcbea68fd48acecfc67753c2062cd48ab
5
5
  SHA512:
6
- metadata.gz: ef36dbcfb77d4c3763d2165993c50fb9f4f7e8b0729a1efc1d63fb9155abb039bf9db92fb59a49d3302ebfec024bafc19dd15b54be84a2d7919040405a10803f
7
- data.tar.gz: beae8f4926a95e4a47786c4ffefc886300f255466d7e08a7e607f444e91883e920b3bf60d666d33b539eed2dac7a1241f64cd23ae42ebe292a8a113ce150de8d
6
+ metadata.gz: 2393fea9842e2c1ee5656f4123416933b0021ba5fcdf80962ddc1e15ea72f12682dbd353cde0f8931066eb2a656be4a34bcf8a6c7ab886e200c52df66c30876b
7
+ data.tar.gz: 3aea3806e8ca62fc0de5bf2b94544f0cb5888c3a20a224e8104b85f4d99095715d845e4509a80930c9eb2d9652a16b05151c659b53b19eda3e8f77ce6b5e7bb6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Added
6
+
7
+ - `PlanMyStuff::Pipeline.clear_testing!(project_item, user: nil)` - reverses `request_testing!` by writing the
8
+ `:inactive` Testing field value. Fires `pipeline_testing_cleared.plan_my_stuff` with `field_name`, `value`,
9
+ `user` payload.
10
+ - `PlanMyStuff::Issues::TestingsController` + `POST/DELETE /issues/:issue_id/testing` route (gated on
11
+ `config.pipeline_enabled`). Backs new "Request testing" / "Clear testing" buttons on the issue show view
12
+ (closes #52).
13
+
3
14
  ## 0.24.0
4
15
 
5
16
  ### Added
data/CONFIGURATION.md CHANGED
@@ -392,6 +392,7 @@ Controllable keys (with gem defaults):
392
392
  | `:'issues/closures'` | `plan_my_stuff/issues/closures` |
393
393
  | `:'issues/viewers'` | `plan_my_stuff/issues/viewers` |
394
394
  | `:'issues/takes'` | `plan_my_stuff/issues/takes` |
395
+ | `:'issues/testings'` | `plan_my_stuff/issues/testings` |
395
396
  | `:'issues/waitings'` | `plan_my_stuff/issues/waitings` |
396
397
  | `:'issues/links'` | `plan_my_stuff/issues/links` |
397
398
  | `:'issues/approvals'` | `plan_my_stuff/issues/approvals` |
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlanMyStuff
4
+ module Issues
5
+ # Toggles the pipeline +Testing+ custom field on an issue's project item via
6
+ # +PlanMyStuff::Pipeline.request_testing!+ and +PlanMyStuff::Pipeline.clear_testing!+. Backs the "Request testing" /
7
+ # "Clear testing" buttons on the mounted issue show view.
8
+ #
9
+ # POST /issues/:issue_id/testing -> create (flips +Testing+ to its active value)
10
+ # DELETE /issues/:issue_id/testing -> destroy (flips +Testing+ back to inactive)
11
+ #
12
+ class TestingsController < PlanMyStuff::ApplicationController
13
+ before_action :require_support_user
14
+
15
+ # POST /issues/:issue_id/testing
16
+ def create
17
+ issue = PlanMyStuff::Issue.find(params[:issue_id])
18
+ project_item = find_project_item!(issue)
19
+
20
+ PlanMyStuff::Pipeline.request_testing!(project_item, user: pms_current_user)
21
+
22
+ yield(project_item) if block_given?
23
+ return if performed?
24
+
25
+ flash[:success] = "Issue ##{issue.number} marked as in testing."
26
+ redirect_to(plan_my_stuff.issue_path(issue))
27
+ rescue ArgumentError, PlanMyStuff::Error => e
28
+ pms_handle_rescue(e)
29
+ flash[:error] = e.message
30
+ redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
31
+ end
32
+
33
+ # DELETE /issues/:issue_id/testing
34
+ def destroy
35
+ issue = PlanMyStuff::Issue.find(params[:issue_id])
36
+ project_item = find_project_item!(issue)
37
+
38
+ PlanMyStuff::Pipeline.clear_testing!(project_item, user: pms_current_user)
39
+
40
+ yield(project_item) if block_given?
41
+ return if performed?
42
+
43
+ flash[:success] = "Issue ##{issue.number} testing cleared."
44
+ redirect_to(plan_my_stuff.issue_path(issue))
45
+ rescue ArgumentError, PlanMyStuff::Error => e
46
+ pms_handle_rescue(e)
47
+ flash[:error] = e.message
48
+ redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
49
+ end
50
+
51
+ private
52
+
53
+ # Redirects non-support users back to the issue page. Mirrors +Issues::TakesController+'s authorization check.
54
+ #
55
+ # @return [void]
56
+ #
57
+ def require_support_user
58
+ return if support_user?
59
+
60
+ redirect_to_unauthorized(
61
+ plan_my_stuff.issue_path(params[:issue_id]),
62
+ )
63
+ end
64
+
65
+ # Looks up the pipeline project item for the issue, raising if missing. Defensive against a stale view (button
66
+ # rendered before the item was removed) or a race with another tab removing the issue from the pipeline.
67
+ #
68
+ # @raise [PlanMyStuff::Error] if the issue is not in the pipeline
69
+ #
70
+ # @param issue [PlanMyStuff::Issue]
71
+ #
72
+ # @return [PlanMyStuff::ProjectItem]
73
+ #
74
+ def find_project_item!(issue)
75
+ project_item = PlanMyStuff::Pipeline::IssueLinker.find_project_item(issue.number)
76
+ return project_item if project_item.present?
77
+
78
+ raise(PlanMyStuff::Error, "Issue ##{issue.number} is not in the pipeline.")
79
+ end
80
+ end
81
+ end
82
+ end
@@ -20,9 +20,24 @@
20
20
  <% if @support_user && @pipeline_enabled && @pipeline_item.nil? && @issue.assignees.blank? %>
21
21
  <%= button_to('Take', plan_my_stuff.issue_take_path(@issue), method: :post) %>
22
22
  <% end %>
23
- <% if @support_user && @pipeline_enabled && @current_user_login.present? && @issue.assignees.include?(@current_user_login) %>
23
+ <%
24
+ show_unassign =
25
+ @support_user &&
26
+ @pipeline_enabled &&
27
+ @current_user_login.present? &&
28
+ @issue.assignees.include?(@current_user_login)
29
+ %>
30
+ <% if show_unassign %>
24
31
  <%= button_to('Unassign', plan_my_stuff.issue_take_path(@issue), method: :delete) %>
25
32
  <% end %>
33
+ <% if @support_user && @pipeline_enabled && @pipeline_item.present? %>
34
+ <% testing_value = @pipeline_item.field_values[PlanMyStuff.configuration.pipeline_testing_field_name] %>
35
+ <% if testing_value == PlanMyStuff.configuration.pipeline_testing_values[:active] %>
36
+ <%= button_to('Clear testing', plan_my_stuff.issue_testing_path(@issue), method: :delete) %>
37
+ <% else %>
38
+ <%= button_to('Request testing', plan_my_stuff.issue_testing_path(@issue), method: :post) %>
39
+ <% end %>
40
+ <% end %>
26
41
  <% if @support_user %>
27
42
  <%= link_to('Start Testing Project', plan_my_stuff.new_testing_project_path(subject_url: @issue.html_url)) %>
28
43
  <% end %>
data/config/routes.rb CHANGED
@@ -15,6 +15,11 @@ PlanMyStuff::Engine.routes.draw do
15
15
  only: %i[create destroy],
16
16
  controller: config.controller_for(:'issues/takes'),
17
17
  )
18
+ resource(
19
+ :testing,
20
+ only: %i[create destroy],
21
+ controller: config.controller_for(:'issues/testings'),
22
+ )
18
23
  end
19
24
  resources :comments, only: %i[create edit update], controller: config.controller_for(:comments)
20
25
  resources :labels, only: %i[create destroy], controller: config.controller_for(:labels)
@@ -348,6 +348,7 @@ PlanMyStuff.configure do |config|
348
348
  # :'issues/closures' => 'plan_my_stuff/issues/closures'
349
349
  # :'issues/viewers' => 'plan_my_stuff/issues/viewers'
350
350
  # :'issues/takes' => 'plan_my_stuff/issues/takes'
351
+ # :'issues/testings' => 'plan_my_stuff/issues/testings'
351
352
  # :'issues/waitings' => 'plan_my_stuff/issues/waitings'
352
353
  # :'issues/links' => 'plan_my_stuff/issues/links'
353
354
  # :'issues/approvals' => 'plan_my_stuff/issues/approvals'
@@ -18,6 +18,7 @@ module PlanMyStuff
18
18
  'issues/closures': 'plan_my_stuff/issues/closures',
19
19
  'issues/viewers': 'plan_my_stuff/issues/viewers',
20
20
  'issues/takes': 'plan_my_stuff/issues/takes',
21
+ 'issues/testings': 'plan_my_stuff/issues/testings',
21
22
  'issues/waitings': 'plan_my_stuff/issues/waitings',
22
23
  'issues/links': 'plan_my_stuff/issues/links',
23
24
  'issues/approvals': 'plan_my_stuff/issues/approvals',
@@ -200,6 +200,25 @@ module PlanMyStuff
200
200
  result
201
201
  end
202
202
 
203
+ # Reverses +request_testing!+ by flipping the +Testing+ custom single-select field back to its inactive value.
204
+ # Not approval-gated -- the forward transition (+request_testing!+) was already gated, so clearing should always
205
+ # succeed (matches +remove!+).
206
+ #
207
+ # @param project_item [PlanMyStuff::ProjectItem]
208
+ # @param user [Object, nil] actor forwarded to the +pipeline_testing_cleared.plan_my_stuff+ payload
209
+ #
210
+ # @return [Hash] mutation result
211
+ #
212
+ def clear_testing!(project_item, user: nil)
213
+ field_name = PlanMyStuff.configuration.pipeline_testing_field_name
214
+ value = PlanMyStuff.configuration.pipeline_testing_values.fetch(:inactive)
215
+ result = project_item.update_single_select_field!(field_name, value)
216
+
217
+ instrument('testing_cleared', project_item, field_name: field_name, value: value, user: user)
218
+
219
+ result
220
+ end
221
+
203
222
  # Moves a project item to "Ready for Release".
204
223
  #
205
224
  # @param project_item [PlanMyStuff::ProjectItem]
@@ -3,7 +3,7 @@
3
3
  module PlanMyStuff
4
4
  module VERSION
5
5
  MAJOR = 0
6
- MINOR = 24
6
+ MINOR = 25
7
7
  TINY = 0
8
8
 
9
9
  # Set PRE to nil unless it's a pre-release (beta, rc, etc.)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plan_my_stuff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.0
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brands Insurance
@@ -61,6 +61,7 @@ files:
61
61
  - app/controllers/plan_my_stuff/issues/closures_controller.rb
62
62
  - app/controllers/plan_my_stuff/issues/links_controller.rb
63
63
  - app/controllers/plan_my_stuff/issues/takes_controller.rb
64
+ - app/controllers/plan_my_stuff/issues/testings_controller.rb
64
65
  - app/controllers/plan_my_stuff/issues/viewers_controller.rb
65
66
  - app/controllers/plan_my_stuff/issues/waitings_controller.rb
66
67
  - app/controllers/plan_my_stuff/issues_controller.rb