140 lines
3.9 KiB
Ruby
140 lines
3.9 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
require "spec_helper"
|
||
|
|
||
|
RSpec.describe API::Helpers::Caching do
|
||
|
subject(:instance) { Class.new.include(described_class).new }
|
||
|
|
||
|
describe "#present_cached" do
|
||
|
let_it_be(:project) { create(:project) }
|
||
|
let_it_be(:user) { create(:user) }
|
||
|
|
||
|
let(:presenter) { API::Entities::Todo }
|
||
|
|
||
|
let(:kwargs) do
|
||
|
{
|
||
|
with: presenter,
|
||
|
project: project
|
||
|
}
|
||
|
end
|
||
|
|
||
|
subject do
|
||
|
instance.present_cached(presentable, **kwargs)
|
||
|
end
|
||
|
|
||
|
before do
|
||
|
# We have to stub #body as it's a Grape method
|
||
|
# unavailable in the module by itself
|
||
|
expect(instance).to receive(:body) do |data|
|
||
|
data
|
||
|
end
|
||
|
|
||
|
allow(instance).to receive(:current_user) { user }
|
||
|
end
|
||
|
|
||
|
context "single object" do
|
||
|
let_it_be(:presentable) { create(:todo, project: project) }
|
||
|
|
||
|
it { is_expected.to be_a(Gitlab::Json::PrecompiledJson) }
|
||
|
|
||
|
it "uses the presenter" do
|
||
|
expect(presenter).to receive(:represent).with(presentable, project: project)
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
|
||
|
it "is valid JSON" do
|
||
|
parsed = Gitlab::Json.parse(subject.to_s)
|
||
|
|
||
|
expect(parsed).to be_a(Hash)
|
||
|
expect(parsed["id"]).to eq(presentable.id)
|
||
|
end
|
||
|
|
||
|
it "fetches from the cache" do
|
||
|
expect(instance.cache).to receive(:fetch).with("#{presentable.cache_key}:#{user.cache_key}", expires_in: described_class::DEFAULT_EXPIRY).once
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
|
||
|
context "when a cache context is supplied" do
|
||
|
before do
|
||
|
kwargs[:cache_context] = -> (todo) { todo.project.cache_key }
|
||
|
end
|
||
|
|
||
|
it "uses the context to augment the cache key" do
|
||
|
expect(instance.cache).to receive(:fetch).with("#{presentable.cache_key}:#{project.cache_key}", expires_in: described_class::DEFAULT_EXPIRY).once
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "when expires_in is supplied" do
|
||
|
it "sets the expiry when accessing the cache" do
|
||
|
kwargs[:expires_in] = 7.days
|
||
|
|
||
|
expect(instance.cache).to receive(:fetch).with("#{presentable.cache_key}:#{user.cache_key}", expires_in: 7.days).once
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "for a collection of objects" do
|
||
|
let_it_be(:presentable) { Array.new(5).map { create(:todo, project: project) } }
|
||
|
|
||
|
it { is_expected.to be_an(Gitlab::Json::PrecompiledJson) }
|
||
|
|
||
|
it "uses the presenter" do
|
||
|
presentable.each do |todo|
|
||
|
expect(presenter).to receive(:represent).with(todo, project: project)
|
||
|
end
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
|
||
|
it "is valid JSON" do
|
||
|
parsed = Gitlab::Json.parse(subject.to_s)
|
||
|
|
||
|
expect(parsed).to be_an(Array)
|
||
|
|
||
|
presentable.each_with_index do |todo, i|
|
||
|
expect(parsed[i]["id"]).to eq(todo.id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
it "fetches from the cache" do
|
||
|
keys = presentable.map { |todo| "#{todo.cache_key}:#{user.cache_key}" }
|
||
|
|
||
|
expect(instance.cache).to receive(:fetch_multi).with(*keys, expires_in: described_class::DEFAULT_EXPIRY).once.and_call_original
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
|
||
|
context "when a cache context is supplied" do
|
||
|
before do
|
||
|
kwargs[:cache_context] = -> (todo) { todo.project.cache_key }
|
||
|
end
|
||
|
|
||
|
it "uses the context to augment the cache key" do
|
||
|
keys = presentable.map { |todo| "#{todo.cache_key}:#{project.cache_key}" }
|
||
|
|
||
|
expect(instance.cache).to receive(:fetch_multi).with(*keys, expires_in: described_class::DEFAULT_EXPIRY).once.and_call_original
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context "expires_in is supplied" do
|
||
|
it "sets the expiry when accessing the cache" do
|
||
|
keys = presentable.map { |todo| "#{todo.cache_key}:#{user.cache_key}" }
|
||
|
kwargs[:expires_in] = 7.days
|
||
|
|
||
|
expect(instance.cache).to receive(:fetch_multi).with(*keys, expires_in: 7.days).once.and_call_original
|
||
|
|
||
|
subject
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|