From 3cd9a4d5be1178d8df286335b1f0eaef8098fa37 Mon Sep 17 00:00:00 2001 From: Pablo Brasero Date: Thu, 4 Jun 2026 15:52:22 +0100 Subject: [PATCH] Take expiry into account when checking moderation zones --- app/controllers/api/notes_controller.rb | 2 +- app/models/moderation_zone.rb | 8 ++++++-- test/models/moderation_zone_test.rb | 25 +++++++++++++++++++------ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/notes_controller.rb b/app/controllers/api/notes_controller.rb index 62b334a3d..d512b117e 100644 --- a/app/controllers/api/notes_controller.rb +++ b/app/controllers/api/notes_controller.rb @@ -89,7 +89,7 @@ module Api lat = OSM.parse_float(params[:lat], OSM::APIBadUserInput, "lat was not a number") description = params[:text] - raise OSM::APIModerationZoneError if current_user.nil? && ModerationZone.falls_within_any?(:lon => lon, :lat => lat) + raise OSM::APIModerationZoneError if current_user.nil? && ModerationZone.falls_within_any_active?(:lon => lon, :lat => lat) # Get note's author info (for logged in users - user_id, for logged out users - IP address) note_author_info = author_info diff --git a/app/models/moderation_zone.rb b/app/models/moderation_zone.rb index 14198a1f6..f3695ec22 100644 --- a/app/models/moderation_zone.rb +++ b/app/models/moderation_zone.rb @@ -36,12 +36,16 @@ class ModerationZone < ApplicationRecord validates :zone, :presence => true validates :ends_at, :presence => true - def self.falls_within_any?(lon:, lat:) + def self.falls_within_any_active?(lon:, lat:) factory = RGeo::Cartesian.simple_factory(:srid => 4326) point = factory.point(lon, lat) where( arel_table[:zone].st_contains(point) - ).exists? + ).any?(&:active?) + end + + def active? + ends_at.future? end end diff --git a/test/models/moderation_zone_test.rb b/test/models/moderation_zone_test.rb index b935a0c84..205bf0013 100644 --- a/test/models/moderation_zone_test.rb +++ b/test/models/moderation_zone_test.rb @@ -3,16 +3,29 @@ require "test_helper" class ModerationZoneTest < ActiveSupport::TestCase - def test_falls_within_any - create(:moderation_zone, :seville_cathedral) + def test_falls_within_any_active + create(:moderation_zone, :seville_cathedral, :ends_at => 1.day.from_now) - # Dead center - assert ModerationZone.falls_within_any?(:lat => 37.385972, :lon => -5.993149) + dead_center = { :lat => 37.385972, :lon => -5.993149 } + + assert ModerationZone.falls_within_any_active?(**dead_center) # Inside, near the boundary - assert ModerationZone.falls_within_any?(:lat => 37.386658, :lon => -5.994024) + assert ModerationZone.falls_within_any_active?(:lat => 37.386658, :lon => -5.994024) # Outside, near the boundary - assert_not ModerationZone.falls_within_any?(:lat => 37.386769, :lon => -5.994185) + assert_not ModerationZone.falls_within_any_active?(:lat => 37.386769, :lon => -5.994185) + + travel_to 2.days.from_now do + assert_not ModerationZone.falls_within_any_active?(**dead_center) + end + end + + def test_active? + modzone1 = create(:moderation_zone, :ends_at => 1.day.from_now) + assert_predicate modzone1, :active? + + modzone2 = create(:moderation_zone, :ends_at => 1.day.ago) + assert_not_predicate modzone2, :active? end end -- 2.47.3