Implement metadata filtering in the API [SCI-11775]

This commit is contained in:
Oleksii Kriuchykhin 2025-04-17 17:22:03 +02:00
parent 3caec16c1c
commit d52176a8d1
5 changed files with 33 additions and 13 deletions

View file

@ -271,6 +271,13 @@ module Api
records
end
def metadata_filter(records)
metadata_filter = params.permit(filter: { metadata: {} }).to_h
return records if metadata_filter.dig(:filter, :metadata).blank?
records.where('metadata @> ?', metadata_filter[:filter][:metadata].to_json)
end
end
end
end

View file

@ -11,9 +11,10 @@ module Api
before_action :load_experiment_for_managing, only: %i(update)
def index
experiments = timestamps_filter(@project.experiments)
experiments = archived_filter(experiments).page(params.dig(:page, :number))
.per(params.dig(:page, :size))
experiments = @project.experiments
experiments = metadata_filter(archived_filter(timestamps_filter(experiments)))
.page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: experiments, each_serializer: ExperimentSerializer, scope: { metadata: params['with-metadata'] == 'true' }
end

View file

@ -11,9 +11,10 @@ module Api
before_action :load_project_for_managing, only: %i(update)
def index
projects = timestamps_filter(@team.projects.visible_to(current_user, @team))
projects = archived_filter(projects).page(params.dig(:page, :number))
.per(params.dig(:page, :size))
projects = @team.projects.visible_to(current_user, @team)
projects = metadata_filter(timestamps_filter(archived_filter(projects)))
.page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: projects, each_serializer: ProjectSerializer, scope: { metadata: params['with-metadata'] == 'true' }, include: include_params
end

View file

@ -15,12 +15,10 @@ module Api
before_action :load_task, only: :activities
def index
tasks =
timestamps_filter(
@experiment.my_modules
).includes(:my_module_status, :my_modules, :my_module_antecessors)
tasks = archived_filter(tasks).page(params.dig(:page, :number))
.per(params.dig(:page, :size))
tasks = @experiment.my_modules.includes(:my_module_status, :my_modules, :my_module_antecessors)
tasks = metadata_filter(archived_filter(timestamps_filter(tasks)))
.page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: tasks, each_serializer: TaskSerializer,
scope: { metadata: params['with-metadata'] == 'true' },

View file

@ -11,7 +11,7 @@ RSpec.describe 'Api::V1::ProjectsController', type: :request do
# valid_projects
2.times do
project = create(:project, name: Faker::Name.unique.name, created_by: @user, team: @team1)
project = create(:project, name: Faker::Name.unique.name, created_by: @user, team: @team1, metadata: { environment: 'test' })
end
2.times do
project = create(:project, name: Faker::Name.unique.name, created_by: @user, team: @team1, archived: true)
@ -72,6 +72,19 @@ RSpec.describe 'Api::V1::ProjectsController', type: :request do
)
end
it 'Response with correct projects, filtered by metadata' do
hash_body = nil
get api_v1_team_projects_path(team_id: @team1.id, 'with-metadata' => 'true', filter: { metadata: { environment: :test } }), headers: @valid_headers
expect { hash_body = json }.not_to raise_exception
expect(hash_body[:data]).to match(
JSON.parse(
ActiveModelSerializers::SerializableResource
.new(@team1.projects.where('metadata @> ?', { environment: 'test'}.to_json), each_serializer: Api::V1::ProjectSerializer, scope: { metadata: true })
.to_json
)['data']
)
end
it 'When invalid request, user in not member of the team' do
hash_body = nil
get api_v1_team_projects_path(team_id: @team2.id),