From 8668a7d156fe14603d7a8570a7dedc8c982e60e0 Mon Sep 17 00:00:00 2001 From: Finn Woelm Date: Tue, 12 Feb 2019 17:00:06 +0800 Subject: [PATCH] ProjectsController: Permit only premium user to create private project Only premium users can create private projects. After creation, project privacy cannot be changed. This should be addresses. See: [#320](https://github.com/OpenlyOne/openly/issues/320) --- app/controllers/projects_controller.rb | 26 +++++++++++--- spec/controllers/projects_controller_spec.rb | 36 ++++++++++++++++++-- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 2b73145b..7aaf89e1 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -6,14 +6,15 @@ class ProjectsController < ApplicationController before_action :authenticate_account!, except: :show before_action :build_project, only: %i[new create] + before_action :assign_create_params_to_project, only: %i[create] before_action :set_project, only: %i[show edit update destroy] - before_action :authorize_action, only: %i[edit update destroy] + before_action :authorize_action, only: %i[create edit update destroy] before_action :authorize_project_access, only: :show def new; end def create - if @project.update(project_params) + if @project.save redirect_with_success_to( new_profile_project_setup_path(@project.owner, @project) ) @@ -62,13 +63,22 @@ def destroy private rescue_from CanCan::AccessDenied do |exception| - can_can_access_denied(exception) + case action_name.to_sym + when :create + raise StandardError, 'Unauthorized to create private project' + else + can_can_access_denied(exception) + end end def authorize_action authorize! params[:action].to_sym, @project end + def assign_create_params_to_project + @project.assign_attributes(project_create_params) + end + def build_project @project = current_user.projects.build end @@ -81,8 +91,16 @@ def profile_slug params[:slug] end + def project_create_params + params + .require(:project) + .permit(:title, :slug, :tag_list, :description, :is_public) + end + def project_params - params.require(:project).permit(:title, :slug, :tag_list, :description) + params + .require(:project) + .permit(:title, :slug, :tag_list, :description) end def project_overview_path diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 9ef1d7b5..a3c8b4e2 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -30,11 +30,12 @@ end describe 'POST #create' do - let(:params) { { project: { title: 'title' } } } + let(:params) { { project: { title: 'title', is_public: true } } } let(:run_request) { post :create, params: params } + let(:account) { create(:account) } before do allow_any_instance_of(Project).to receive(:setup_archive) - sign_in create(:account) + sign_in account end it_should_behave_like 'an authenticated action' @@ -48,6 +49,17 @@ expect_any_instance_of(Project).to receive(:save) run_request end + + context 'when account is free' do + let(:account) { create(:account, :free) } + + it 'cannot create private project' do + Project.delete_all + params[:project][:is_public] = false + expect { run_request }.to raise_error(StandardError) + expect(Project).to be_none + end + end end describe 'GET #show' do @@ -147,6 +159,26 @@ expect_any_instance_of(Project).to receive(:update) run_request end + + context 'when trying to make public project private' do + let!(:project) { create :project, :public, :skip_archive_setup } + let(:add_params) { { project: { is_public: false } } } + + it 'does not make project private' do + expect { run_request } + .not_to(change { project.reload.public? }.from(true)) + end + end + + context 'when trying to make private project public' do + let!(:project) { create :project, :private, :skip_archive_setup } + let(:add_params) { { project: { is_public: true } } } + + it 'does not make project public' do + expect { run_request } + .not_to(change { project.reload.private? }.from(true)) + end + end end describe 'DELETE #destroy' do