Updated

spec/models / invalidation_spec.rb

F
1025 lines of codes
0 methods
N/A complexity/method
6 churn
3060.94 complexity
1504 duplications
require 'rails_helper' RSpec.describe Invalidation, type: :model do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs") } it "has a valid factory" do expect(FactoryBot.build(:invalidation, name: "Joe Bloggs")).to be_valid end describe "associations" do
  1. Similar code found in 2 nodes Locations: 0 1
it { is_expected.to belong_to(:petition) } it { is_expected.to have_many(:signatures) } end describe "indexes" do it { is_expected.to have_db_index(:petition_id) } end describe "callbacks" do context "when an invalidation hasn't started" do let!(:invalidation) { FactoryBot.create(:invalidation, name: "Joe Bloggs") } it "can be deleted" do expect(invalidation.destroy).to be_truthy end end context "when an invalidation has started" do let!(:invalidation) { FactoryBot.create(:invalidation, :started, name: "Joe Bloggs") } it "can't be deleted" do expect(invalidation.destroy).to be_falsey end end end describe "validations" do
  1. describe#validations has a flog score of 114
it { is_expected.to validate_presence_of(:summary) } it { is_expected.to validate_length_of(:summary).is_at_most(255) } it { is_expected.to validate_length_of(:details).is_at_most(10000) } it { is_expected.to validate_numericality_of(:petition_id).only_integer.is_greater_than_or_equal_to(100000) } it { is_expected.to validate_length_of(:name).is_at_most(255) } it { is_expected.to validate_length_of(:postcode).is_at_most(255) } it { is_expected.to validate_length_of(:ip_address).is_at_most(20) } it { is_expected.to validate_length_of(:email).is_at_most(255) } it { is_expected.to validate_length_of(:domain).is_at_most(255) } it { is_expected.to validate_length_of(:constituency_id).is_at_most(30) } it { is_expected.to validate_length_of(:location_code).is_at_most(30) } it { is_expected.not_to allow_value("foo").for(:ip_address) } it { is_expected.to allow_value("123.123.123.123").for(:ip_address) } context "when there are no conditions" do subject { FactoryBot.build(:invalidation) } before do subject.valid? end it "adds an error to :petition_id" do expect(subject.errors[:petition_id]).to include("Please select some conditions, otherwise all signatures will be invalidated") end end context "when a petition doesn't exist" do subject { FactoryBot.build(:invalidation, petition_id: 123456) } before do subject.valid? end it "adds an error to :petition_id" do expect(subject.errors[:petition_id]).to include("Petition doesn't exist") end end context "when a constituency doesn't exist" do
  1. Similar code found in 3 nodes Locations: 0 1 2
subject { FactoryBot.build(:invalidation, constituency_id: "1234") } before do subject.valid? end it "adds an error to :constituency_id" do expect(subject.errors[:constituency_id]).to include("Constituency doesn't exist") end end context "when a constituency doesn't exist" do
  1. Similar code found in 3 nodes Locations: 0 1 2
subject { FactoryBot.build(:invalidation, constituency_id: "1234") } before do subject.valid? end it "adds an error to :constituency_id" do
  1. describe(validations)::context(when a constituency doesn't exist)::it#adds an error to :constituency_id has a flog score of 29
expect(subject.errors[:constituency_id]).to include("Constituency doesn't exist") end end context "when a location doesn't exist" do
  1. Similar code found in 3 nodes Locations: 0 1 2
subject { FactoryBot.build(:invalidation, location_code: "XX") } before do subject.valid? end it "adds an error to :location_code" do expect(subject.errors[:location_code]).to include("Location doesn't exist") end end context "when the date range is reversed" do subject { FactoryBot.build(:invalidation, created_after: 2.weeks.ago, created_before: 3.weeks.ago) } before do subject.valid? end it "adds an error to :created_after" do expect(subject.errors[:created_after]).to include("Starting date is after the finishing date") end end end describe "class methods" do describe ".by_most_recent" do
  1. Similar code found in 2 nodes Locations: 0 1
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", created_at: 3.weeks.ago) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", created_at: 2.weeks.ago) } it "orders the invalidations by the created_at timestamp in descending order" do expect(described_class.by_most_recent.to_a).to eq([invalidation_2, invalidation_1]) end end describe ".by_longest_running" do
  1. Similar code found in 2 nodes Locations: 0 1
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 1.hour.ago) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 2.hours.ago) } it "orders the invalidations by the started_at timestamp in ascending order" do expect(described_class.by_most_recent.to_a).to eq([invalidation_2, invalidation_1]) end end describe ".cancelled" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: 2.hours.ago) } it "scopes the query to invalidations with a cancelled_at timestamp" do expect(described_class.cancelled.to_a).to eq([invalidation_2]) end end describe ".completed" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: 2.hours.ago) } it "scopes the query to invalidations with a completed_at timestamp" do expect(described_class.completed.to_a).to eq([invalidation_2]) end end describe ".enqueued" do let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: 2.hours.ago) } let!(:invalidation_3) { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: 2.hours.ago, started_at: 1.hour.ago) }
  1. Similar code found in 2 nodes Locations: 0 1
