Commit 9eae1060 authored by Adam Hegyi's avatar Adam Hegyi

Add filtering by recorded at date to measurements

This change adds filtering capabilities by recorded at to instance
statistics measurements GraphQL api.
parent 37ff491b
...@@ -13,10 +13,20 @@ module Resolvers ...@@ -13,10 +13,20 @@ module Resolvers
required: true, required: true,
description: 'The type of measurement/statistics to retrieve' description: 'The type of measurement/statistics to retrieve'
def resolve(identifier:) argument :recorded_after, Types::TimeType,
required: false,
description: 'Measurement recorded after this date'
argument :recorded_before, Types::TimeType,
required: false,
description: 'Measurement recorded before this date'
def resolve(identifier:, recorded_before: nil, recorded_after: nil)
authorize! authorize!
::Analytics::InstanceStatistics::Measurement ::Analytics::InstanceStatistics::Measurement
.recorded_after(recorded_after)
.recorded_before(recorded_before)
.with_identifier(identifier) .with_identifier(identifier)
.order_by_latest .order_by_latest
end end
......
...@@ -36,6 +36,8 @@ module Analytics ...@@ -36,6 +36,8 @@ module Analytics
scope :order_by_latest, -> { order(recorded_at: :desc) } scope :order_by_latest, -> { order(recorded_at: :desc) }
scope :with_identifier, -> (identifier) { where(identifier: identifier) } scope :with_identifier, -> (identifier) { where(identifier: identifier) }
scope :recorded_after, -> (date) { where(self.model.arel_table[:recorded_at].gteq(date)) if date.present? }
scope :recorded_before, -> (date) { where(self.model.arel_table[:recorded_at].lteq(date)) if date.present? }
def self.measurement_identifier_values def self.measurement_identifier_values
identifiers.values identifiers.values
......
---
title: Add filtering by recorded date to instance statistics measurements GraphQL API
merge_request: 46344
author:
type: changed
...@@ -16452,6 +16452,16 @@ type Query { ...@@ -16452,6 +16452,16 @@ type Query {
Returns the last _n_ elements from the list. Returns the last _n_ elements from the list.
""" """
last: Int last: Int
"""
Measurement recorded after this date
"""
recordedAfter: Time
"""
Measurement recorded before this date
"""
recordedBefore: Time
): InstanceStatisticsMeasurementConnection ): InstanceStatisticsMeasurementConnection
""" """
......
...@@ -47741,6 +47741,26 @@ ...@@ -47741,6 +47741,26 @@
}, },
"defaultValue": null "defaultValue": null
}, },
{
"name": "recordedAfter",
"description": "Measurement recorded after this date",
"type": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
},
"defaultValue": null
},
{
"name": "recordedBefore",
"description": "Measurement recorded before this date",
"type": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
},
"defaultValue": null
},
{ {
"name": "after", "name": "after",
"description": "Returns the elements in the list that come after the specified cursor.", "description": "Returns the elements in the list that come after the specified cursor.",
...@@ -14,7 +14,9 @@ RSpec.describe Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsReso ...@@ -14,7 +14,9 @@ RSpec.describe Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsReso
let_it_be(:project_measurement_new) { create(:instance_statistics_measurement, :project_count, recorded_at: 2.days.ago) } let_it_be(:project_measurement_new) { create(:instance_statistics_measurement, :project_count, recorded_at: 2.days.ago) }
let_it_be(:project_measurement_old) { create(:instance_statistics_measurement, :project_count, recorded_at: 10.days.ago) } let_it_be(:project_measurement_old) { create(:instance_statistics_measurement, :project_count, recorded_at: 10.days.ago) }
subject { resolve_measurements({ identifier: 'projects' }, { current_user: current_user }) } let(:arguments) { { identifier: 'projects' } }
subject { resolve_measurements(arguments, { current_user: current_user }) }
context 'when requesting project count measurements' do context 'when requesting project count measurements' do
context 'as an admin user' do context 'as an admin user' do
...@@ -40,6 +42,24 @@ RSpec.describe Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsReso ...@@ -40,6 +42,24 @@ RSpec.describe Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsReso
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end end
end end
context 'when filtering by recorded_after and recorded_before' do
before do
arguments[:recorded_after] = 4.days.ago
arguments[:recorded_before] = 1.day.ago
end
it { is_expected.to match_array([project_measurement_new]) }
context 'when "incorrect" values are passed' do
before do
arguments[:recorded_after] = 1.day.ago
arguments[:recorded_before] = 4.days.ago
end
it { is_expected.to be_empty }
end
end
end end
context 'when requesting pipeline counts by pipeline status' do context 'when requesting pipeline counts by pipeline status' do
......
...@@ -45,6 +45,34 @@ RSpec.describe Analytics::InstanceStatistics::Measurement, type: :model do ...@@ -45,6 +45,34 @@ RSpec.describe Analytics::InstanceStatistics::Measurement, type: :model do
it { is_expected.to match_array([measurement_1, measurement_2]) } it { is_expected.to match_array([measurement_1, measurement_2]) }
end end
describe '.recorded_after' do
subject { described_class.recorded_after(8.days.ago) }
it { is_expected.to match_array([measurement_2, measurement_3]) }
context 'when nil is given' do
subject { described_class.recorded_after(nil) }
it 'does not apply filtering' do
expect(subject).to match_array([measurement_1, measurement_2, measurement_3])
end
end
end
describe '.recorded_before' do
subject { described_class.recorded_before(4.days.ago) }
it { is_expected.to match_array([measurement_1, measurement_3]) }
context 'when nil is given' do
subject { described_class.recorded_after(nil) }
it 'does not apply filtering' do
expect(subject).to match_array([measurement_1, measurement_2, measurement_3])
end
end
end
end end
describe '#measurement_identifier_values' do describe '#measurement_identifier_values' do
......
...@@ -9,7 +9,8 @@ RSpec.describe 'InstanceStatisticsMeasurements' do ...@@ -9,7 +9,8 @@ RSpec.describe 'InstanceStatisticsMeasurements' do
let!(:instance_statistics_measurement_1) { create(:instance_statistics_measurement, :project_count, recorded_at: 20.days.ago, count: 5) } let!(:instance_statistics_measurement_1) { create(:instance_statistics_measurement, :project_count, recorded_at: 20.days.ago, count: 5) }
let!(:instance_statistics_measurement_2) { create(:instance_statistics_measurement, :project_count, recorded_at: 10.days.ago, count: 10) } let!(:instance_statistics_measurement_2) { create(:instance_statistics_measurement, :project_count, recorded_at: 10.days.ago, count: 10) }
let(:query) { graphql_query_for(:instanceStatisticsMeasurements, 'identifier: PROJECTS', 'nodes { count identifier }') } let(:arguments) { 'identifier: PROJECTS' }
let(:query) { graphql_query_for(:instanceStatisticsMeasurements, arguments, 'nodes { count identifier }') }
before do before do
post_graphql(query, current_user: current_user) post_graphql(query, current_user: current_user)
...@@ -21,4 +22,14 @@ RSpec.describe 'InstanceStatisticsMeasurements' do ...@@ -21,4 +22,14 @@ RSpec.describe 'InstanceStatisticsMeasurements' do
{ "count" => 5, 'identifier' => 'PROJECTS' } { "count" => 5, 'identifier' => 'PROJECTS' }
]) ])
end end
context 'with recorded_at filters' do
let(:arguments) { %(identifier: PROJECTS, recordedAfter: "#{15.days.ago.to_date}", recordedBefore: "#{5.days.ago.to_date}") }
it 'returns filtered measurement objects' do
expect(graphql_data.dig('instanceStatisticsMeasurements', 'nodes')).to eq([
{ "count" => 10, 'identifier' => 'PROJECTS' }
])
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment