diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index 213e4bc56..374708888 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -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 diff --git a/app/controllers/api/v1/experiments_controller.rb b/app/controllers/api/v1/experiments_controller.rb index 4fc0da84b..9539c8ee0 100644 --- a/app/controllers/api/v1/experiments_controller.rb +++ b/app/controllers/api/v1/experiments_controller.rb @@ -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 diff --git a/app/controllers/api/v1/projects_controller.rb b/app/controllers/api/v1/projects_controller.rb index 8c4ec13d5..18e6b8e24 100644 --- a/app/controllers/api/v1/projects_controller.rb +++ b/app/controllers/api/v1/projects_controller.rb @@ -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 diff --git a/app/controllers/api/v1/tasks_controller.rb b/app/controllers/api/v1/tasks_controller.rb index 111e71457..313f300a8 100644 --- a/app/controllers/api/v1/tasks_controller.rb +++ b/app/controllers/api/v1/tasks_controller.rb @@ -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' }, diff --git a/spec/requests/api/v1/projects_controller_spec.rb b/spec/requests/api/v1/projects_controller_spec.rb index ca23f5a1d..965f74d6a 100644 --- a/spec/requests/api/v1/projects_controller_spec.rb +++ b/spec/requests/api/v1/projects_controller_spec.rb @@ -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),