it "scopes the query to invalidations with a enqueued_at timestamp that have not started" do expect(described_class.enqueued.to_a).to eq([invalidation_2]) end end describe ".not_completed" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: 2.hours.ago) } it "scopes the query to invalidations without a completed_at timestamp" do expect(described_class.not_completed.to_a).to eq([invalidation_1]) end end describe ".pending" do let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs") } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: 2.hours.ago) } let!(:invalidation_3) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 2.hours.ago) } let!(:invalidation_4) { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: 2.hours.ago) } let!(:invalidation_5) { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: 2.hours.ago) } it "scopes the query to invalidations that have not been processed in anyway" do expect(described_class.pending.to_a).to eq([invalidation_1]) end end describe ".running" do let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 3.hours.ago, completed_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 3.hours.ago, completed_at: 2.hours.ago) }
  1. Similar code found in 2 nodes Locations: 0 1
it "scopes the query to invalidations that have started, but not completed" do expect(described_class.running.to_a).to eq([invalidation_1]) end end describe ".started" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
let!(:invalidation_1) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: nil) } let!(:invalidation_2) { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: 2.hours.ago) } it "scopes the query to invalidations with a started_at timestamp" do expect(described_class.started.to_a).to eq([invalidation_2]) end end end describe "instance methods" do describe "#cancelled?" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
context "when cancelled_at is nil" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: nil) } it "returns false" do expect(subject.cancelled?).to eq(false) end end context "when cancelled_at is set" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: Time.current) } it "returns true" do expect(subject.cancelled?).to eq(true) end end end describe "#cancel!" do it "changes cancelled? from false to true" do expect { subject.cancel! }.to change { subject.cancelled? }.from(false).to(true) end it "it sets cancelled_at" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
  2. describe(instance methods)::describe(#cancel!)::it#it sets cancelled_at has a flog score of 28
expect { subject.cancel! }.to change { subject.cancelled_at }.from(nil).to(be_within(1.second).of(Time.current)) end context "when the invalidation has already been cancelled" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: Time.current) } it "returns false" do expect(subject.cancel!).to be_falsey end end context "when the invalidation has already completed processing" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: Time.current) } it "returns false" do expect(subject.cancel!).to be_falsey end end end describe "#completed?" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
context "when completed_at is nil" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: nil) } it "returns false" do expect(subject.completed?).to eq(false) end end context "when completed_at is set" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: Time.current) } it "returns true" do expect(subject.completed?).to eq(true) end end end describe "#count!" do before do 3.times do FactoryBot.create(:validated_signature, ip_address: "10.0.1.1") end end subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1") } it "updates the matching_count" do expect { subject.count! }.to change { subject.matching_count }.from(0).to(3) end it "updates the counted_at timestamp" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
  2. describe(instance methods)::describe(#count!)::it#updates the counted_at timestamp has a flog score of 28
expect { subject.count! }.to change { subject.counted_at }.from(nil).to(be_within(1.second).of(Time.current)) end context "when the invalidation in no longer pending" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1", started_at: Time.current) } it "returns false" do expect(subject.count!).to be_falsey end end end describe "#enqueued?" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
context "when enqueued_at is nil" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: nil) } it "returns false" do expect(subject.enqueued?).to eq(false) end end context "when enqueued_at is set" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: Time.current) } it "returns true" do expect(subject.enqueued?).to eq(true) end end end describe "#start!" do subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1") } let(:job) do
  1. Similar code found in 2 nodes Locations: 0 1
{ job: InvalidateSignaturesJob, args: [ { "_aj_globalid" => "gid://epets/Invalidation/#{subject.id}" } ], queue: "high_priority" } end it "enqueues the invalidate signatures job" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
expect { subject.start! }.to change { enqueued_jobs }.from([]).to([job]) end it "updates the enqueued_at timestamps" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
  2. describe(instance methods)::describe(#start!)::it#updates the enqueued_at timestamps has a flog score of 28
expect { subject.start! }.to change { subject.enqueued_at }.from(nil).to(be_within(1.second).of(Time.current)) end context "when the invalidation in no longer pending" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1", started_at: Time.current) } it "returns false" do expect(subject.start!).to be_falsey end end end describe "#started?" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
context "when started_at is nil" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: nil) } it "returns false" do expect(subject.started?).to eq(false) end end context "when started_at is set" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: Time.current) } it "returns true" do expect(subject.started?).to eq(true) end end end describe "#pending?" do context "by default" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs") } it "returns true" do expect(subject.pending?).to eq(true) end end context "when a invalidation is enqueued" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", enqueued_at: Time.current) } it "returns false" do expect(subject.pending?).to eq(false) end end context "when a invalidation is running" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: Time.current) } it "returns false" do expect(subject.pending?).to eq(false) end end context "when a invalidation has been cancelled" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", cancelled_at: Time.current) } it "returns false" do expect(subject.pending?).to eq(false) end end context "when a invalidation has been completed" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", completed_at: Time.current) } it "returns false" do expect(subject.pending?).to eq(false) end end end describe "#running?" do context "by default" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs") } it "returns false" do expect(subject.running?).to eq(false) end end context "when a invalidation is running" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: Time.current) } it "returns true" do expect(subject.running?).to eq(true) end end context "when a invalidation has been cancelled" do
  1. Similar code found in 2 nodes Locations: 0 1
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: Time.current, cancelled_at: Time.current) } it "returns false" do expect(subject.running?).to eq(false) end end context "when a invalidation has been completed" do
  1. Similar code found in 2 nodes Locations: 0 1
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", started_at: Time.current, completed_at: Time.current) } it "returns false" do expect(subject.running?).to eq(false) end end end describe "#percent_completed" do context "when matching_count is zero" do context "and the invalidation has not started" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 0, invalidated_count: 0) } it "returns 0" do expect(subject.percent_completed).to eq(0) end end context "and the invalidation has started" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 0, invalidated_count: 0, started_at: Time.current) } it "returns 100" do expect(subject.percent_completed).to eq(100) end end context "and the invalidation has completed" do subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 0, invalidated_count: 0, started_at: Time.current, completed_at: Time.current) } it "returns 100" do expect(subject.percent_completed).to eq(100) end end end context "when matching_count is not zero" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 100, invalidated_count: 50, started_at: Time.current) } it "returns the percentage of completed invalidations" do expect(subject.percent_completed).to eq(50) end end context "when invalidated_count is a negative number" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 100, invalidated_count: -50, started_at: Time.current) } it "returns 0" do expect(subject.percent_completed).to eq(0) end end context "when invalidated_count is greater than matching_count" do
  1. Similar code found in 4 nodes Locations: 0 1 2 3
