From 39c755089f291416471923725ca29abd2a0ee870 Mon Sep 17 00:00:00 2001
From: Jorge Coutinho
Date: Fri, 1 Nov 2024 13:56:03 -0300
Subject: [PATCH 01/16] add new logic for product_drive deletion
---
app/models/product_drive.rb | 4 ++++
app/views/product_drives/show.html.erb | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb
index f9a36a4b87..999694d068 100644
--- a/app/models/product_drive.rb
+++ b/app/models/product_drive.rb
@@ -69,6 +69,10 @@ def self.search_date_range(dates)
@search_date_range = { start_date: dates[0], end_date: dates[1] }
end
+ def can_delete?(user)
+ user.has_role?(Role::ORG_ADMIN, organization) && donations.empty?
+ end
+
# quantities are FILTERED by date then SORTED by name
#
# @param date_range [Range]
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index 4153457f04..da244bceb4 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,7 +90,11 @@
From 3aec94e073f2892444abc98e09e9a1e2c4678332 Mon Sep 17 00:00:00 2001
From: Jorge Coutinho
Date: Fri, 1 Nov 2024 13:56:35 -0300
Subject: [PATCH 02/16] add new tests for Product Drive system spec
---
spec/system/product_drive_system_spec.rb | 30 ++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/spec/system/product_drive_system_spec.rb b/spec/system/product_drive_system_spec.rb
index c60bc0122a..67a534e11f 100644
--- a/spec/system/product_drive_system_spec.rb
+++ b/spec/system/product_drive_system_spec.rb
@@ -130,4 +130,34 @@
expect(page).to have_content 'Endless drive'
end
end
+
+ context "when deleting a Product drive" do
+ let(:new_product_drive) { create(:product_drive, name: 'New Test', start_date: 3.weeks.ago, end_date: 3.weeks.from_now, organization: organization) }
+ let(:subject) { product_drive_path(new_product_drive.id) }
+
+ context "when user is a org_admin" do
+ before do
+ user.add_role(:org_admin, organization)
+ end
+
+ it "must delete" do
+ visit subject
+ click_on 'Delete'
+ expect(page).to have_content 'Product drive was successfully destroyed.'
+ end
+
+ it "must not delete if there are donations" do
+ create(:donation, product_drive: new_product_drive)
+ visit subject
+ expect(page).not_to have_button 'Delete'
+ end
+ end
+
+ context "when user is not a org_admin" do
+ it "must not delete" do
+ visit subject
+ expect(page).not_to have_button 'Delete'
+ end
+ end
+ end
end
From cb17ab10a371fa78fae8ded3c56f3acec5113636 Mon Sep 17 00:00:00 2001
From: Jorge Coutinho
Date: Mon, 4 Nov 2024 20:41:22 -0300
Subject: [PATCH 03/16] Implement new role verification and validation for
product drive deletion
---
app/controllers/product_drives_controller.rb | 18 +++++++++-
app/helpers/product_drive_helper.rb | 4 +++
app/models/product_drive.rb | 9 +++--
app/views/product_drives/show.html.erb | 9 +++--
spec/requests/product_drives_requests_spec.rb | 34 ++++++++++++++++---
5 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/app/controllers/product_drives_controller.rb b/app/controllers/product_drives_controller.rb
index 05e55e5dca..67c24a268d 100644
--- a/app/controllers/product_drives_controller.rb
+++ b/app/controllers/product_drives_controller.rb
@@ -1,6 +1,7 @@
class ProductDrivesController < ApplicationController
include Importable
before_action :set_product_drive, only: [:show, :edit, :update, :destroy]
+ before_action :verify_role, only: :destroy
def index
setup_date_range_picker
@@ -76,7 +77,15 @@ def update
end
def destroy
- current_organization.product_drives.find(params[:id]).destroy
+ product_drive = current_organization.product_drives.find(params[:id])
+ product_drive.destroy
+
+ if product_drive.errors.any?
+ flash[:error] = product_drive.errors.full_messages.join("\n")
+ redirect_back(fallback_location: product_drives_url)
+ return
+ end
+
respond_to do |format|
format.html { redirect_to product_drives_url, notice: 'Product drive was successfully destroyed.' }
format.json { head :no_content }
@@ -85,6 +94,13 @@ def destroy
private
+ def verify_role
+ return if current_user.has_role?(Role::ORG_ADMIN, current_organization)
+
+ flash[:error] = 'You are not allowed to perform this action.'
+ redirect_to product_drives_url
+ end
+
# Use callbacks to share common setup or constraints between actions.
def set_product_drive
@product_drive_info = ProductDrive.find(params[:id])
diff --git a/app/helpers/product_drive_helper.rb b/app/helpers/product_drive_helper.rb
index f6dd0c3784..f5b857ab81 100644
--- a/app/helpers/product_drive_helper.rb
+++ b/app/helpers/product_drive_helper.rb
@@ -4,4 +4,8 @@ def is_virtual(product_drive:)
product_drive.virtual? ? 'Yes' : 'No'
end
+
+ def can_delete_product_drive?(user, product_drive)
+ user.has_role?(Role::ORG_ADMIN, product_drive.organization) && product_drive.donations.empty?
+ end
end
diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb
index 999694d068..77353e8e27 100644
--- a/app/models/product_drive.rb
+++ b/app/models/product_drive.rb
@@ -40,6 +40,8 @@ class ProductDrive < ApplicationRecord
validate :end_date_is_bigger_of_end_date
+ before_destroy :validate_destroy, prepend: true
+
def end_date_is_bigger_of_end_date
return if start_date.nil? || end_date.nil?
@@ -69,8 +71,11 @@ def self.search_date_range(dates)
@search_date_range = { start_date: dates[0], end_date: dates[1] }
end
- def can_delete?(user)
- user.has_role?(Role::ORG_ADMIN, organization) && donations.empty?
+ def validate_destroy
+ return if donations.empty?
+
+ errors.add(:base, "Cannot delete product drive with donations.")
+ throw(:abort)
end
# quantities are FILTERED by date then SORTED by name
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index da244bceb4..f663d4cbeb 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,11 +90,10 @@
diff --git a/spec/requests/product_drives_requests_spec.rb b/spec/requests/product_drives_requests_spec.rb
index fe6f4476ea..9e5223413c 100644
--- a/spec/requests/product_drives_requests_spec.rb
+++ b/spec/requests/product_drives_requests_spec.rb
@@ -209,11 +209,37 @@
end
describe "DELETE #destroy" do
- it "redirects to the index" do
- product_drive = create(:product_drive, organization: organization)
+ let(:product_drive) { create(:product_drive, organization: organization) }
+
+ context 'when user is not a org_admin' do
+ it "does not delete the product drive" do
+ delete product_drive_path(id: product_drive.id)
+ follow_redirect!
+
+ expect(response.body).to include('You are not allowed to perform this action.')
+ end
+ end
+
+ context 'when user is a org_admin' do
+ before do
+ user.add_role(Role::ORG_ADMIN, organization)
+ end
+
+ it 'deletes the product drive' do
+ delete product_drive_path(id: product_drive.id)
+ follow_redirect!
+
+ expect(response.body).to include('Product drive was successfully destroyed.')
+ end
+
+ it "does not delete the product drive if it has donations" do
+ user.add_role(Role::ORG_ADMIN, organization)
+ create(:donation, product_drive: product_drive)
+ delete product_drive_path(id: product_drive.id)
+ follow_redirect!
- delete product_drive_path(id: product_drive.id)
- expect(response).to redirect_to(product_drives_path)
+ expect(response.body).to include('Cannot delete product drive with donations.')
+ end
end
end
end
From f7b416af05d2cd1f2500cb358c2b50bcd309420d Mon Sep 17 00:00:00 2001
From: Jorge Coutinho
Date: Mon, 4 Nov 2024 20:41:39 -0300
Subject: [PATCH 04/16] Remove product drive deletion tests from system spec
---
spec/system/product_drive_system_spec.rb | 30 ------------------------
1 file changed, 30 deletions(-)
diff --git a/spec/system/product_drive_system_spec.rb b/spec/system/product_drive_system_spec.rb
index 67a534e11f..c60bc0122a 100644
--- a/spec/system/product_drive_system_spec.rb
+++ b/spec/system/product_drive_system_spec.rb
@@ -130,34 +130,4 @@
expect(page).to have_content 'Endless drive'
end
end
-
- context "when deleting a Product drive" do
- let(:new_product_drive) { create(:product_drive, name: 'New Test', start_date: 3.weeks.ago, end_date: 3.weeks.from_now, organization: organization) }
- let(:subject) { product_drive_path(new_product_drive.id) }
-
- context "when user is a org_admin" do
- before do
- user.add_role(:org_admin, organization)
- end
-
- it "must delete" do
- visit subject
- click_on 'Delete'
- expect(page).to have_content 'Product drive was successfully destroyed.'
- end
-
- it "must not delete if there are donations" do
- create(:donation, product_drive: new_product_drive)
- visit subject
- expect(page).not_to have_button 'Delete'
- end
- end
-
- context "when user is not a org_admin" do
- it "must not delete" do
- visit subject
- expect(page).not_to have_button 'Delete'
- end
- end
- end
end
From 83976b79885ac56390a70a0eec6eeb446af73543 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 3 Jan 2025 14:29:59 -0500
Subject: [PATCH 05/16] fixed proposed changes
---
app/helpers/product_drive_helper.rb | 4 ----
app/models/product_drive.rb | 7 ++----
app/services/product_drive_destroy_service.rb | 23 +++++++++++++++++++
app/views/product_drives/show.html.erb | 6 ++---
4 files changed, 28 insertions(+), 12 deletions(-)
create mode 100644 app/services/product_drive_destroy_service.rb
diff --git a/app/helpers/product_drive_helper.rb b/app/helpers/product_drive_helper.rb
index f5b857ab81..f6dd0c3784 100644
--- a/app/helpers/product_drive_helper.rb
+++ b/app/helpers/product_drive_helper.rb
@@ -4,8 +4,4 @@ def is_virtual(product_drive:)
product_drive.virtual? ? 'Yes' : 'No'
end
-
- def can_delete_product_drive?(user, product_drive)
- user.has_role?(Role::ORG_ADMIN, product_drive.organization) && product_drive.donations.empty?
- end
end
diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb
index 77353e8e27..058d35914b 100644
--- a/app/models/product_drive.rb
+++ b/app/models/product_drive.rb
@@ -71,11 +71,8 @@ def self.search_date_range(dates)
@search_date_range = { start_date: dates[0], end_date: dates[1] }
end
- def validate_destroy
- return if donations.empty?
-
- errors.add(:base, "Cannot delete product drive with donations.")
- throw(:abort)
+ def destroy_product_drive
+ ProductDriveDestroyService.new(self).call
end
# quantities are FILTERED by date then SORTED by name
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
new file mode 100644
index 0000000000..7fbf829444
--- /dev/null
+++ b/app/services/product_drive_destroy_service.rb
@@ -0,0 +1,23 @@
+class ProductDriveDestroyService
+ def initialize(product_drive)
+ @product_drive = product_drive
+ end
+
+ def call
+ return false unless can_destroy?
+
+ # Perform destruction logic
+ @product_drive.destroy
+ end
+
+ private
+
+ def can_destroy?
+ if @product_drive.donations.empty?
+ true
+ else
+ @product_drive.errors.add(:base, "Cannot delete product drive with donations.")
+ false
+ end
+ end
+end
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index f663d4cbeb..db8414138d 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,10 +90,10 @@
From 3204abe21d11c93e6f7f512ea267fae3a8c7b543 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 10 Jan 2025 16:50:00 -0500
Subject: [PATCH 06/16] proposed changes
---
app/controllers/product_drives_controller.rb | 9 +---
app/models/product_drive.rb | 4 --
app/services/product_drive_destroy_service.rb | 46 +++++++++++++++++--
app/views/product_drives/show.html.erb | 5 +-
spec/requests/product_drives_requests_spec.rb | 34 ++------------
5 files changed, 47 insertions(+), 51 deletions(-)
diff --git a/app/controllers/product_drives_controller.rb b/app/controllers/product_drives_controller.rb
index 67c24a268d..6abe8f3064 100644
--- a/app/controllers/product_drives_controller.rb
+++ b/app/controllers/product_drives_controller.rb
@@ -1,7 +1,7 @@
class ProductDrivesController < ApplicationController
include Importable
before_action :set_product_drive, only: [:show, :edit, :update, :destroy]
- before_action :verify_role, only: :destroy
+ before_action only: :destroy
def index
setup_date_range_picker
@@ -94,13 +94,6 @@ def destroy
private
- def verify_role
- return if current_user.has_role?(Role::ORG_ADMIN, current_organization)
-
- flash[:error] = 'You are not allowed to perform this action.'
- redirect_to product_drives_url
- end
-
# Use callbacks to share common setup or constraints between actions.
def set_product_drive
@product_drive_info = ProductDrive.find(params[:id])
diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb
index 058d35914b..dd4376efbf 100644
--- a/app/models/product_drive.rb
+++ b/app/models/product_drive.rb
@@ -71,10 +71,6 @@ def self.search_date_range(dates)
@search_date_range = { start_date: dates[0], end_date: dates[1] }
end
- def destroy_product_drive
- ProductDriveDestroyService.new(self).call
- end
-
# quantities are FILTERED by date then SORTED by name
#
# @param date_range [Range]
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 7fbf829444..0ecf32491d 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -1,23 +1,59 @@
class ProductDriveDestroyService
- def initialize(product_drive)
+ attr_reader :product_drive, :user, :organization
+
+ def initialize(product_drive, user, organization)
@product_drive = product_drive
+ @user = user
+ @organization = organization
+ end
+
+ def self.call(product_drive, user, organization)
+ new(product_drive, user, organization).call
end
def call
- return false unless can_destroy?
+ return unauthorized_error unless verify_role
+ return donation_error unless can_destroy?
- # Perform destruction logic
- @product_drive.destroy
+ product_drive = organization.product_drives.find(product_drive.id)
+ product_drive.destroy
+
+ if product_drive.errors.any?
+ {
+ success: false,
+ message: product_drive.errors.full_messages.join("\n")
+ }
+ else
+ {
+ success: true,
+ message: 'Product drive was successfully destroyed.'
+ }
+ end
end
private
+ def verify_role
+ return true if user.has_role?(Role::ORG_ADMIN, @organization)
+ flash[:error] = 'You are not allowed to perform this action.'
+ redirect_to product_drives_url
+ end
+
def can_destroy?
- if @product_drive.donations.empty?
+ if product_drive.donations.empty?
true
else
@product_drive.errors.add(:base, "Cannot delete product drive with donations.")
false
end
end
+
+ def unauthorized_error
+ { success: false, message: "You are not allowed to perform this action." }
+ end
+
+ def donation_error
+ product_drive.errors.add(:base, "Cannot delete product drive with donations.")
+ { success: false, message: "Cannot delete product drive with donations." }
+ end
end
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index db8414138d..29b4f59c01 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,10 +90,7 @@
diff --git a/spec/requests/product_drives_requests_spec.rb b/spec/requests/product_drives_requests_spec.rb
index 9e5223413c..fe6f4476ea 100644
--- a/spec/requests/product_drives_requests_spec.rb
+++ b/spec/requests/product_drives_requests_spec.rb
@@ -209,37 +209,11 @@
end
describe "DELETE #destroy" do
- let(:product_drive) { create(:product_drive, organization: organization) }
-
- context 'when user is not a org_admin' do
- it "does not delete the product drive" do
- delete product_drive_path(id: product_drive.id)
- follow_redirect!
-
- expect(response.body).to include('You are not allowed to perform this action.')
- end
- end
-
- context 'when user is a org_admin' do
- before do
- user.add_role(Role::ORG_ADMIN, organization)
- end
-
- it 'deletes the product drive' do
- delete product_drive_path(id: product_drive.id)
- follow_redirect!
-
- expect(response.body).to include('Product drive was successfully destroyed.')
- end
-
- it "does not delete the product drive if it has donations" do
- user.add_role(Role::ORG_ADMIN, organization)
- create(:donation, product_drive: product_drive)
- delete product_drive_path(id: product_drive.id)
- follow_redirect!
+ it "redirects to the index" do
+ product_drive = create(:product_drive, organization: organization)
- expect(response.body).to include('Cannot delete product drive with donations.')
- end
+ delete product_drive_path(id: product_drive.id)
+ expect(response).to redirect_to(product_drives_path)
end
end
end
From 677de1252fe2720d518ee1b0ed7192f195100f38 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 10 Jan 2025 16:58:20 -0500
Subject: [PATCH 07/16] fixed ruby lint errors
---
app/services/product_drive_destroy_service.rb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 0ecf32491d..39a5c74d54 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -26,7 +26,7 @@ def call
else
{
success: true,
- message: 'Product drive was successfully destroyed.'
+ message: "Product drive was successfully destroyed."
}
end
end
@@ -35,7 +35,7 @@ def call
def verify_role
return true if user.has_role?(Role::ORG_ADMIN, @organization)
- flash[:error] = 'You are not allowed to perform this action.'
+ flash[:error] = "You are not allowed to perform this action."
redirect_to product_drives_url
end
@@ -49,11 +49,11 @@ def can_destroy?
end
def unauthorized_error
- { success: false, message: "You are not allowed to perform this action." }
+ {success: false, message: "You are not allowed to perform this action."}
end
def donation_error
product_drive.errors.add(:base, "Cannot delete product drive with donations.")
- { success: false, message: "Cannot delete product drive with donations." }
+ {success: false, message: "Cannot delete product drive with donations."}
end
end
From b0ac10f9593dcd6ff28f7de33c86da36e4d32cf3 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 10 Jan 2025 17:03:46 -0500
Subject: [PATCH 08/16] fixed error in rspec-system(6,3)
---
app/services/product_drive_destroy_service.rb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 39a5c74d54..f43fd0b732 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -35,8 +35,7 @@ def call
def verify_role
return true if user.has_role?(Role::ORG_ADMIN, @organization)
- flash[:error] = "You are not allowed to perform this action."
- redirect_to product_drives_url
+ false
end
def can_destroy?
From 045d8be942b17f198e78a62771a9e4659b610ecb Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 10 Jan 2025 17:32:35 -0500
Subject: [PATCH 09/16] replaced ProductDrivePolicy with the can destroy in
product destroy service
---
app/views/product_drives/show.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index 29b4f59c01..d5260db14c 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,7 +90,7 @@
From 018c9f42d1b5e470e11c3b931df3594e6adf1c1b Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Fri, 10 Jan 2025 18:06:50 -0500
Subject: [PATCH 10/16] changed can_destroy to class method so it is able to be
called
---
app/services/product_drive_destroy_service.rb | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index f43fd0b732..aa17bfabb9 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -13,7 +13,7 @@ def self.call(product_drive, user, organization)
def call
return unauthorized_error unless verify_role
- return donation_error unless can_destroy?
+ return donation_error unless self.class.can_destroy?(product_drive, user)
product_drive = organization.product_drives.find(product_drive.id)
product_drive.destroy
@@ -38,11 +38,13 @@ def verify_role
false
end
- def can_destroy?
+ def self.can_destroy?(product_drive, user)
+ return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
+
if product_drive.donations.empty?
true
else
- @product_drive.errors.add(:base, "Cannot delete product drive with donations.")
+ product_drive.errors.add(:base, "Cannot delete product drive with donations.")
false
end
end
From 1b8c05fa24e60a06ceb3bf07b180b9e8190a9f16 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Mon, 13 Jan 2025 15:16:13 -0500
Subject: [PATCH 11/16] fixed rubocop errors and arguments in show.html.erb
---
app/services/product_drive_destroy_service.rb | 4 ++--
app/views/product_drives/show.html.erb | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index aa17bfabb9..7b7bce706d 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -13,7 +13,7 @@ def self.call(product_drive, user, organization)
def call
return unauthorized_error unless verify_role
- return donation_error unless self.class.can_destroy?(product_drive, user)
+ return donation_error unless self.class.can_destroy?(product_drive)
product_drive = organization.product_drives.find(product_drive.id)
product_drive.destroy
@@ -38,7 +38,7 @@ def verify_role
false
end
- def self.can_destroy?(product_drive, user)
+ def can_destroy?(product_drive, user)
return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
if product_drive.donations.empty?
diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb
index d5260db14c..906c925cf4 100644
--- a/app/views/product_drives/show.html.erb
+++ b/app/views/product_drives/show.html.erb
@@ -90,7 +90,7 @@
From 4d822f3b75c12f94cdddcbaf443389a549a8ffac Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Mon, 13 Jan 2025 15:34:06 -0500
Subject: [PATCH 12/16] attempted to fixes, made can_destroy class method ot
make it a class method
---
app/services/product_drive_destroy_service.rb | 25 +++++++++++--------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 7b7bce706d..7dfc12486e 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -11,9 +11,14 @@ def self.call(product_drive, user, organization)
new(product_drive, user, organization).call
end
+ def self.can_destroy?(product_drive, user)
+ return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
+ product_drive.donations.empty?
+ end
+
def call
return unauthorized_error unless verify_role
- return donation_error unless self.class.can_destroy?(product_drive)
+ return donation_error unless self.class.can_destroy?(product_drive, user)
product_drive = organization.product_drives.find(product_drive.id)
product_drive.destroy
@@ -38,16 +43,16 @@ def verify_role
false
end
- def can_destroy?(product_drive, user)
- return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
+ # def can_destroy?(product_drive, user)
+ # return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
- if product_drive.donations.empty?
- true
- else
- product_drive.errors.add(:base, "Cannot delete product drive with donations.")
- false
- end
- end
+ # if product_drive.donations.empty?
+ # true
+ # else
+ # product_drive.errors.add(:base, "Cannot delete product drive with donations.")
+ # false
+ # end
+ # end
def unauthorized_error
{success: false, message: "You are not allowed to perform this action."}
From 542a1e75317eca658ec74d9475b3b6b3ba124597 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Mon, 13 Jan 2025 15:58:49 -0500
Subject: [PATCH 13/16] removed redundant operation as product_drive is already
accessible
---
app/services/product_drive_destroy_service.rb | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 7dfc12486e..f3b9ebf679 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -20,7 +20,6 @@ def call
return unauthorized_error unless verify_role
return donation_error unless self.class.can_destroy?(product_drive, user)
- product_drive = organization.product_drives.find(product_drive.id)
product_drive.destroy
if product_drive.errors.any?
From cbb18ec05bc721be5cdc90068ec1d75e92511bed Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Mon, 13 Jan 2025 16:06:08 -0500
Subject: [PATCH 14/16] no longer destroying in controller
---
app/controllers/product_drives_controller.rb | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/app/controllers/product_drives_controller.rb b/app/controllers/product_drives_controller.rb
index 6abe8f3064..7260bdd299 100644
--- a/app/controllers/product_drives_controller.rb
+++ b/app/controllers/product_drives_controller.rb
@@ -77,18 +77,13 @@ def update
end
def destroy
- product_drive = current_organization.product_drives.find(params[:id])
- product_drive.destroy
+ result = ProductDriveDestroyService.call(@product_drive, current_user, current_organization)
- if product_drive.errors.any?
- flash[:error] = product_drive.errors.full_messages.join("\n")
+ if result[:success]
+ redirect_to product_drives_url, notice: result[:message]
+ else
+ flash[:error] = result[:message]
redirect_back(fallback_location: product_drives_url)
- return
- end
-
- respond_to do |format|
- format.html { redirect_to product_drives_url, notice: 'Product drive was successfully destroyed.' }
- format.json { head :no_content }
end
end
From e8edee3e82ec768a0c7d5fcdced2a2b795c0aa52 Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Thu, 16 Jan 2025 14:57:02 -0500
Subject: [PATCH 15/16] updated code based on requested changes
---
app/controllers/product_drives_controller.rb | 7 +-
app/models/product_drive.rb | 2 -
app/services/product_drive_destroy_service.rb | 75 +++++--------------
3 files changed, 21 insertions(+), 63 deletions(-)
diff --git a/app/controllers/product_drives_controller.rb b/app/controllers/product_drives_controller.rb
index 7260bdd299..c7be796378 100644
--- a/app/controllers/product_drives_controller.rb
+++ b/app/controllers/product_drives_controller.rb
@@ -1,7 +1,6 @@
class ProductDrivesController < ApplicationController
include Importable
before_action :set_product_drive, only: [:show, :edit, :update, :destroy]
- before_action only: :destroy
def index
setup_date_range_picker
@@ -79,10 +78,10 @@ def update
def destroy
result = ProductDriveDestroyService.call(@product_drive, current_user, current_organization)
- if result[:success]
- redirect_to product_drives_url, notice: result[:message]
+ if result.success?
+ redirect_to product_drives_url, notice: result.value
else
- flash[:error] = result[:message]
+ flash[:error] = result.error
redirect_back(fallback_location: product_drives_url)
end
end
diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb
index dd4376efbf..f9a36a4b87 100644
--- a/app/models/product_drive.rb
+++ b/app/models/product_drive.rb
@@ -40,8 +40,6 @@ class ProductDrive < ApplicationRecord
validate :end_date_is_bigger_of_end_date
- before_destroy :validate_destroy, prepend: true
-
def end_date_is_bigger_of_end_date
return if start_date.nil? || end_date.nil?
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index f3b9ebf679..978679d00e 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -1,64 +1,25 @@
class ProductDriveDestroyService
- attr_reader :product_drive, :user, :organization
-
- def initialize(product_drive, user, organization)
- @product_drive = product_drive
- @user = user
- @organization = organization
- end
-
- def self.call(product_drive, user, organization)
- new(product_drive, user, organization).call
- end
-
- def self.can_destroy?(product_drive, user)
- return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
- product_drive.donations.empty?
- end
-
- def call
- return unauthorized_error unless verify_role
- return donation_error unless self.class.can_destroy?(product_drive, user)
-
- product_drive.destroy
-
- if product_drive.errors.any?
- {
- success: false,
- message: product_drive.errors.full_messages.join("\n")
- }
- else
- {
- success: true,
- message: "Product drive was successfully destroyed."
- }
+ class << self
+ def call(product_drive, user, organization)
+ return Result.new(error: "You are not allowed to perform this action.") unless verify_role(user, organization)
+ return Result.new(error: "Cannot delete product drive with donations.") unless can_destroy?(product_drive, user)
+
+ if product_drive.destroy
+ Result.new(value: "Product drive was successfully destroyed.")
+ else
+ Result.new(error: product_drive.errors.full_messages.join("\n"))
+ end
end
- end
-
- private
-
- def verify_role
- return true if user.has_role?(Role::ORG_ADMIN, @organization)
- false
- end
- # def can_destroy?(product_drive, user)
- # return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
-
- # if product_drive.donations.empty?
- # true
- # else
- # product_drive.errors.add(:base, "Cannot delete product drive with donations.")
- # false
- # end
- # end
+ def can_destroy?(product_drive, user)
+ return false unless user.has_role?(Role::ORG_ADMIN, product_drive.organization)
+ product_drive.donations.empty?
+ end
- def unauthorized_error
- {success: false, message: "You are not allowed to perform this action."}
- end
+ private
- def donation_error
- product_drive.errors.add(:base, "Cannot delete product drive with donations.")
- {success: false, message: "Cannot delete product drive with donations."}
+ def verify_role(user, organization)
+ user.has_role?(Role::ORG_ADMIN, organization)
+ end
end
end
From 21cf464a628b9fbcc102d263546e56f427dda6ad Mon Sep 17 00:00:00 2001
From: michascant <89426143+MichaScant@users.noreply.github.com>
Date: Thu, 16 Jan 2025 15:21:42 -0500
Subject: [PATCH 16/16] throwing errors in destroy service at times now as test
expects it
---
app/services/product_drive_destroy_service.rb | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/app/services/product_drive_destroy_service.rb b/app/services/product_drive_destroy_service.rb
index 978679d00e..ea6533bc90 100644
--- a/app/services/product_drive_destroy_service.rb
+++ b/app/services/product_drive_destroy_service.rb
@@ -2,12 +2,16 @@ class ProductDriveDestroyService
class << self
def call(product_drive, user, organization)
return Result.new(error: "You are not allowed to perform this action.") unless verify_role(user, organization)
- return Result.new(error: "Cannot delete product drive with donations.") unless can_destroy?(product_drive, user)
+
+ unless can_destroy?(product_drive, user)
+ product_drive.errors.add(:base, "Cannot delete product drive with donations.")
+ raise ActiveRecord::RecordInvalid.new(product_drive)
+ end
if product_drive.destroy
Result.new(value: "Product drive was successfully destroyed.")
else
- Result.new(error: product_drive.errors.full_messages.join("\n"))
+ raise ActiveRecord::RecordNotDestroyed.new("Failed to destroy product drive", product_drive)
end
end