summaryrefslogtreecommitdiff
path: root/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
blob: d98138f6385a30754d1a15bef657ef5a8d4f551a (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Resolvers::DesignManagement::VersionsResolver do
  include GraphqlHelpers
  include DesignManagementTestHelpers

  describe '#resolve' do
    let(:resolver) { described_class }
    let_it_be(:issue) { create(:issue) }
    let_it_be(:authorized_user) { create(:user) }
    let_it_be(:first_version) { create(:design_version, issue: issue) }
    let_it_be(:other_version) { create(:design_version, issue: issue) }
    let_it_be(:first_design) { create(:design, issue: issue, versions: [first_version, other_version]) }
    let_it_be(:other_design) { create(:design, :with_versions, issue: issue) }

    let(:project) { issue.project }
    let(:params) { {} }
    let(:current_user) { authorized_user }
    let(:parent_args) { { irrelevant: 1.2 } }
    let(:parent) { double('Parent', parent: nil, irep_node: double(arguments: parent_args)) }

    before do
      enable_design_management
      project.add_developer(authorized_user)
    end

    shared_examples 'a source of versions' do
      subject(:result) { resolve_versions(object)&.to_a }

      let_it_be(:all_versions) { object.versions.ordered }

      context 'when the user is not authorized' do
        let(:current_user) { create(:user) }

        it { is_expected.to be_empty }
      end

      context 'without constraints' do
        it 'returns the ordered versions' do
          expect(result.to_a).to eq(all_versions)
        end

        context 'loading associations' do
          it 'prevents N+1 queries when loading author' do
            control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
              resolve_versions(object).items.map(&:author)
            end.count

            create_list(:design_version, 3, issue: issue)

            expect do
              resolve_versions(object).items.map(&:author)
            end.not_to exceed_all_query_limit(control_count)
          end
        end
      end

      context 'when constrained' do
        let_it_be(:matching) { all_versions.earlier_or_equal_to(first_version) }

        shared_examples 'a query for all_versions up to the first_version' do
          it { is_expected.to eq(matching) }
        end

        context 'by earlier_or_equal_to_id' do
          let(:params) { { earlier_or_equal_to_id: global_id_of(first_version) } }

          it_behaves_like 'a query for all_versions up to the first_version'
        end

        context 'by earlier_or_equal_to_sha' do
          let(:params) { { earlier_or_equal_to_sha: first_version.sha } }

          it_behaves_like 'a query for all_versions up to the first_version'
        end

        context 'by earlier_or_equal_to_sha AND earlier_or_equal_to_id' do
          context 'and they match' do
            # This usage is rather dumb, but so long as they match, this will
            # return successfully
            let(:params) do
              {
                earlier_or_equal_to_sha: first_version.sha,
                earlier_or_equal_to_id:  global_id_of(first_version)
              }
            end

            it_behaves_like 'a query for all_versions up to the first_version'
          end

          context 'and they do not match' do
            let(:params) do
              {
                earlier_or_equal_to_sha: first_version.sha,
                earlier_or_equal_to_id:  global_id_of(other_version)
              }
            end

            it 'generates a suitable error' do
              expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
                result
              end
            end
          end
        end

        context 'by at_version in parent' do
          let(:parent_args) { { atVersion: global_id_of(first_version) } }

          it_behaves_like 'a query for all_versions up to the first_version'
        end
      end
    end

    describe 'a design collection' do
      let_it_be(:object) { DesignManagement::DesignCollection.new(issue) }

      it_behaves_like 'a source of versions'
    end

    describe 'a design' do
      let_it_be(:object) { first_design }

      it_behaves_like 'a source of versions'
    end

    def resolve_versions(obj, context = { current_user: current_user })
      eager_resolve(resolver, obj: obj, parent: parent, args: params, ctx: context)
    end
  end
end