require 'minitest_helper'
require_relative '../../lib/redis_hash_store/rails_cache'

class User
  attr_reader :id, :updated_at

  def initialize(id)
    @id = id
    @updated_at = Time.now -
      rand(60) -
      rand(60) * 60 -
      rand(24) * 60 * 60 -
      rand(14) * 24 * 60 * 60
  end

  def persisted?
    true
  end

  def touch
    @updated_at = Time.now
  end
end

class RailsCacheWrapper
  include RedisHashStore::RailsCache

  attr_accessor :call_counter

  def initialize
    @call_counter = 0
  end

  def call(*options)
    redis_hash_cache *options do
      @call_counter += 1
      'foo'
    end
  end

  private

  def perform_caching
    true
  end
end

class TestRailsCache < MiniTest::Test
  def setup
    setup_redis
  end

  def test_cache
    users = (1..3).map do |i|
      User.new i
    end
    wrapper = RailsCacheWrapper.new
    3.times do
      cached_value = wrapper.call(*users)
      assert_equal 1, wrapper.call_counter
      assert_equal 'foo', cached_value
    end
    assert_equal 1, Redis.current.keys.size
    key_parts = Redis.current.keys.first.split(':')
    assert_equal RedisHashStore.configuration.key_prefix, key_parts.shift
    assert_equal RailsCacheWrapper.to_s, key_parts.shift
    assert_equal users.map { |user| user.class.to_s }, key_parts.shift(users.size)
    last_key_parts = users[0..-2].map(&:id)
    last_key_parts << (users.last.id / RedisHashStore.configuration.fields_per_hash)
    last_key_parts.map!(&:to_s)
    assert_equal last_key_parts, key_parts.shift(users.size)
    assert key_parts.empty?
  end
end
