diff options
Diffstat (limited to 'spec/lib/gitlab/graphql')
5 files changed, 134 insertions, 39 deletions
diff --git a/spec/lib/gitlab/graphql/docs/renderer_spec.rb b/spec/lib/gitlab/graphql/docs/renderer_spec.rb index 81ef7fcda97..d1be962a4f8 100644 --- a/spec/lib/gitlab/graphql/docs/renderer_spec.rb +++ b/spec/lib/gitlab/graphql/docs/renderer_spec.rb @@ -36,10 +36,10 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do specify do expectation = <<~DOC - ## ArrayTest + ### ArrayTest - | Name | Type | Description | - | --- | ---- | ---------- | + | Field | Type | Description | + | ----- | ---- | ----------- | | `foo` | String! => Array | A description | DOC @@ -59,10 +59,10 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do specify do expectation = <<~DOC - ## OrderingTest + ### OrderingTest - | Name | Type | Description | - | --- | ---- | ---------- | + | Field | Type | Description | + | ----- | ---- | ----------- | | `bar` | String! | A description of bar field | | `foo` | String! | A description of foo field | DOC @@ -82,15 +82,45 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do specify do expectation = <<~DOC - ## DeprecatedTest + ### DeprecatedTest - | Name | Type | Description | - | --- | ---- | ---------- | + | Field | Type | Description | + | ----- | ---- | ----------- | | `foo` **{warning-solid}** | String! | **Deprecated:** This is deprecated. Deprecated in 1.10 | DOC is_expected.to include(expectation) end end + + context 'A type with an emum field' do + let(:type) do + enum_type = Class.new(Types::BaseEnum) do + graphql_name 'MyEnum' + + value 'BAZ', description: 'A description of BAZ' + value 'BAR', description: 'A description of BAR', deprecated: { reason: 'This is deprecated', milestone: '1.10' } + end + + Class.new(Types::BaseObject) do + graphql_name 'EnumTest' + + field :foo, enum_type, null: false, description: 'A description of foo field' + end + end + + specify do + expectation = <<~DOC + ### MyEnum + + | Value | Description | + | ----- | ----------- | + | `BAR` **{warning-solid}** | **Deprecated:** This is deprecated. Deprecated in 1.10 | + | `BAZ` | A description of BAZ | + DOC + + is_expected.to include(expectation) + end + end end end diff --git a/spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb b/spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb index 180966de895..33a9d40931e 100644 --- a/spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb +++ b/spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb @@ -6,9 +6,26 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do subject { described_class.new(parent, finder) } let(:params) { HashWithIndifferentAccess.new } + let(:finder_params) { finder.params.to_h.with_indifferent_access } + + # Dumb finder class, that only implements what we need, and has + # predictable query counts. + let(:finder_class) do + Class.new(IssuesFinder) do + def execute + params[:project_id].issues.where(iid: params[:iids]) + end + + private + + def params_class + IssuesFinder::Params + end + end + end describe '#find_all' do - let(:finder) { double(:finder, params: params, execute: %i[x y z]) } + let(:finder) { issuable_finder(params: params, result: [:x, :y, :z]) } where(:factory, :param_name) do %i[project group].map { |thing| [thing, :"#{thing}_id"] } @@ -19,7 +36,7 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do it 'assignes the parent parameter, and batching_find_alls the finder' do expect(subject.find_all).to contain_exactly(:x, :y, :z) - expect(params).to include(param_name => parent) + expect(finder_params).to include(param_name => parent) end end @@ -34,12 +51,12 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do describe '#batching_find_all' do context 'the finder params are anything other than [iids]' do - let(:finder) { double(:finder, params: params, execute: [:foo]) } + let(:finder) { issuable_finder(params: params, result: [:foo]) } let(:parent) { build_stubbed(:project) } it 'batching_find_alls the finder, setting the correct parent parameter' do expect(subject.batching_find_all).to eq([:foo]) - expect(params[:project_id]).to eq(parent) + expect(finder_params[:project_id]).to eq(parent) end it 'allows a post-process block' do @@ -48,23 +65,6 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do end context 'the finder params are exactly [iids]' do - # Dumb finder class, that only implements what we need, and has - # predictable query counts. - let(:finder_class) do - Class.new do - attr_reader :current_user, :params - - def initialize(user, args) - @current_user = user - @params = HashWithIndifferentAccess.new(args.to_h) - end - - def execute - params[:project_id].issues.where(iid: params[:iids]) - end - end - end - it 'batches requests' do issue_a = create(:issue) issue_b = create(:issue) @@ -93,4 +93,13 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do end end end + + private + + def issuable_finder(user: double(:user), params: {}, result: nil) + new_finder = finder_class.new(user, params) + allow(new_finder).to receive(:execute).and_return(result) if result + + new_finder + end end diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb index 09d7e084172..c8f368b15fc 100644 --- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb +++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb @@ -262,6 +262,22 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do end end + context 'when ordering by similarity' do + let!(:project1) { create(:project, name: 'test') } + let!(:project2) { create(:project, name: 'testing') } + let!(:project3) { create(:project, name: 'tests') } + let!(:project4) { create(:project, name: 'testing stuff') } + let!(:project5) { create(:project, name: 'test') } + + let(:nodes) do + Project.sorted_by_similarity_desc('test', include_in_select: true) + end + + let(:descending_nodes) { nodes.to_a } + + it_behaves_like 'nodes are in descending order' + end + context 'when an invalid cursor is provided' do let(:arguments) { { before: Base64Bp.urlsafe_encode64('invalidcursor', padding: false) } } @@ -358,15 +374,6 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do end end - context 'when before and last does not request all remaining nodes' do - let(:arguments) { { before: encoded_cursor(project_list.last), last: 2 } } - - it 'has a previous and a next' do - expect(subject.has_previous_page).to be_truthy - expect(subject.has_next_page).to be_truthy - end - end - context 'when before and last does request all remaining nodes' do let(:arguments) { { before: encoded_cursor(project_list[1]), last: 3 } } diff --git a/spec/lib/gitlab/graphql/pagination/keyset/order_info_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/order_info_spec.rb index 9f310f30253..444c10074a0 100644 --- a/spec/lib/gitlab/graphql/pagination/keyset/order_info_spec.rb +++ b/spec/lib/gitlab/graphql/pagination/keyset/order_info_spec.rb @@ -51,6 +51,18 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::OrderInfo do expect(order_list.last.operator_for(:after)).to eq '>' end end + + context 'when ordering by SIMILARITY' do + let(:relation) { Project.sorted_by_similarity_desc('test', include_in_select: true) } + + it 'assigns the right attribute name, named function, and direction' do + expect(order_list.count).to eq 2 + expect(order_list.first.attribute_name).to eq 'similarity' + expect(order_list.first.named_function).to be_kind_of(Arel::Nodes::Addition) + expect(order_list.first.named_function.to_sql).to include 'SIMILARITY(' + expect(order_list.first.sort_direction).to eq :desc + end + end end describe '#validate_ordering' do diff --git a/spec/lib/gitlab/graphql/pagination/keyset/query_builder_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/query_builder_spec.rb index 31c02fd43e8..c7e7db4d535 100644 --- a/spec/lib/gitlab/graphql/pagination/keyset/query_builder_spec.rb +++ b/spec/lib/gitlab/graphql/pagination/keyset/query_builder_spec.rb @@ -131,5 +131,42 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::QueryBuilder do end end end + + context 'when sorting using SIMILARITY' do + let(:relation) { Project.sorted_by_similarity_desc('test', include_in_select: true) } + let(:arel_table) { Project.arel_table } + let(:decoded_cursor) { { 'similarity' => 0.5, 'id' => 100 } } + let(:similarity_sql) do + [ + '(SIMILARITY(COALESCE("projects"."path", \'\'), \'test\') * CAST(\'1\' AS numeric))', + '(SIMILARITY(COALESCE("projects"."name", \'\'), \'test\') * CAST(\'0.7\' AS numeric))', + '(SIMILARITY(COALESCE("projects"."description", \'\'), \'test\') * CAST(\'0.2\' AS numeric))' + ].join(' + ') + end + + context 'when no values are nil' do + context 'when :after' do + it 'generates the correct condition' do + conditions = builder.conditions.gsub(/\s+/, ' ') + + expect(conditions).to include "(#{similarity_sql} < 0.5)" + expect(conditions).to include '"projects"."id" < 100' + expect(conditions).to include "OR (#{similarity_sql} IS NULL)" + end + end + + context 'when :before' do + let(:before_or_after) { :before } + + it 'generates the correct condition' do + conditions = builder.conditions.gsub(/\s+/, ' ') + + expect(conditions).to include "(#{similarity_sql} > 0.5)" + expect(conditions).to include '"projects"."id" > 100' + expect(conditions).to include "OR ( #{similarity_sql} = 0.5" + end + end + end + end end end |