Hi Phil, I feel like such an idiot. I was well aware of the lossy-conversion issue, but had eliminated it as a possibility because I was “sure” that there was no conversion going on in the backend. When I went to grab the code, there it was: “Time.at <http://time.at/>()”. Sigh …
Thanks for making me re-examine my assumptions. Please take a look at my other issue — there’s no “behind the scenes” code there. Jack > On Feb 25, 2021, at 12:43 PM, Phil Pirozhkov <pirjs...@gmail.com> wrote: > > Jack, > > I'd like a sneak peak into `subscription_cancelled_at`'s code. > Some lossy conversions may happen behind the scenes. See > https://github.com/rails/rails/issues/38831#issuecomment-606146664 > > I'd definitely not rely on micro- and milli-second precision in expectations. > To my best memory Rails opted to round to seconds in their > ActiveJob-related test helpers. > > With RSpec, I'd suggest using be_within(1.second).of(future_date) > > - Phil > > On Thu, Feb 25, 2021 at 9:58 PM Jack Royal-Gordon <jac...@pobox.com> wrote: >> >> I have the following examples: >> >> describe "#subscription_cancelled_at" do >> let!(:user) { FactoryBot.create(:user, stripe_id: 'stripe') } >> let!(:stripe_customer) { Stripe::Customer.new } >> let!(:past_date) { 2.weeks.ago } >> let!(:future_date) { 2.weeks.from_now } >> let!(:subscription) { build_deep_struct(status: 'active', >> cancel_at_period_end: false, canceled_at: nil, current_period_end: >> future_date) } >> >> it 'returns nil if there is no subscription' do >> allow(user).to receive(:stripe_customer).and_return(nil) >> expect(user).to receive(:stripe_customer) >> expect(stripe_customer).to_not receive(:subscriptions) >> expect(user.subscription_cancelled_at).to be_nil >> end >> >> it "returns canceled_at if it is populated" do >> subscription.canceled_at = past_date >> allow(user).to receive(:stripe_customer).and_return(stripe_customer) >> allow(stripe_customer).to >> receive(:subscriptions).and_return([subscription]) >> expect(user).to receive(:stripe_customer) >> expect(stripe_customer).to receive(:subscriptions) >> expect(user.subscription_cancelled_at.utc).to eq past_date >> end >> >> it "returns current_period_end if subscription will cancel at period end" >> do >> subscription.cancel_at_period_end = true >> allow(user).to receive(:stripe_customer).and_return(stripe_customer) >> allow(stripe_customer).to >> receive(:subscriptions).and_return([subscription]) >> expect(user).to receive(:stripe_customer) >> expect(stripe_customer).to receive(:subscriptions) >> expect(user.subscription_cancelled_at).to eq future_date >> end >> >> it 'returns false otherwise' do >> allow(user).to receive(:stripe_customer).and_return(stripe_customer) >> allow(stripe_customer).to >> receive(:subscriptions).and_return([subscription]) >> expect(user).to receive(:stripe_customer) >> expect(stripe_customer).to receive(:subscriptions) >> expect(user.subscription_cancelled_at).to be_nil >> end >> end >> >> >> All that’s really going on here is that I’m passing the dates through some >> data structures and eventually returning the expected dates. There is no >> date math (or conversion) involved behind the scenes. However, I get these >> results: >> >> 1) User::StripeCustomer#subscription_cancelled_at returns canceled_at if it >> is populated >> Failure/Error: expect(user.subscription_cancelled_at.utc).to eq >> @@past_date >> >> >> >> expected: 2021-02-11 18:48:06.455547000 +0000 >> got: 2021-02-11 18:48:06.455546855 +0000 >> >> >> >> (compared using ==) >> >> >> >> Diff: >> @@ -1 +1 @@ >> -Thu, 11 Feb 2021 18:48:06 UTC +00:00 >> +2021-02-11 18:48:06 UTC >> >> >> >> # ./spec/models/user/stripe_customer_spec.rb:312:in `block (3 levels) in >> <top (required)>' >> >> 2) User::StripeCustomer#subscription_cancelled_at returns >> current_period_end if subscription will cancel at period end >> Failure/Error: expect(user.subscription_cancelled_at).to eq @@future_date >> >> >> >> expected: 2021-03-11 18:48:06.455753000 +0000 >> got: 2021-03-11 10:48:06.455752849 -0800 >> >> >> >> (compared using ==) >> >> >> >> Diff: >> @@ -1 +1 @@ >> -Thu, 11 Mar 2021 18:48:06 UTC +00:00 >> +2021-03-11 10:48:06 -0800 >> >> >> >> # ./spec/models/user/stripe_customer_spec.rb:321:in `block (3 levels) in >> <top (required)>' >> >> >> Notice that the times being compared are off by very small amounts (< 1 >> sec). I tried replacing the “let!” commands with assignments to class >> variables (@@past_date, etc) in an attempt to ensure that the let! blocks >> were not being re-evaluated each time they were referenced, but that was not >> the case. >> >> I can certainly change the test to check for a time “close” to the expected >> time, but that is a hack. Can anyone explain why I’m getting these >> differences? >> >> -- >> You received this message because you are subscribed to the Google Groups >> "rspec" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to rspec+unsubscr...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/rspec/E9584261-2BFC-49BB-AC53-21991545F39F%40pobox.com. > > -- > You received this message because you are subscribed to the Google Groups > "rspec" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rspec+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/rspec/CAAk5Ok-68sKasxG3O6jwG4FisKVC3Sfa9w_WRx5PYeQLxJjRgw%40mail.gmail.com. -- You received this message because you are subscribed to the Google Groups "rspec" group. To unsubscribe from this group and stop receiving emails from it, send an email to rspec+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/7B90A0A4-037D-4A03-9160-5772CFDCBE45%40pobox.com.