require 'rails_helper'
RSpec.describe Admin::SignaturesController, type: :controller, admin: true do
let!(:petition) { FactoryBot.create(:open_petition) }
let!(:signature) { FactoryBot.create(:validated_signature, petition: petition, email: "user@example.com") }
context "not logged in" do -
describe "GET /admin/signatures" do
it "redirects to the login page" do
get :index, q: "Alice"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/login")
end
end
describe "DELETE /admin/signatures/:id" do
it "redirects to the login page" do
delete :destroy, id: signature.id
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/login")
end
end
end
context "logged in as moderator user but need to reset password" do -
let(:user) { FactoryBot.create(:moderator_user, force_password_reset: true) }
before { login_as(user) }
describe "GET /admin/signatures" do
it "redirects to the login page" do
get :index, q: "Alice"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/profile/#{user.id}/edit")
end
end
describe "DELETE /admin/signatures/:id" do
it "redirects to edit profile page" do
delete :destroy, id: signature.id
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/profile/#{user.id}/edit")
end
end
end
context "logged in as moderator user" do
let(:user) { FactoryBot.create(:moderator_user) }
let(:token) { SecureRandom.base64(32) }
let(:verifier) { ActiveSupport::MessageVerifier.new(token, serializer: JSON) }
let(:signature_ids) { verifier.generate([signature.id]) }
before do
login_as(user)
session[:_bulk_verification_token] = token
end
describe "GET /admin/signatures" do -
before { get :index, q: "Alice" }
it "returns 200 OK" do
expect(response).to have_http_status(:ok)
end
it "renders the :index template" do
expect(response).to render_template("admin/signatures/index")
end
end
describe "POST /admin/signatures/:id/validate" do -
context "when the signature is validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/validate)::context#when the signature is validated has a flog score of 40
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:validate!).and_return(true)
post :validate, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signature validated successfully")
end
end
context "when the signature is not validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/validate)::context#when the signature is not validated has a flog score of 52
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:validate!).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :validate, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signature could not be validated - please contact support")
end
end
end
describe "POST /admin/signatures/:id/invalidate" do -
context "when the signature is validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/invalidate)::context#when the signature is validated has a flog score of 40
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:invalidate!).and_return(true)
post :invalidate, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signature invalidated successfully")
end
end
context "when the signature is not validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/invalidate)::context#when the signature is not validated has a flog score of 52
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:invalidate!).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :invalidate, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signature could not be invalidated - please contact support")
end
end
end
describe "POST /admin/signatures/:id/subscribe" do
before do
signature.update!(notify_by_email: false)
end
context "and the update succeeds" do -
it "redirects to the search page" do
post :subscribe, id: signature.id, q: "user@example.com"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
post :subscribe, id: signature.id, q: "user@example.com"
expect(flash[:notice]).to eq("Signature subscribed successfully")
end
it "changes the notify_by_email attribute" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/subscribe)::context(and the update succeeds)::it#changes the notify_by_email attribute has a flog score of 25
expect {
post :subscribe, id: signature.id, q: "user@example.com"
}.to change {
signature.reload.notify_by_email
}.from(false).to(true)
end
end
context "and the update fails" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/subscribe)::context#and the update fails has a flog score of 36
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:update).with(notify_by_email: true).and_return(false)
end
it "redirects to the search page" do
post :subscribe, id: signature.id, q: "user@example.com"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
post :subscribe, id: signature.id, q: "user@example.com"
expect(flash[:alert]).to eq("Signature could not be subscribed - please contact support")
end
end
end
describe "POST /admin/signatures/:id/unsubscribe" do
before do
signature.update!(notify_by_email: true)
end
context "and the update succeeds" do -
it "redirects to the search page" do
post :unsubscribe, id: signature.id, q: "user@example.com"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
post :unsubscribe, id: signature.id, q: "user@example.com"
expect(flash[:notice]).to eq("Signature unsubscribed successfully")
end
it "changes the notify_by_email attribute" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/unsubscribe)::context(and the update succeeds)::it#changes the notify_by_email attribute has a flog score of 25
expect {
post :unsubscribe, id: signature.id, q: "user@example.com"
}.to change {
signature.reload.notify_by_email
}.from(true).to(false)
end
end
context "and the update fails" do - context(logged in as moderator user)::describe(POST /admin/signatures/:id/unsubscribe)::context#and the update fails has a flog score of 36
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:update).with(notify_by_email: false).and_return(false)
end
it "redirects to the search page" do
post :unsubscribe, id: signature.id, q: "user@example.com"
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
post :unsubscribe, id: signature.id, q: "user@example.com"
expect(flash[:alert]).to eq("Signature could not be unsubscribed - please contact support")
end
end
end
describe "DELETE /admin/signatures/:id" do
context "when the signature is destroyed" do - context(logged in as moderator user)::describe(DELETE /admin/signatures/:id)::context#when the signature is destroyed has a flog score of 40
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:destroy).and_return(true)
delete :destroy, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signature removed successfully")
end
end
context "when the signature is not destroyed" do - context(logged in as moderator user)::describe(DELETE /admin/signatures/:id)::context#when the signature is not destroyed has a flog score of 40
before do
expect(Signature).to receive(:find).with(signature.id.to_s).and_return(signature)
expect(signature).to receive(:destroy).and_return(false)
delete :destroy, id: signature.id, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signature could not be removed - please contact support")
end
end
end
describe "POST /admin/signatures/validate" do -
context "when the signature is validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/validate)::context#when the signature is validated has a flog score of 39
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:validate!).and_return(true)
post :bulk_validate, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signatures validated successfully")
end
end
context "when the signature is not validated" do - context(logged in as moderator user)::describe(POST /admin/signatures/validate)::context#when the signature is not validated has a flog score of 51
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:validate!).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :bulk_validate, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signatures could not be validated - please contact support")
end
end
context "when the signature ids hmac is missing" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_validate, selected_ids: signature.id, all_ids: "", q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request for \[\d+\]/)
end
end
context "when the selected_ids param contains an invalid id" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_validate, selected_ids: "1,2", all_ids: signature_ids, q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request - \d+ not present in \[\d+\]/)
end
end
end
describe "POST /admin/signatures/invalidate" do -
context "when the signature is invalidated" do - context(logged in as moderator user)::describe(POST /admin/signatures/invalidate)::context#when the signature is invalidated has a flog score of 39
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:invalidate!).and_return(true)
post :bulk_invalidate, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signatures invalidated successfully")
end
end
context "when the signature is not invalidated" do - context(logged in as moderator user)::describe(POST /admin/signatures/invalidate)::context#when the signature is not invalidated has a flog score of 51
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:invalidate!).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :bulk_invalidate, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signatures could not be invalidated - please contact support")
end
end
context "when the signature ids hmac is missing" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_invalidate, selected_ids: signature.id, all_ids: "", q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request for \[\d+\]/)
end
end
context "when the selected_ids param contains an invalid id" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_invalidate, selected_ids: "1,2", all_ids: signature_ids, q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request - \d+ not present in \[\d+\]/)
end
end
end
describe "POST /admin/signatures/subscribe" do
context "when the signature is subcribed" do - context(logged in as moderator user)::describe(POST /admin/signatures/subscribe)::context#when the signature is subcribed has a flog score of 41
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:update!).with(notify_by_email: true).and_return(true)
post :bulk_subscribe, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signatures subscribed successfully")
end
end
context "when the signature is not subscribed" do - context(logged in as moderator user)::describe(POST /admin/signatures/subscribe)::context#when the signature is not subscribed has a flog score of 54
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:update!).with(notify_by_email: true).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :bulk_subscribe, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signatures could not be subscribed - please contact support")
end
end
context "when the signature ids hmac is missing" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_subscribe, selected_ids: signature.id, all_ids: "", q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request for \[\d+\]/)
end
end
context "when the selected_ids param contains an invalid id" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_subscribe, selected_ids: "1,2", all_ids: signature_ids, q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request - \d+ not present in \[\d+\]/)
end
end
end
describe "POST /admin/signatures/unsubscribe" do
context "when the signature is unsubcribed" do - context(logged in as moderator user)::describe(POST /admin/signatures/unsubscribe)::context#when the signature is unsubcribed has a flog score of 41
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:update!).with(notify_by_email: false).and_return(true)
post :bulk_unsubscribe, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signatures unsubscribed successfully")
end
end
context "when the signature is not unsubscribed" do - context(logged in as moderator user)::describe(POST /admin/signatures/unsubscribe)::context#when the signature is not unsubscribed has a flog score of 54
let(:exception) { ActiveRecord::StatementInvalid.new("Invalid SQL") }
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:update!).with(notify_by_email: false).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
post :bulk_unsubscribe, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signatures could not be unsubscribed - please contact support")
end
end
context "when the signature ids hmac is missing" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_unsubscribe, selected_ids: signature.id, all_ids: "", q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request for \[\d+\]/)
end
end
context "when the selected_ids param contains an invalid id" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_unsubscribe, selected_ids: "1,2", all_ids: signature_ids, q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request - \d+ not present in \[\d+\]/)
end
end
end
describe "DELETE /admin/signatures" do -
context "when the signature is destroyed" do - context(logged in as moderator user)::describe(DELETE /admin/signatures)::context#when the signature is destroyed has a flog score of 39
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:destroy!).and_return(true)
delete :bulk_destroy, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash notice message" do
expect(flash[:notice]).to eq("Signatures removed successfully")
end
end
context "when the signature is not destroyed" do - context(logged in as moderator user)::describe(DELETE /admin/signatures)::context#when the signature is not destroyed has a flog score of 51
let(:exception) { ActiveRecord::RecordNotDestroyed.new("Cannot delete the creator signature") }
before do
expect(Signature).to receive(:find).with([signature.id]).and_return([signature])
expect(signature).to receive(:destroy!).and_raise(exception)
expect(Appsignal).to receive(:send_exception).with(exception)
delete :bulk_destroy, selected_ids: signature.id, all_ids: signature_ids, q: "user@example.com"
end
it "redirects to the search page" do
expect(response).to redirect_to("https://moderate.petition.parliament.uk/admin/signatures?q=user%40example.com")
end
it "sets the flash alert message" do
expect(flash[:alert]).to eq("Signatures could not be removed - please contact support")
end
end
context "when the signature ids hmac is missing" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_destroy, selected_ids: signature.id, all_ids: "", q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request for \[\d+\]/)
end
end
context "when the selected_ids param contains an invalid id" do
before do
expect(Signature).not_to receive(:find)
end
it "returns a 400 Bad Request" do
expect {
delete :bulk_destroy, selected_ids: "1,2", all_ids: signature_ids, q: "user@example.com"
}.to raise_error(BulkVerification::InvalidBulkRequest, /Invalid bulk request - \d+ not present in \[\d+\]/)
end
end
end
end
end