diff --git a/app/controllers/api/v1/results_controller.rb b/app/controllers/api/v1/results_controller.rb index 938c4e20a..4d2137fb9 100644 --- a/app/controllers/api/v1/results_controller.rb +++ b/app/controllers/api/v1/results_controller.rb @@ -35,18 +35,17 @@ module Api def load_vars @team = Team.find(params.require(:team_id)) - render jsonapi: {}, status: :forbidden unless can_read_team?(@team) - + unless can_read_team?(@team) + return render jsonapi: {}, status: :forbidden + end @project = @team.projects.find(params.require(:project_id)) - render jsonapi: {}, status: :forbidden unless can_read_project?( - @project - ) - + unless can_read_project?(@project) + return render jsonapi: {}, status: :forbidden + end @experiment = @project.experiments.find(params.require(:experiment_id)) - render jsonapi: {}, status: :forbidden unless can_read_experiment?( - @experiment - ) - + unless can_read_experiment?(@experiment) + return render jsonapi: {}, status: :forbidden + end @task = @experiment.my_modules.find(params.require(:task_id)) end diff --git a/spec/factories/experiments.rb b/spec/factories/experiments.rb index d2ab428e3..498c591b1 100644 --- a/spec/factories/experiments.rb +++ b/spec/factories/experiments.rb @@ -1,6 +1,6 @@ FactoryBot.define do factory :experiment do - name 'My Experiment' + name { Faker::Name.unique.name } description 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' end diff --git a/spec/factories/result.rb b/spec/factories/result.rb new file mode 100644 index 000000000..c7ae2d613 --- /dev/null +++ b/spec/factories/result.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :result do + name { Faker::Name.unique.name } + my_module { create(:my_module) } + end +end diff --git a/spec/factories/result_asset.rb b/spec/factories/result_asset.rb new file mode 100644 index 000000000..52c76b54e --- /dev/null +++ b/spec/factories/result_asset.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :result_asset do + asset { create(:asset) } + result { create(:result) } + end +end diff --git a/spec/factories/result_table.rb b/spec/factories/result_table.rb new file mode 100644 index 000000000..47849dbe4 --- /dev/null +++ b/spec/factories/result_table.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :result_table do + table { create(:table) } + end +end diff --git a/spec/factories/result_text.rb b/spec/factories/result_text.rb new file mode 100644 index 000000000..18cad32d8 --- /dev/null +++ b/spec/factories/result_text.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :result_text do + text { Faker::Lorem.paragraph } + result { create(:result) } + end +end diff --git a/spec/factories/table.rb b/spec/factories/table.rb new file mode 100644 index 000000000..3abeacf1f --- /dev/null +++ b/spec/factories/table.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :table do + name { Faker::Name.unique.name } + contents { Faker::Lorem.characters } + end +end diff --git a/spec/requests/api/v1/experiments_controller_spec.rb b/spec/requests/api/v1/experiments_controller_spec.rb new file mode 100644 index 000000000..2ca62d3da --- /dev/null +++ b/spec/requests/api/v1/experiments_controller_spec.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe "Api::V1::ExperimentsController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + @valid_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + @unaccessible_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + create_list(:experiment, 3, created_by: @user, last_modified_by: @user, + project: @valid_project) + create_list(:experiment, 3, created_by: @user, last_modified_by: @user, + project: @unaccessible_project) + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET experiments, #index' do + it 'Response with correct experiments' do + hash_body = nil + get api_v1_team_project_experiments_path(team_id: @teams.first.id, + project_id: @valid_project), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_project.experiments, + each_serializer: Api::V1::ExperimentSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, project from another team' do + hash_body = nil + get api_v1_team_project_experiments_path(team_id: @teams.second.id, + project_id: @valid_project), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiments_path(team_id: @teams.second.id, + project_id: @unaccessible_project), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing project' do + hash_body = nil + get api_v1_team_project_experiments_path(team_id: @teams.first.id, + project_id: -1), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end + + describe 'GET experiment, #show' do + it 'When valid request, user can read experiment' do + hash_body = nil + get api_v1_team_project_experiment_path(team_id: @teams.first.id, + project_id: @valid_project, id: @valid_project.experiments.first.id), + headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_project.experiments.first, + serializer: Api::V1::ExperimentSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiment_path( + team_id: @teams.second.id, + project_id: @unaccessible_project, + id: @unaccessible_project.experiments.first.id + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing experiment' do + hash_body = nil + get api_v1_team_project_experiment_path(team_id: @teams.first.id, + project_id: @valid_project, id: -1), + headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, experiment from another project' do + hash_body = nil + get api_v1_team_project_experiment_path( + team_id: @teams.first.id, + project_id: @valid_project, + id: @unaccessible_project.experiments.first.id + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, experiment from unaccessible project' do + hash_body = nil + get api_v1_team_project_experiment_path( + team_id: @teams.first.id, + project_id: @unaccessible_project, + id: @unaccessible_project.experiments.first.id + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end diff --git a/spec/requests/api/v1/projects_controller_spec.rb b/spec/requests/api/v1/projects_controller_spec.rb new file mode 100644 index 000000000..34c3c556a --- /dev/null +++ b/spec/requests/api/v1/projects_controller_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe "Api::V1::ProjectsController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + # valid_projects + create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + # unaccessable_projects + create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET projects, #index' do + it 'Response with correct projects' do + hash_body = nil + get api_v1_team_projects_path(team_id: @teams.first.id), + headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@teams.first.projects, + each_serializer: Api::V1::ProjectSerializer) + .as_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: @teams.second.id), + headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing team' do + hash_body = nil + get api_v1_team_projects_path(team_id: -1), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end + + describe 'GET project, #show' do + it 'When valid request, user can read project' do + hash_body = nil + get api_v1_team_project_path(team_id: @teams.first.id, + id: @teams.first.projects.first.id), + headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@teams.first.projects.first, + serializer: Api::V1::ProjectSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_path(team_id: @teams.second.id, + id: @teams.second.projects.first.id), + headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing project' do + hash_body = nil + get api_v1_team_project_path(team_id: @teams.first.id, id: -1), + headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, project from another team' do + hash_body = nil + get api_v1_team_project_path(team_id: @teams.first.id, + id: @teams.second.projects.first.id), + headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end diff --git a/spec/requests/api/v1/results_controller_spec.rb b/spec/requests/api/v1/results_controller_spec.rb new file mode 100644 index 000000000..c176312c1 --- /dev/null +++ b/spec/requests/api/v1/results_controller_spec.rb @@ -0,0 +1,162 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe "Api::V1::ResultsController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + @valid_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + @unaccessible_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + @valid_experiment = create(:experiment, created_by: @user, + last_modified_by: @user, project: @valid_project) + @unaccessible_experiment = create(:experiment, created_by: @user, + last_modified_by: @user, project: @unaccessible_project) + + @valid_task = create(:my_module, created_by: @user, + last_modified_by: @user, experiment: @valid_experiment) + @unaccessible_task = create(:my_module, created_by: @user, + last_modified_by: @user, experiment: @unaccessible_experiment) + + create(:result_text, result: create( + :result, user: @user, last_modified_by: @user, my_module: @valid_task + )) + create(:result_table, result: create( + :result, user: @user, last_modified_by: @user, my_module: @valid_task + )) + create(:result_asset, result: create( + :result, user: @user, last_modified_by: @user, my_module: @valid_task + )) + + create(:result_text, result: + create(:result, user: @user, last_modified_by: @user, + my_module: @unaccessible_task)) + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET results, #index' do + it 'Response with correct results' do + hash_body = nil + get api_v1_team_project_experiment_task_results_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @valid_task + ), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_task.results, each_serializer: Api::V1::ResultSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, task from another experiment' do + hash_body = nil + get api_v1_team_project_experiment_task_results_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @unaccessible_task + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiment_task_results_path( + team_id: @teams.second.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @valid_task + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing task' do + hash_body = nil + get api_v1_team_project_experiment_task_results_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: -1 + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end + + describe 'GET result, #show' do + it 'When valid request, user can read result' do + hash_body = nil + get api_v1_team_project_experiment_task_result_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @valid_task, + id: @valid_task.results.first.id + ), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_task.results.first, serializer: Api::V1::ResultSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiment_task_result_path( + team_id: @teams.second.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @valid_task, + id: @valid_task.results.first.id + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing result' do + hash_body = nil + get api_v1_team_project_experiment_task_result_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @valid_task, + id: -1 + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, result from unaccessible task' do + hash_body = nil + get api_v1_team_project_experiment_task_result_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + task_id: @unaccessible_task, + id: @unaccessible_task.results.first.id + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end diff --git a/spec/requests/api/v1/tasks_controller_spec.rb b/spec/requests/api/v1/tasks_controller_spec.rb new file mode 100644 index 000000000..26ad2fdda --- /dev/null +++ b/spec/requests/api/v1/tasks_controller_spec.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe "Api::V1::TasksController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + @valid_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + @unaccessible_project = create(:project, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + @valid_experiment = create(:experiment, created_by: @user, + last_modified_by: @user, project: @valid_project) + @unaccessible_experiment = create(:experiment, created_by: @user, + last_modified_by: @user, project: @unaccessible_project) + + create_list(:my_module, 3, created_by: @user, + last_modified_by: @user, experiment: @valid_experiment) + create_list(:my_module, 3, created_by: @user, + last_modified_by: @user, experiment: @unaccessible_experiment) + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET tasks, #index' do + it 'Response with correct tasks' do + hash_body = nil + get api_v1_team_project_experiment_tasks_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment + ), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_experiment.my_modules, + each_serializer: Api::V1::TaskSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, experiment from another project' do + hash_body = nil + get api_v1_team_project_experiment_tasks_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @unaccessible_experiment + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiment_tasks_path( + team_id: @teams.second.id, + project_id: @unaccessible_project, + experiment_id: @unaccessible_experiment + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing experiment' do + hash_body = nil + get api_v1_team_project_experiment_tasks_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: -1 + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end + + describe 'GET task, #show' do + it 'When valid request, user can read task' do + hash_body = nil + get api_v1_team_project_experiment_task_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + id: @valid_experiment.my_modules.first.id + ), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_experiment.my_modules.first, + serializer: Api::V1::TaskSerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_project_experiment_task_path( + team_id: @teams.second.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + id: @valid_experiment.my_modules.first.id + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing task' do + hash_body = nil + get api_v1_team_project_experiment_task_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + id: -1 + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, task from unaccessible experiment' do + hash_body = nil + get api_v1_team_project_experiment_task_path( + team_id: @teams.first.id, + project_id: @valid_project, + experiment_id: @valid_experiment, + id: @unaccessible_experiment.my_modules.first.id + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end