summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/lib/cache_helpers_shared_examples.rb
blob: 845fa78a82767fdb8263ce28dade4eed93a27f08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# frozen_string_literal: true

RSpec.shared_examples_for 'object cache helper' do
  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("#{presenter.class.name}:#{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] = -> (item) { item.project.cache_key }
    end

    it "uses the context to augment the cache key" do
      expect(instance.cache).to receive(:fetch).with("#{presenter.class.name}:#{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("#{presenter.class.name}:#{presentable.cache_key}:#{user.cache_key}", expires_in: 7.days).once

      subject
    end
  end
end

RSpec.shared_examples_for 'collection cache helper' do
  it { is_expected.to be_an(Gitlab::Json::PrecompiledJson) }

  it "uses the presenter" do
    presentable.each do |item|
      expect(presenter).to receive(:represent).with(item, 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 |item, i|
      expect(parsed[i]["id"]).to eq(item.id)
    end
  end

  it "fetches from the cache" do
    keys = presentable.map { |item| "#{presenter.class.name}:#{item.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] = -> (item) { item.project.cache_key }
    end

    it "uses the context to augment the cache key" do
      keys = presentable.map { |item| "#{presenter.class.name}:#{item.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 { |item| "#{presenter.class.name}:#{item.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