diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 121f5e3cbfeb5206b021f5d48746538105d4dd2e..38f1a4e58bcf8f683c1ac4069b4949ffedd65881 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -25329,6 +25329,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodecisecurefileregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodecisecurefileregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodecisecurefileregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodecisecurefileregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodecisecurefileregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.containerRepositoryRegistries` @@ -25348,6 +25349,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodecontainerrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodecontainerrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodecontainerrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodecontainerrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodecontainerrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.dependencyProxyBlobRegistries` @@ -25371,6 +25373,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodedependencyproxyblobregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodedependencyproxyblobregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodedependencyproxyblobregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodedependencyproxyblobregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodedependencyproxyblobregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.dependencyProxyManifestRegistries` @@ -25390,6 +25393,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodedependencyproxymanifestregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodedependencyproxymanifestregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodedependencyproxymanifestregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodedependencyproxymanifestregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodedependencyproxymanifestregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.designManagementRepositoryRegistries` @@ -25413,6 +25417,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodedesignmanagementrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodedesignmanagementrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodedesignmanagementrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodedesignmanagementrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodedesignmanagementrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.groupWikiRepositoryRegistries` @@ -25432,6 +25437,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodegroupwikirepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodegroupwikirepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodegroupwikirepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodegroupwikirepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodegroupwikirepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.jobArtifactRegistries` @@ -25451,6 +25457,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodejobartifactregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodejobartifactregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodejobartifactregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodejobartifactregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodejobartifactregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.lfsObjectRegistries` @@ -25470,6 +25477,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodelfsobjectregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodelfsobjectregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodelfsobjectregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodelfsobjectregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodelfsobjectregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.mergeRequestDiffRegistries` @@ -25489,6 +25497,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodemergerequestdiffregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodemergerequestdiffregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodemergerequestdiffregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodemergerequestdiffregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodemergerequestdiffregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.packageFileRegistries` @@ -25508,6 +25517,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodepackagefileregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodepackagefileregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodepackagefileregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodepackagefileregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodepackagefileregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.pagesDeploymentRegistries` @@ -25527,6 +25537,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodepagesdeploymentregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodepagesdeploymentregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodepagesdeploymentregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodepagesdeploymentregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodepagesdeploymentregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.pipelineArtifactRegistries` @@ -25546,6 +25557,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodepipelineartifactregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodepipelineartifactregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodepipelineartifactregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodepipelineartifactregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodepipelineartifactregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.projectRepositoryRegistries` @@ -25565,6 +25577,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodeprojectrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodeprojectrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodeprojectrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodeprojectrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodeprojectrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.projectWikiRepositoryRegistries` @@ -25584,6 +25597,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodeprojectwikirepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodeprojectwikirepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodeprojectwikirepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodeprojectwikirepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodeprojectwikirepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.snippetRepositoryRegistries` @@ -25603,6 +25617,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodesnippetrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodesnippetrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodesnippetrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodesnippetrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodesnippetrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.terraformStateVersionRegistries` @@ -25622,6 +25637,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodeterraformstateversionregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodeterraformstateversionregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodeterraformstateversionregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodeterraformstateversionregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodeterraformstateversionregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ##### `GeoNode.uploadRegistries` @@ -25641,6 +25657,7 @@ four standard [pagination arguments](#pagination-arguments): | <a id="geonodeuploadregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. | | <a id="geonodeuploadregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. | | <a id="geonodeuploadregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. | +| <a id="geonodeuploadregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. | | <a id="geonodeuploadregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. | ### `GitlabInstanceFeatureFlag` @@ -41051,6 +41068,19 @@ Geo registry class. | <a id="georegistryclassterraform_state_version_registry"></a>`TERRAFORM_STATE_VERSION_REGISTRY` | Geo::TerraformStateVersionRegistry registry class. | | <a id="georegistryclassupload_registry"></a>`UPLOAD_REGISTRY` | Geo::UploadRegistry registry class. | +### `GeoRegistrySort` + +Values for sorting Geo registries. + +| Value | Description | +| ----- | ----------- | +| <a id="georegistrysortid_asc"></a>`ID_ASC` | ID by ascending order. | +| <a id="georegistrysortid_desc"></a>`ID_DESC` | ID by descending order. | +| <a id="georegistrysortlast_synced_at_asc"></a>`LAST_SYNCED_AT_ASC` | Latest sync date by ascending order. | +| <a id="georegistrysortlast_synced_at_desc"></a>`LAST_SYNCED_AT_DESC` | Latest sync date by descending order. | +| <a id="georegistrysortverified_at_asc"></a>`VERIFIED_AT_ASC` | Latest verification date by ascending order. | +| <a id="georegistrysortverified_at_desc"></a>`VERIFIED_AT_DESC` | Latest verification date by descending order. | + ### `GitlabSubscriptionsAddOnType` Types of add-ons. diff --git a/ee/app/finders/geo/framework_registry_finder.rb b/ee/app/finders/geo/framework_registry_finder.rb index 0b41ed716ab4c2137242301ac59c99ddf87814c1..d79425cd86dbf0df43dc734900ee711cdff5b16b 100644 --- a/ee/app/finders/geo/framework_registry_finder.rb +++ b/ee/app/finders/geo/framework_registry_finder.rb @@ -24,7 +24,7 @@ def execute registry_entries = by_replication_state(registry_entries) registry_entries = by_verification_state(registry_entries) registry_entries = by_keyword(registry_entries) - registry_entries.ordered_by_id + ordered(registry_entries) end private @@ -76,6 +76,15 @@ def by_keyword(registry_entries) registry_entries.with_search(params[:keyword]) end + + def ordered(registry_entries) + if params[:sort].to_s.include?('verified_at') && verification_disabled? + raise ArgumentError, "Sorting by verified_at is not supported " \ + "because verification is not enabled for #{replicator_class.model}" + end + + registry_entries.ordered_by(params[:sort]) + end end end end diff --git a/ee/app/graphql/resolvers/geo/registries_resolver.rb b/ee/app/graphql/resolvers/geo/registries_resolver.rb index 58d644c5ef8015cfbd7df9fe146e5eeaadd17727..5a2d6ccd88a3776d3ad134f6263df350ff8e0795 100644 --- a/ee/app/graphql/resolvers/geo/registries_resolver.rb +++ b/ee/app/graphql/resolvers/geo/registries_resolver.rb @@ -36,6 +36,10 @@ def self.replicator_class milestone: '17.9' } + argument :sort, ::Types::Geo::RegistrySortEnum, + required: false, + description: 'Sort registries by given criteria.' + def resolve(**args) return registry_class.none unless geo_node_is_current? @@ -52,7 +56,8 @@ def registry_finder_params(args) ids: registry_ids(args[:ids]), replication_state: args[:replication_state], verification_state: args[:verification_state], - keyword: args[:keyword] + keyword: args[:keyword], + sort: args[:sort] }.compact end diff --git a/ee/app/graphql/types/geo/registry_sort_enum.rb b/ee/app/graphql/types/geo/registry_sort_enum.rb new file mode 100644 index 0000000000000000000000000000000000000000..69ec403b669861c2bbfe638edc20a6a6a9eddff9 --- /dev/null +++ b/ee/app/graphql/types/geo/registry_sort_enum.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Types + module Geo + class RegistrySortEnum < BaseEnum + graphql_name 'GeoRegistrySort' + description 'Values for sorting Geo registries' + + value 'ID_ASC', description: 'ID by ascending order.', value: :id_asc + value 'ID_DESC', description: 'ID by descending order.', value: :id_desc + value 'VERIFIED_AT_ASC', description: 'Latest verification date by ascending order.', value: :verified_at_asc + value 'VERIFIED_AT_DESC', description: 'Latest verification date by descending order.', value: :verified_at_desc + value 'LAST_SYNCED_AT_ASC', description: 'Latest sync date by ascending order.', value: :last_synced_at_asc + value 'LAST_SYNCED_AT_DESC', description: 'Latest sync date by descending order.', value: :last_synced_at_desc + end + end +end diff --git a/ee/app/models/geo/base_registry.rb b/ee/app/models/geo/base_registry.rb index 263a06ede4484ba263be81ac4f32ec287c13212f..daa463ea1c0c29c2632639f2a9078524c75eef54 100644 --- a/ee/app/models/geo/base_registry.rb +++ b/ee/app/models/geo/base_registry.rb @@ -28,6 +28,23 @@ def self.ordered_by_id order(:id) end + def self.ordered_by(method) + case method.to_s + when 'id_desc' + order(id: :desc) + when 'verified_at_asc' + order(verified_at: :asc) + when 'verified_at_desc' + order(verified_at: :desc) + when 'last_synced_at_asc' + order(last_synced_at: :asc) + when 'last_synced_at_desc' + order(last_synced_at: :desc) + else + ordered_by_id + end + end + def self.after_bulk_mark_update_cursor(bulk_mark_update_cursor) where("id > ?", bulk_mark_update_cursor) end diff --git a/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb b/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..7dfb23c0043fa632fd8215ac133f94e2abf8273e --- /dev/null +++ b/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['GeoRegistrySort'], feature_category: :geo_replication do + it { expect(described_class.graphql_name).to eq('GeoRegistrySort') } + + it 'exposes the correct registry sort parameters' do + parameters = %w[ID_ASC ID_DESC VERIFIED_AT_ASC VERIFIED_AT_DESC LAST_SYNCED_AT_ASC LAST_SYNCED_AT_DESC] + expect(described_class.values.keys).to include(*parameters) + end +end diff --git a/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb b/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb index 413624110ee7d4e6f7df045c5df3ebb30c423d23..8490a6b368a9104e752976befaf5f336b4458e0a 100644 --- a/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb +++ b/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb @@ -5,20 +5,29 @@ let(:replicator_class) { Gitlab::Geo::Replicator.for_class_name(described_class.name) } let(:model_class) { replicator_class.model } - let(:factory_traits) { replicator_class.verification_enabled? ? [:synced, :verification_succeeded] : [:synced] } - - # rubocop:disable Rails/SaveBang - let!(:registry1) { create(registry_factory, :synced) } - let!(:registry2) { create(registry_factory, *factory_traits) } - let!(:registry3) { create(registry_factory) } - let!(:registry4) { create(registry_factory, *factory_traits) } - # rubocop:enable Rails/SaveBang let(:params) { {} } - subject(:registries) { described_class.new(user, params).execute } + before do + # Make sure a Geo node is stubbed to ensure .verification_enabled? doesn't return false + stub_current_geo_node(create(:geo_node)) + end describe '#execute' do + let(:factory_traits) do + replicator_class.verification_enabled? ? [:synced, :verification_succeeded] : [:synced] + end + + # rubocop:disable Rails/SaveBang -- This is not creating a record but a factory. + # See Rubocop issue: https://github.com/thoughtbot/factory_bot/issues/1620 + let!(:registry1) { create(registry_factory, :synced) } + let!(:registry2) { create(registry_factory, *factory_traits) } + let!(:registry3) { create(registry_factory) } + let!(:registry4) { create(registry_factory, *factory_traits) } + # rubocop:enable Rails/SaveBang + + subject(:registries) { described_class.new(user, params).execute } + context 'when user cannot read all Geo' do let_it_be(:user) { create(:user) } @@ -155,6 +164,67 @@ def searchable_attributes end end + context 'with a sort param' do + context 'when sorting by id descending' do + let(:params) { { sort: 'id_desc' } } + + it 'returns all registries sorted by id desc' do + expected_result = [registry4, registry3, registry2, registry1] + + expect(registries.to_a).to eq(expected_result) + end + end + + context 'when sorting by last_synced_at ascending' do + let(:params) { { sort: 'last_synced_at_asc' } } + + it 'returns all registries sorted by last_synced_at asc' do + expected_result = [registry1, registry2, registry4, registry3] + + expect(registries.to_a).to eq(expected_result) + end + end + + context 'when sorting by verified_at' do + let(:params) { { sort: 'verified_at_desc' } } + + context 'with verification enabled' do + before do + skip_if_verification_is_not_enabled + end + + it 'returns all registries sorted by verified_at desc' do + expected_result = [registry1, registry3, registry4, registry2] + + expect(registries.to_a).to eq(expected_result) + end + end + + context 'with verification disabled' do + before do + skip_if_verification_is_enabled + end + + it 'raises ArgumentError' do + message = "Sorting by verified_at is not supported " \ + "because verification is not enabled for #{replicator_class.model}" + + expect { registries }.to raise_error(ArgumentError, message) + end + end + end + end + + context 'with a nil sort param' do + let(:params) { { sort: nil } } + + it 'returns all registries sorted by id ascending' do + expected_result = [registry1, registry2, registry3, registry4] + + expect(registries.to_a).to eq(expected_result) + end + end + context 'with no params' do it 'returns all registries' do expect(registries.to_a).to contain_exactly(registry1, registry2, registry3, registry4) diff --git a/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb b/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb index 88726d80fc94eca8eef9c6c9addfc0fb712f3da7..70b17d1daf533e68ab89a9f97e5d80f225b829e7 100644 --- a/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb +++ b/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb @@ -53,6 +53,15 @@ end end + context 'when the sort argument is present' do + it 'returns all registries in sort order' do + args = { sort: 'id_desc'.upcase } + expected = [registry4, registry3, registry2, registry1] + + expect(resolve_registries(args).to_a).to eq(expected) + end + end + context 'with verification enabled' do before do skip_if_verification_is_not_enabled @@ -66,6 +75,15 @@ expect(resolve_registries(args).to_a).to eq(expected) end end + + context 'when the verified_at sort argument is present' do + it 'returns registries with requested verified_at, in order' do + args = { sort: 'verified_at_asc'.upcase } + expected = [registry2, registry4, registry1, registry3] + + expect(resolve_registries(args).to_a).to eq(expected) + end + end end context 'with verification disabled' do @@ -82,6 +100,16 @@ expect { resolve_registries(args) }.to raise_error(ArgumentError, message) end end + + context 'when the verified_at sort argument is present' do + it 'raises ArgumentError' do + args = { sort: 'verified_at_asc'.upcase } + message = "Sorting by verified_at is not supported " \ + "because verification is not enabled for #{replicator_class.model}" + + expect { resolve_registries(args) }.to raise_error(ArgumentError, message) + end + end end end diff --git a/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb b/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb index ff911159281e8b3cdeb5c99d587614844bdc2b7d..e4d8254fcc5f9e30709c3b54fa634014de12b9fe 100644 --- a/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb +++ b/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb @@ -100,6 +100,38 @@ end end + describe '.ordered_by' do + let!(:registry1) { create(registry_class_factory, last_synced_at: 3.hours.ago, verified_at: 6.hours.ago) } + let!(:registry2) { create(registry_class_factory, last_synced_at: 6.hours.ago, verified_at: 3.hours.ago) } + # rubocop:disable Rails/SaveBang -- Rubocop believes this is a record creation, not factory :( + let!(:registry3) { create(registry_class_factory) } + # rubocop:enable Rails/SaveBang + + it 'orders records by id ASC by default' do + expect(described_class.ordered_by('').to_a).to eq([registry1, registry2, registry3]) + end + + it 'orders records by id DESC' do + expect(described_class.ordered_by('id_desc').to_a).to eq([registry3, registry2, registry1]) + end + + it 'orders records by last_synced_at DESC' do + expect(described_class.ordered_by('last_synced_at_desc').to_a).to eq([registry3, registry1, registry2]) + end + + it 'orders records by last_synced_at ASC' do + expect(described_class.ordered_by('last_synced_at_asc').to_a).to eq([registry2, registry1, registry3]) + end + + it 'orders records by verified_at DESC' do + expect(described_class.ordered_by('verified_at_desc').to_a).to eq([registry3, registry2, registry1]) + end + + it 'orders records by verified_at ASC' do + expect(described_class.ordered_by('verified_at_asc').to_a).to eq([registry1, registry2, registry3]) + end + end + describe '.fail_sync_timeouts' do it 'marks started records as failed if they are expired' do record1 = create(registry_class_factory, :started, last_synced_at: 9.hours.ago)