summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/sidekiq_middleware/worker_context/client_spec.rb
blob: 3baa0c6f9676bc771660f9913f441660cc1af08f (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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do
  let(:worker_class) do
    Class.new do
      def self.name
        'TestWithContextWorker'
      end

      include ApplicationWorker

      feature_category :team_planning

      def self.job_for_args(args)
        jobs.find { |job| job['args'] == args }
      end

      def perform(*args)
      end
    end
  end

  let(:not_owned_worker_class) do
    Class.new(worker_class) do
      def self.name
        'TestNotOwnedWithContextWorker'
      end

      feature_category :not_owned
    end
  end

  let(:mailer_class) do
    Class.new(ApplicationMailer) do
      def self.name
        'TestMailer'
      end

      def test_mail
      end
    end
  end

  before do
    stub_const(worker_class.name, worker_class)
    stub_const(not_owned_worker_class.name, not_owned_worker_class)
    stub_const(mailer_class.name, mailer_class)
  end

  describe "#call" do
    it 'applies a context for jobs scheduled in batch' do
      user_per_job = { 'job1' => build_stubbed(:user, username: 'user-1'),
                       'job2' => build_stubbed(:user, username: 'user-2') }

      TestWithContextWorker.bulk_perform_async_with_contexts(
        %w(job1 job2),
        arguments_proc: -> (name) { [name, 1, 2, 3] },
        context_proc: -> (name) { { user: user_per_job[name] } }
      )

      job1 = TestWithContextWorker.job_for_args(['job1', 1, 2, 3])
      job2 = TestWithContextWorker.job_for_args(['job2', 1, 2, 3])

      expect(job1['meta.user']).to eq(user_per_job['job1'].username)
      expect(job2['meta.user']).to eq(user_per_job['job2'].username)
    end

    context 'when the feature category is set in the context_proc' do
      it 'takes the feature category from the worker, not the caller' do
        TestWithContextWorker.bulk_perform_async_with_contexts(
          %w(job1 job2),
          arguments_proc: -> (name) { [name, 1, 2, 3] },
          context_proc: -> (_) { { feature_category: 'code_review' } }
        )

        job1 = TestWithContextWorker.job_for_args(['job1', 1, 2, 3])
        job2 = TestWithContextWorker.job_for_args(['job2', 1, 2, 3])

        expect(job1['meta.feature_category']).to eq('team_planning')
        expect(job2['meta.feature_category']).to eq('team_planning')
      end

      it 'takes the feature category from the caller if the worker is not owned' do
        TestNotOwnedWithContextWorker.bulk_perform_async_with_contexts(
          %w(job1 job2),
          arguments_proc: -> (name) { [name, 1, 2, 3] },
          context_proc: -> (_) { { feature_category: 'code_review' } }
        )

        job1 = TestNotOwnedWithContextWorker.job_for_args(['job1', 1, 2, 3])
        job2 = TestNotOwnedWithContextWorker.job_for_args(['job2', 1, 2, 3])

        expect(job1['meta.feature_category']).to eq('code_review')
        expect(job2['meta.feature_category']).to eq('code_review')
      end

      it 'does not set any explicit feature category for mailers', :sidekiq_mailers do
        expect(Gitlab::ApplicationContext).not_to receive(:with_context)

        TestMailer.test_mail.deliver_later
      end
    end

    context 'when the feature category is already set in the surrounding block' do
      it 'takes the feature category from the worker, not the caller' do
        Gitlab::ApplicationContext.with_context(feature_category: 'authentication_and_authorization') do
          TestWithContextWorker.bulk_perform_async_with_contexts(
            %w(job1 job2),
            arguments_proc: -> (name) { [name, 1, 2, 3] },
            context_proc: -> (_) { {} }
          )
        end

        job1 = TestWithContextWorker.job_for_args(['job1', 1, 2, 3])
        job2 = TestWithContextWorker.job_for_args(['job2', 1, 2, 3])

        expect(job1['meta.feature_category']).to eq('team_planning')
        expect(job2['meta.feature_category']).to eq('team_planning')
      end

      it 'takes the feature category from the caller if the worker is not owned' do
        Gitlab::ApplicationContext.with_context(feature_category: 'authentication_and_authorization') do
          TestNotOwnedWithContextWorker.bulk_perform_async_with_contexts(
            %w(job1 job2),
            arguments_proc: -> (name) { [name, 1, 2, 3] },
            context_proc: -> (_) { {} }
          )
        end

        job1 = TestNotOwnedWithContextWorker.job_for_args(['job1', 1, 2, 3])
        job2 = TestNotOwnedWithContextWorker.job_for_args(['job2', 1, 2, 3])

        expect(job1['meta.feature_category']).to eq('authentication_and_authorization')
        expect(job2['meta.feature_category']).to eq('authentication_and_authorization')
      end
    end
  end
end