From c574a4d93ab56f35a0e37aabc2be4d8c7249c7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 18 Jun 2019 21:44:12 +0200 Subject: [PATCH] Fix `DirectMessage.today` on different time zones The dates are saved on UTC times on the database. So, for example, if living in West Australia, `Date.current.beginning_of_day` will be stored as UTC's yesterday at 15:15:00, while `Date.current.end_of_day` will be stored as UTC's today at 15:14:59. When we use the `DATE` database function, PostgreSQL will select the records with the same UTC date as the current UTC date. However, we need the records with the same application date (as defined in `config.time_zone`) as the current application date. The test passed (for us) because we were using `beginning_of_day + 3.hours` to make sure we were creating records when the date in Madrid was the same as the UTC date. Using a ruby interval for the time condition solves the problem. --- app/models/direct_message.rb | 2 +- spec/models/direct_message_spec.rb | 8 ++++---- spec/spec_helper.rb | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/direct_message.rb b/app/models/direct_message.rb index 4f3b08482..442d56534 100644 --- a/app/models/direct_message.rb +++ b/app/models/direct_message.rb @@ -8,7 +8,7 @@ class DirectMessage < ApplicationRecord validates :receiver, presence: true validate :max_per_day - scope :today, lambda { where("DATE(created_at) = DATE(?)", Time.current) } + scope :today, lambda { where(created_at: Date.current.beginning_of_day..Date.current.end_of_day) } def max_per_day return if errors.any? diff --git a/spec/models/direct_message_spec.rb b/spec/models/direct_message_spec.rb index 1c67c363f..ccb072bf7 100644 --- a/spec/models/direct_message_spec.rb +++ b/spec/models/direct_message_spec.rb @@ -75,11 +75,11 @@ describe DirectMessage do describe "scopes" do - describe "today" do + describe "today", :with_non_utc_time_zone do it "returns direct messages created today" do - direct_message1 = create(:direct_message, created_at: Time.now.utc.beginning_of_day + 3.hours) - direct_message2 = create(:direct_message, created_at: Time.now.utc) - direct_message3 = create(:direct_message, created_at: Time.now.utc.end_of_day) + create(:direct_message, created_at: Date.current.beginning_of_day) + create(:direct_message, created_at: Time.current) + create(:direct_message, created_at: Date.current.end_of_day) expect(described_class.today.count).to eq 3 end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2b5458e96..dccfd4d3d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -104,6 +104,12 @@ RSpec.configure do |config| allow(Date).to receive(:today).and_return(Time.now.to_date) end + config.before(:each, :with_non_utc_time_zone) do + application_zone = ActiveSupport::TimeZone.new("Madrid") + + allow(Time).to receive(:zone).and_return(application_zone) + end + # Allows RSpec to persist some state between runs in order to support # the `--only-failures` and `--next-failure` CLI options. config.example_status_persistence_file_path = "spec/examples.txt"