subject { FactoryBot.create(:invalidation, name: "Joe Bloggs", matching_count: 50, invalidated_count: 100, started_at: Time.current) } it "returns 100" do expect(subject.percent_completed).to eq(100) end end end describe "#matching_signatures" do context "when filtering by petition" do let!(:petition_1) { FactoryBot.create(:open_petition) } let!(:petition_2) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, petition: petition_1) } let!(:signature_2) { FactoryBot.create(:validated_signature, petition: petition_2) } let!(:signature_3) { FactoryBot.create(:pending_signature, petition: petition_1) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, petition: petition_1) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, petition: petition_1) } subject { FactoryBot.create(:invalidation, petition: petition_1) } it "includes validated signatures for petition 1" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures for petition 1" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures for petition 1" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures for petition 1" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures for petition 2" do expect(subject.matching_signatures).not_to include(signature_2) end end context "when filtering by name" do let!(:petition) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, name: "Joe Public", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, name: "John Doe", petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, name: "Joe Public", petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, name: "Joe Public", petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, name: "Joe Public", petition: petition) } subject { FactoryBot.create(:invalidation, name: "Joe Public") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end context "and the filter includes a LIKE wildcard" do
  1. Similar code found in 2 nodes Locations: 0 1
subject { FactoryBot.create(:invalidation, name: "Joe %") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end end context "when filtering by postcode" do before do stub_api_request_for("SW1A0AA").to_return(api_response(:ok, "london_and_westminster")) stub_api_request_for("E16PL").to_return(api_response(:ok, "bethnal_green_and_bow")) end let!(:petition) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, postcode: "SW1A 0AA", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, postcode: "E1 6PL", petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, postcode: "SW1A 0AA", petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, postcode: "SW1A 0AA", petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, postcode: "SW1A 0AA", petition: petition) } subject { FactoryBot.create(:invalidation, postcode: "SW1A0AA") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "when filtering by ip_address" do let!(:petition) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, ip_address: "10.0.1.1", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, ip_address: "192.168.1.1", petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, ip_address: "10.0.1.1", petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, ip_address: "10.0.1.1", petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, ip_address: "10.0.1.1", petition: petition) } subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "when filtering by email" do let!(:petition_1) { FactoryBot.create(:open_petition) } let!(:petition_2) { FactoryBot.create(:open_petition) } let!(:petition_3) { FactoryBot.create(:open_petition) } let!(:petition_4) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, email: "joe@public.com", petition: petition_1) } let!(:signature_2) { FactoryBot.create(:validated_signature, email: "john@doe.com", petition: petition_1) } let!(:signature_3) { FactoryBot.create(:pending_signature, email: "joe@public.com", petition: petition_2) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, email: "joe@public.com", petition: petition_3) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, email: "joe@public.com", petition: petition_4) } subject { FactoryBot.create(:invalidation, email: "joe@public.com") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end context "and the filter includes a LIKE wildcard" do
  1. Similar code found in 2 nodes Locations: 0 1
subject { FactoryBot.create(:invalidation, email: "%@public.com") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end end context "when filtering by domain" do let!(:petition_1) { FactoryBot.create(:open_petition) } let!(:petition_2) { FactoryBot.create(:open_petition) } let!(:petition_3) { FactoryBot.create(:open_petition) } let!(:petition_4) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, email: "joe@public.com", petition: petition_1) } let!(:signature_2) { FactoryBot.create(:validated_signature, email: "john@doe.com", petition: petition_1) } let!(:signature_3) { FactoryBot.create(:pending_signature, email: "joe@public.com", petition: petition_2) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, email: "joe@public.com", petition: petition_3) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, email: "joe@public.com", petition: petition_4) } subject { FactoryBot.create(:invalidation, domain: "public.com") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "when filtering by date range" do let!(:petition) { FactoryBot.create(:open_petition) } context "and just the start date is specified" do
  1. Similar code found in 2 nodes Locations: 0 1
let!(:signature_1) { FactoryBot.create(:validated_signature, created_at: 2.weeks.ago, petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, created_at: 2.weeks.ago, petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, created_at: 2.weeks.ago, petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, created_at: 2.weeks.ago, petition: petition) } subject { FactoryBot.create(:invalidation, created_after: 3.weeks.ago) } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "and just the end date is specified" do
  1. Similar code found in 2 nodes Locations: 0 1
let!(:signature_1) { FactoryBot.create(:validated_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, created_at: 2.weeks.ago, petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, created_at: 4.weeks.ago, petition: petition) } subject { FactoryBot.create(:invalidation, created_before: 3.weeks.ago) } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "and both the start date and end date are specified" do let!(:signature_1) { FactoryBot.create(:validated_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, created_at: 2.weeks.ago, petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, created_at: 4.weeks.ago, petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, created_at: 4.weeks.ago, petition: petition) } subject { FactoryBot.create(:invalidation, created_before: 3.weeks.ago, created_after: 5.weeks.ago) } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end end context "when filtering by constituency_id" do let!(:petition) { FactoryBot.create(:open_petition) } let!(:coventry) { FactoryBot.create(:constituency, :coventry_north_east) } let!(:bethnal) { FactoryBot.create(:constituency, :bethnal_green_and_bow) } let!(:signature_1) { FactoryBot.create(:validated_signature, constituency_id: "3427", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, constituency_id: "3320", petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, constituency_id: "3427", petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, constituency_id: "3427", petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, constituency_id: "3427", petition: petition) } subject { FactoryBot.create(:invalidation, constituency_id: "3427") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end context "when filtering by location_code" do let!(:petition) { FactoryBot.create(:open_petition) } let!(:united_kingdom) { FactoryBot.create(:location, code: "GB", name: "United Kingdom") } let!(:australia) { FactoryBot.create(:location, code: "AU", name: "Australia") } let!(:signature_1) { FactoryBot.create(:validated_signature, location_code: "GB", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, location_code: "AU", petition: petition) } let!(:signature_3) { FactoryBot.create(:pending_signature, location_code: "GB", petition: petition) } let!(:signature_4) { FactoryBot.create(:invalidated_signature, location_code: "GB", petition: petition) } let!(:signature_5) { FactoryBot.create(:fraudulent_signature, location_code: "GB", petition: petition) } subject { FactoryBot.create(:invalidation, location_code: "GB") } it "includes validated signatures that match" do expect(subject.matching_signatures).to include(signature_1) end it "includes pending signatures that match" do expect(subject.matching_signatures).to include(signature_3) end it "excludes invalidated signatures that match" do expect(subject.matching_signatures).not_to include(signature_4) end it "excludes fraudulent signatures that match" do expect(subject.matching_signatures).not_to include(signature_5) end it "excludes signatures that don't match" do expect(subject.matching_signatures).not_to include(signature_2) end end end describe "#invalidate!" do let!(:petition) { FactoryBot.create(:open_petition) } let!(:signature_1) { FactoryBot.create(:validated_signature, ip_address: "10.0.1.1", petition: petition) } let!(:signature_2) { FactoryBot.create(:validated_signature, ip_address: "192.168.1.1", petition: petition) } let!(:signature_3) { FactoryBot.create(:validated_signature, ip_address: "10.0.1.1", petition: petition) } let!(:signature_4) { FactoryBot.create(:validated_signature, ip_address: "192.168.1.2", petition: petition) } let!(:signature_5) { FactoryBot.create(:validated_signature, ip_address: "10.0.1.1", petition: petition) } subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1") } it "sets the matching_count" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
expect { subject.invalidate! }.to change { subject.reload.matching_count }.from(0).to(3) end it "increments the invalidated_count after each invalidation" do expect(subject).to receive(:increment!).with(:invalidated_count).exactly(3).times.and_call_original subject.invalidate! end it "sets the invalidated_count" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
expect { subject.invalidate! }.to change { subject.reload.invalidated_count }.from(0).to(3) end it "sets the started_at timestamp" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
  2. describe(instance methods)::describe(#invalidate!)::it#sets the started_at timestamp has a flog score of 31
expect { subject.invalidate! }.to change { subject.reload.started_at }.from(nil).to(be_within(1.second).of(Time.current)) end it "sets the completed_at timestamp" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
  2. describe(instance methods)::describe(#invalidate!)::it#sets the completed_at timestamp has a flog score of 31
expect { subject.invalidate! }.to change { subject.reload.completed_at }.from(nil).to(be_within(1.second).of(Time.current)) end it "adds the invalidated signatures to the signatures association" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
expect { subject.invalidate! }.to change { subject.signatures.count }.from(0).to(3) end context "when the invalidation has already completed processing" do
  1. Similar code found in 5 nodes Locations: 0 1 2 3 4
subject { FactoryBot.create(:invalidation, ip_address: "10.0.1.1", completed_at: Time.current) } it "returns false" do expect(subject.invalidate!).to be_falsey end end context "when cancelled before starting" do before do subject.cancel! end it "doesn't start" do expect { subject.invalidate! }.not_to change { subject.reload.started_at } end end context "when cancelled during processing" do before do 200.times do FactoryBot.create(:validated_signature, ip_address: "10.0.1.1", petition: petition) end end it "doesn't finish" do
  1. describe(instance methods)::describe(#invalidate!)::context(when cancelled during processing)::it#doesn't finish has a flog score of 52
allow(subject).to receive(:cancelled?).and_return(false, true) subject.invalidate! subject.reload expect(subject.matching_count).to eq(203) expect(subject.invalidated_count).to eq(100) expect(subject.signatures.count).to eq(100) end end end end end