ltdev
ltdev

Reputation: 4477

Rspec test record is within range of dates

I'm having this scope function inside my model

# models/Post.rb
  def self.filtered (params)

    unless params[:year].blank? && params[:month].blank?
      year = params[:year].to_i
      month = params[:month].to_i
      return where(created_at: DateTime.new(year, month, 1).beginning_of_day..DateTime.new(year, month, -1).end_of_day)
    end

    self

  end

# controllers/posts_controller.rb
@posts = Post.filtered(params)

Which basically returns all archived posts of specific year and month

SELECT  `posts`.* FROM `posts` 
WHERE (`posts`.`created_at` BETWEEN '2017-10-01 00:00:00' AND '2017-10-31 23:59:59')

I'm trying to write a test for this method to make sure that a post is was created in the requested year and month, how can I do this?

# spec/models/post_spec.rb
  describe '.filtered' do
    let!(:older) { FactoryGirl.create(:post, created_at: 1.month.ago) } # this post should not appear in the list
    let!(:newer) { FactoryGirl.create(:post, created_at: Time.zone.now) } # this post should appear in the list

    it 'is within specific year and month' do
      expect(Post.filtered({year: Date.today.strftime("%Y"), month: Date.today.strftime("%m")}).map { |post| post.created_at }).to be ???

    end
  end

Upvotes: 0

Views: 943

Answers (2)

EJAg
EJAg

Reputation: 3298

Use #contain_exactly to match elements when order should be disregarded.

# spec/models/post_spec.rb
  describe '.filtered' do
    let!(:older) { FactoryGirl.create(:post, created_at: 1.month.ago) } # this post should not appear in the list
    let!(:newer) { FactoryGirl.create(:post, created_at: Time.zone.now) } # this post should appear in the list

    it 'is within specific year and month' do
      expect(Post.filtered({year: Date.today.strftime("%Y"), month: Date.today.strftime("%m")}).map { |post| article.created_at }).to contain_exactly(newer)

end

end

By the way, instead of creating a class method like what you did here, you might want to consider a scope so it can be chained with other scopes.

Upvotes: 1

Daniel Westendorf
Daniel Westendorf

Reputation: 3465

Use the include matcher to verify a record is included in the result set.

expect(Post.filtered({year: Date.today.strftime("%Y"), month: Date.today.strftime("%m")}).to include(newer)

Upvotes: 1

Related Questions