From be8ed0984a8ff3d057dfc3155ae5a2953c9659eb Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Sun, 14 Oct 2012 16:00:49 +0400 Subject: [PATCH 1/7] #672: added #add_member, #remove_member, #update, #destroy actipns for Repository API --- app/controllers/api/v1/base_controller.rb | 29 +--- .../api/v1/platforms_controller.rb | 13 -- .../api/v1/repositories_controller.rb | 29 ++++ app/helpers/api/v1/base_helper.rb | 42 ++++++ config/routes.rb | 7 +- .../api/v1/platforms_controller_spec.rb | 2 +- .../api/v1/repositories_controller_spec.rb | 137 +++++++++++++++++- 7 files changed, 214 insertions(+), 45 deletions(-) create mode 100644 app/helpers/api/v1/base_helper.rb diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index 6b4baa981..cb2b8bcdc 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -1,5 +1,6 @@ # -*- encoding : utf-8 -*- class Api::V1::BaseController < ApplicationController + include Api::V1::BaseHelper #respond_to :json rescue_from CanCan::AccessDenied do |exception| @@ -8,32 +9,4 @@ class Api::V1::BaseController < ApplicationController end end - protected - - def paginate_params - per_page = params[:per_page].to_i - per_page = 20 if per_page < 1 - per_page = 100 if per_page >100 - {:page => params[:page], :per_page => per_page} - end - - def render_json_response(subject, message, status = 200) - id = status != 200 ? nil : subject.id - - render :json => { - subject.class.name.downcase.to_sym => { - :id => id, - :message => message - } - }.to_json, :status => status - end - - def render_validation_error(subject, message) - errors = subject.errors.full_messages.join('. ') - if errors.present? - message << '. ' << errors - end - render_json_response(subject, message, 422) - end - end diff --git a/app/controllers/api/v1/platforms_controller.rb b/app/controllers/api/v1/platforms_controller.rb index ff37d009a..19efa1611 100644 --- a/app/controllers/api/v1/platforms_controller.rb +++ b/app/controllers/api/v1/platforms_controller.rb @@ -81,17 +81,4 @@ class Api::V1::PlatformsController < Api::V1::BaseController render_json_response @platform, 'Platform has been destroyed successfully' end - private - - def member - return @member if @member - if params[:type] == 'User' - member = User - elsif params[:type] == 'Group' - member = Group - end - @member = member.where(:id => params[:member_id]).first if member - @member ||= '' - end - end diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 92546fe97..5b53ba3a4 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -7,7 +7,36 @@ class Api::V1::RepositoriesController < Api::V1::BaseController load_and_authorize_resource :repository, :through => :platform, :shallow => true def show + end + def update + rep_params = params[:repository] || {} + if @repository.update_attributes(rep_params) + render_json_response @repository, 'Repository has been updated successfully' + else + render_validation_error @repository, 'Repository has not been updated' + end + end + + def add_member + if member.present? && @repository.add_member(member) + render_json_response @repository, "#{member.class.to_s} '#{member.id}' has been added to repository successfully" + else + render_validation_error @repository, 'Member has not been added to repository' + end + end + + def remove_member + if member.present? && @repository.remove_member(member) + render_json_response @repository, "#{member.class.to_s} '#{member.id}' has been removed from repository successfully" + else + render_validation_error @repository, 'Member has not been removed from repository' + end + end + + def destroy + @repository.destroy # later with resque + render_json_response @repository, 'Repository has been destroyed successfully' end end diff --git a/app/helpers/api/v1/base_helper.rb b/app/helpers/api/v1/base_helper.rb new file mode 100644 index 000000000..969a3760c --- /dev/null +++ b/app/helpers/api/v1/base_helper.rb @@ -0,0 +1,42 @@ +module Api::V1::BaseHelper + + protected + + def paginate_params + per_page = params[:per_page].to_i + per_page = 20 if per_page < 1 + per_page = 100 if per_page >100 + {:page => params[:page], :per_page => per_page} + end + + def render_json_response(subject, message, status = 200) + id = status != 200 ? nil : subject.id + + render :json => { + subject.class.name.downcase.to_sym => { + :id => id, + :message => message + } + }.to_json, :status => status + end + + def render_validation_error(subject, message) + errors = subject.errors.full_messages.join('. ') + if errors.present? + message << '. ' << errors + end + render_json_response(subject, message, 422) + end + + def member + return @member if @member + if params[:type] == 'User' + member = User + elsif params[:type] == 'Group' + member = Group + end + @member = member.where(:id => params[:member_id]).first if member + @member ||= '' + end + +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 9e9038b08..63df9f4d0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,7 +32,12 @@ Rosa::Application.routes.draw do put :clear } end - resources :repositories, :only => [:show] + resources :repositories, :only => [:show, :update, :destroy] do + member { + put :add_member + delete :remove_member + } + end resources :projects, :only => [:show] do collection { get :get_id } member { diff --git a/spec/controllers/api/v1/platforms_controller_spec.rb b/spec/controllers/api/v1/platforms_controller_spec.rb index fc906dbae..682bce637 100644 --- a/spec/controllers/api/v1/platforms_controller_spec.rb +++ b/spec/controllers/api/v1/platforms_controller_spec.rb @@ -52,7 +52,7 @@ shared_examples_for 'api platform user with writer rights' do delete :remove_member, {:member_id => member.id, :type => 'User', :id => @platform.id}, :format => :json end - it 'should be able to perform update action' do + it 'should be able to perform remove_member action' do response.should be_success end it 'ensures that member has been removed from platform' do diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb index 7ca1dffc4..2ea7952a7 100644 --- a/spec/controllers/api/v1/repositories_controller_spec.rb +++ b/spec/controllers/api/v1/repositories_controller_spec.rb @@ -35,6 +35,133 @@ shared_examples_for "api repository user without show rights" do end end +shared_examples_for 'api repository user with writer rights' do + + context 'api repository user with update rights' do + before do + put :update, {:repository => {:description => 'new description'}, :id => @repository.id}, :format => :json + end + + it 'should be able to perform update action' do + response.should be_success + end + it 'ensures that repository has been updated' do + @repository.reload + @repository.description.should == 'new description' + end + end + + context 'api repository user with add_member rights' do + let(:member) { FactoryGirl.create(:user) } + before do + put :add_member, {:member_id => member.id, :type => 'User', :id => @repository.id}, :format => :json + end + + it 'should be able to perform add_member action' do + response.should be_success + end + it 'ensures that new member has been added to repository' do + @repository.members.should include(member) + end + end + + context 'api repository user with remove_member rights' do + let(:member) { FactoryGirl.create(:user) } + before do + @repository.add_member(member) + delete :remove_member, {:member_id => member.id, :type => 'User', :id => @repository.id}, :format => :json + end + + it 'should be able to perform remove_member action' do + response.should be_success + end + it 'ensures that member has been removed from repository' do + @repository.members.should_not include(member) + end + end + + context 'api repository user with destroy rights' do + it 'should be able to perform destroy action for main platform' do + delete :destroy, :id => @repository.id, :format => :json + response.should be_success + end + it 'ensures that repository of main platform has been destroyed' do + lambda { delete :destroy, :id => @repository.id, :format => :json }.should change{ Repository.count }.by(-1) + end + it 'should not be able to perform destroy action for repository of personal platform' do + delete :destroy, :id => @personal_repository.id, :format => :json + response.should_not be_success + end + it 'ensures that repository of personal platform has not been destroyed' do + lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count } + end + end +end + +shared_examples_for 'api repository user without writer rights' do + + context 'api repository user without update rights' do + before do + put :update, {:repository => {:description => 'new description'}, :id => @repository.id}, :format => :json + end + + it 'should not be able to perform update action' do + response.should_not be_success + end + it 'ensures that repository has not been updated' do + @repository.reload + @repository.description.should_not == 'new description' + end + end + + context 'api repository user without add_member rights' do + let(:member) { FactoryGirl.create(:user) } + before do + put :add_member, {:member_id => member.id, :type => 'User', :id => @repository.id}, :format => :json + end + + it 'should not be able to perform add_member action' do + response.should_not be_success + end + it 'ensures that new member has not been added to repository' do + @repository.members.should_not include(member) + end + end + + context 'api repository user without remove_member rights' do + let(:member) { FactoryGirl.create(:user) } + before do + @repository.add_member(member) + delete :remove_member, {:member_id => member.id, :type => 'User', :id => @repository.id}, :format => :json + end + + it 'should be able to perform update action' do + response.should_not be_success + end + it 'ensures that member has not been removed from repository' do + @repository.members.should include(member) + end + end + + context 'api repository user without destroy rights' do + it 'should not be able to perform destroy action for repository of main platform' do + delete :destroy, :id => @repository.id, :format => :json + response.should_not be_success + end + it 'ensures that repository of main platform has not been destroyed' do + lambda { delete :destroy, :id => @repository.id, :format => :json }.should_not change{ Repository.count } + end + it 'should not be able to perform destroy action for repository of personal platform' do + delete :destroy, :id => @personal_repository.id, :format => :json + response.should_not be_success + end + it 'ensures that repository of personal platform has not been destroyed' do + lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count } + end + end +end + + describe Api::V1::RepositoriesController do before(:each) do stub_symlink_methods @@ -52,8 +179,11 @@ describe Api::V1::RepositoriesController do response.status.should == 401 end - it_should_behave_like 'api repository user without reader rights for hidden platform' if APP_CONFIG['anonymous_access'] - it_should_behave_like 'api repository user with show rights' if APP_CONFIG['anonymous_access'] + if APP_CONFIG['anonymous_access'] + it_should_behave_like 'api repository user without reader rights for hidden platform' + it_should_behave_like 'api repository user with show rights' + end + it_should_behave_like 'api repository user without writer rights' end context 'for admin' do @@ -64,6 +194,7 @@ describe Api::V1::RepositoriesController do it_should_behave_like 'api repository user with reader rights' it_should_behave_like 'api repository user with reader rights for hidden platform' + it_should_behave_like 'api repository user with writer rights' end context 'for platform owner user' do @@ -77,6 +208,7 @@ describe Api::V1::RepositoriesController do it_should_behave_like 'api repository user with reader rights' it_should_behave_like 'api repository user with reader rights for hidden platform' + it_should_behave_like 'api repository user with writer rights' end context 'for user' do @@ -88,5 +220,6 @@ describe Api::V1::RepositoriesController do it_should_behave_like 'api repository user with reader rights' it_should_behave_like 'api repository user without reader rights for hidden platform' it_should_behave_like 'api repository user with show rights' + it_should_behave_like 'api repository user without writer rights' end end From 146f72c06202d4f24691a6866f029b0e8db1c85d Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Sun, 14 Oct 2012 16:39:58 +0400 Subject: [PATCH 2/7] #672: small refactoring --- .../api/v1/platforms_controller.rb | 21 +++--------- .../api/v1/repositories_controller.rb | 22 +++--------- app/helpers/api/v1/base_helper.rb | 34 +++++++++++++++++++ 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/app/controllers/api/v1/platforms_controller.rb b/app/controllers/api/v1/platforms_controller.rb index 19efa1611..007237092 100644 --- a/app/controllers/api/v1/platforms_controller.rb +++ b/app/controllers/api/v1/platforms_controller.rb @@ -33,11 +33,7 @@ class Api::V1::PlatformsController < Api::V1::BaseController platform_params = params[:platform] || {} owner = User.where(:id => platform_params[:owner_id]).first platform_params[:owner] = owner if owner - if @platform.update_attributes(platform_params) - render_json_response @platform, 'Platform has been updated successfully' - else - render_validation_error @platform, 'Platform has not been updated' - end + update_subject @platform end def members @@ -45,19 +41,11 @@ class Api::V1::PlatformsController < Api::V1::BaseController end def add_member - if member.present? && @platform.add_member(member) - render_json_response @platform, "#{member.class.to_s} '#{member.id}' has been added to platform successfully" - else - render_validation_error @platform, 'Member has not been added to platform' - end + add_member_to_subject @platform end def remove_member - if member.present? && @platform.remove_member(member) - render_json_response @platform, "#{member.class.to_s} '#{member.id}' has been removed from platform successfully" - else - render_validation_error @platform, 'Member has not been removed from platform' - end + remove_member_from_subject @platform end def clone @@ -77,8 +65,7 @@ class Api::V1::PlatformsController < Api::V1::BaseController end def destroy - @platform.destroy # later with resque - render_json_response @platform, 'Platform has been destroyed successfully' + destroy_subject @platform end end diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 5b53ba3a4..fa9fa6046 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -10,33 +10,19 @@ class Api::V1::RepositoriesController < Api::V1::BaseController end def update - rep_params = params[:repository] || {} - if @repository.update_attributes(rep_params) - render_json_response @repository, 'Repository has been updated successfully' - else - render_validation_error @repository, 'Repository has not been updated' - end + update_subject @repository end def add_member - if member.present? && @repository.add_member(member) - render_json_response @repository, "#{member.class.to_s} '#{member.id}' has been added to repository successfully" - else - render_validation_error @repository, 'Member has not been added to repository' - end + add_member_to_subject @repository end def remove_member - if member.present? && @repository.remove_member(member) - render_json_response @repository, "#{member.class.to_s} '#{member.id}' has been removed from repository successfully" - else - render_validation_error @repository, 'Member has not been removed from repository' - end + remove_member_from_subject @repository end def destroy - @repository.destroy # later with resque - render_json_response @repository, 'Repository has been destroyed successfully' + destroy_subject @repository end end diff --git a/app/helpers/api/v1/base_helper.rb b/app/helpers/api/v1/base_helper.rb index 969a3760c..0599169b8 100644 --- a/app/helpers/api/v1/base_helper.rb +++ b/app/helpers/api/v1/base_helper.rb @@ -2,6 +2,38 @@ module Api::V1::BaseHelper protected + def add_member_to_subject(subject) + class_name = subject.class.name.downcase + if member.present? && subject.add_member(member) + render_json_response subject, "#{member.class.to_s} '#{member.id}' has been added to #{class_name} successfully" + else + render_validation_error subject, "Member has not been added to #{class_name}" + end + end + + def remove_member_from_subject(subject) + class_name = subject.class.name.downcase + if member.present? && subject.remove_member(member) + render_json_response subject, "#{member.class.to_s} '#{member.id}' has been removed from #{class_name} successfully" + else + render_validation_error subject, "Member has not been removed from #{class_name}" + end + end + + def destroy_subject(subject) + subject.destroy # later with resque + render_json_response subject, "#{subject.class.name} has been destroyed successfully" + end + + def update_subject(subject) + class_name = subject.class.name + if subject.update_attributes(params[class_name.downcase.to_sym] || {}) + render_json_response subject, "#{class_name} has been updated successfully" + else + render_validation_error subject, "#{class_name} has not been updated" + end + end + def paginate_params per_page = params[:per_page].to_i per_page = 20 if per_page < 1 @@ -28,6 +60,8 @@ module Api::V1::BaseHelper render_json_response(subject, message, 422) end + private + def member return @member if @member if params[:type] == 'User' From 00f5d0ce6242f3918ad09a87b6f22d09bacb17b3 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Sun, 14 Oct 2012 17:38:06 +0400 Subject: [PATCH 3/7] #672: updated Repositories API --- .../api/v1/repositories_controller.rb | 34 ++++++++++++- .../platforms/repositories_controller.rb | 3 +- app/models/ability.rb | 2 +- config/routes.rb | 3 ++ .../api/v1/repositories_controller_spec.rb | 49 +++++++++++++++++++ 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index fa9fa6046..474b0b648 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -25,4 +25,36 @@ class Api::V1::RepositoriesController < Api::V1::BaseController destroy_subject @repository end -end + def add_project + project = Project.where(:id => params[:project_id]).first + if project + begin + @repository.projects << project + render_json_response @repository, "Project '#{project.id}' has been added to repository successfully" + rescue ActiveRecord::RecordInvalid + render_validation_error @repository, t('flash.repository.project_not_added') + end + else + render_validation_error @repository, "Project has not been added to repository" + end + end + + def remove_project + project_id = params[:project_id] + ProjectToRepository.where(:project_id => project_id, :repository_id => @repository.id).destroy_all + render_json_response @repository, "Project '#{project_id}' has been removed from repository successfully" + end + + def signatures + key_pair = @repository.key_pair + key_pair.destroy if key_pair + key_pair = @repository.key_pair.build(params[:repository]) + key_pair.user_id = current_user.id + if key_pair.save + render_json_response @repository, 'Signatures have been updated for repository successfully' + else + render_validation_error @repository, 'Signatures have not been updated for repository' + end + end + +end \ No newline at end of file diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index 7afc34a21..8767fbb94 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -131,8 +131,7 @@ class Platforms::RepositoriesController < Platforms::BaseController end def remove_project - @project = Project.find(params[:project_id]) - ProjectToRepository.where(:project_id => @project.id, :repository_id => @repository.id).destroy_all + ProjectToRepository.where(:project_id => params[:project_id], :repository_id => @repository.id).destroy_all redirect_to platform_repository_path(@platform, @repository), :notice => t('flash.repository.project_removed') end diff --git a/app/models/ability.rb b/app/models/ability.rb index 24c4a7a6a..382673bc5 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -100,7 +100,7 @@ class Ability can [:read, :projects_list], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can([:read, :projects_list], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} can([:create, :edit, :update, :destroy, :projects_list, :add_project, :remove_project], Repository) {|repository| local_admin? repository.platform} - can([:remove_members, :remove_member, :add_member], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} + can([:remove_members, :remove_member, :add_member, :signatures], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)} can(:clear, Platform) {|platform| local_admin?(platform) && platform.personal?} can([:change_visibility, :settings, :destroy, :edit, :update], Repository) {|repository| owner? repository.platform} diff --git a/config/routes.rb b/config/routes.rb index 63df9f4d0..6f8bd4009 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -36,6 +36,9 @@ Rosa::Application.routes.draw do member { put :add_member delete :remove_member + put :add_project + delete :remove_project + put :signatures } end resources :projects, :only => [:show] do diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb index 2ea7952a7..fcff0d10b 100644 --- a/spec/controllers/api/v1/repositories_controller_spec.rb +++ b/spec/controllers/api/v1/repositories_controller_spec.rb @@ -96,6 +96,30 @@ shared_examples_for 'api repository user with writer rights' do lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count } end end + + context 'api repository user with add_project rights' do + before { put :add_project, :id => @repository.id, :project_id => @project.id, :format => :json } + it 'should be able to perform add_project action' do + response.should be_success + end + it 'ensures that project has been added to repository' do + @repository.projects.should include(@project) + end + end + + context 'api repository user with remove_project rights' do + before do + @repository.projects << @project + delete :remove_project, :id => @repository.id, :project_id => @project.id, :format => :json + end + it 'should be able to perform remove_project action' do + response.should be_success + end + it 'ensures that project has been removed from repository' do + @repository.reload + @repository.projects.should_not include(@project) + end + end end shared_examples_for 'api repository user without writer rights' do @@ -159,6 +183,31 @@ shared_examples_for 'api repository user without writer rights' do lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count } end end + + context 'api repository user without add_project rights' do + before { put :add_project, :id => @repository.id, :project_id => @project.id, :format => :json } + it 'should not be able to perform add_project action' do + response.should_not be_success + end + it 'ensures that project has not been added to repository' do + @repository.projects.should_not include(@project) + end + end + + context 'api repository user without remove_project rights' do + before do + @repository.projects << @project + delete :remove_project, :id => @repository.id, :project_id => @project.id, :format => :json + end + it 'should not be able to perform remove_project action' do + response.should_not be_success + end + it 'ensures that project has not been removed from repository' do + @repository.reload + @repository.projects.should include(@project) + end + end + end From 5c88ac6f3e9d5c2966f0f3cbe50bca4b26aaa48f Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Sun, 14 Oct 2012 18:44:10 +0400 Subject: [PATCH 4/7] #672: updated Repositories#signatures API action, added specs --- .../api/v1/repositories_controller.rb | 7 +++-- .../api/v1/repositories_controller_spec.rb | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 474b0b648..c438478d7 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -48,12 +48,15 @@ class Api::V1::RepositoriesController < Api::V1::BaseController def signatures key_pair = @repository.key_pair key_pair.destroy if key_pair - key_pair = @repository.key_pair.build(params[:repository]) + key_pair = @repository.build_key_pair(params[:repository]) key_pair.user_id = current_user.id if key_pair.save render_json_response @repository, 'Signatures have been updated for repository successfully' else - render_validation_error @repository, 'Signatures have not been updated for repository' + message = 'Signatures have not been updated for repository' + errors = key_pair.errors.full_messages.join('. ') + (message << '. ' << errors) if errors.present? + render_json_response @repository, message, 422 end end diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb index fcff0d10b..1aa7b8ffb 100644 --- a/spec/controllers/api/v1/repositories_controller_spec.rb +++ b/spec/controllers/api/v1/repositories_controller_spec.rb @@ -120,6 +120,20 @@ shared_examples_for 'api repository user with writer rights' do @repository.projects.should_not include(@project) end end + + context 'api repository user with update signatures rights' do + before do + stub_key_pairs_calls + put :signatures, :id => @repository.id, :repository => {:public => 'iampublic', :secret => 'iamsecret'}, :format => :json + end + it 'should be able to perform signatures action' do + response.should be_success + end + it 'ensures that signatures has been updated' do + @repository.key_pair.should_not be_nil + end + end + end shared_examples_for 'api repository user without writer rights' do @@ -208,6 +222,19 @@ shared_examples_for 'api repository user without writer rights' do end end + context 'api repository user without update signatures rights' do + before do + stub_key_pairs_calls + put :signatures, :id => @repository.id, :repository => {:public => 'iampublic', :secret => 'iamsecret'}, :format => :json + end + it 'should not be able to perform signatures action' do + response.should_not be_success + end + it 'ensures that signatures has not been updated' do + @repository.key_pair.should be_nil + end + end + end From fae5d3ff2ba3b41af04712b3cd7f06eda4e99883 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 15 Oct 2012 12:28:18 +0400 Subject: [PATCH 5/7] #690: truncate project name before validation --- app/models/project.rb | 6 +++- spec/models/project_spec.rb | 58 +++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 1c8bc74a9..43baaa007 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -54,7 +54,7 @@ class Project < ActiveRecord::Base where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR (projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids) } - + before_validation :truncate_name, :on => :create before_create :set_maintainer after_save :attach_to_personal_repository @@ -177,6 +177,10 @@ class Project < ActiveRecord::Base protected + def truncate_name + self.name = name.strip if name + end + def attach_to_personal_repository owner_rep = self.owner.personal_repository if is_package diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index ab13f6ae3..c2892dec4 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -9,17 +9,35 @@ describe Project do @child_child_project = @child_project.fork(FactoryGirl.create(:user)) end - context 'for destroy root' do - before do - @root_project.destroy + context 'for destroy' do + let!(:root_project) { FactoryGirl.create(:project) } + let!(:child_project) { root_project.fork(FactoryGirl.create(:user)) } + let!(:child_child_project) { child_project.fork(FactoryGirl.create(:user)) } + + context 'root project' do + before { root_project.destroy } + + it "should not be delete child" do + Project.where(:id => child_project).count.should == 1 + end + + it "should not be delete child of the child" do + Project.where(:id => child_child_project).count.should == 1 + end end - it "should not be delete child" do - Project.where(:id => @child_project).count.should == 1 - end + pending 'when will be available :orphan_strategy => :adopt' do + context 'middle node' do + before{ child_project.destroy } - it "should not be delete child of the child" do - Project.where(:id => @child_child_project).count.should == 1 + it "should set root project as a parent for orphan child" do + Project.find(child_child_project).ancestry == root_project + end + + it "should not be delete child of the child" do + Project.where(:id => child_child_project).count.should == 1 + end + end end end @@ -48,19 +66,17 @@ describe Project do end end - # uncommit when will be available :orphan_strategy => :adopt + context 'truncates project name before validation' do + let!(:project) { FactoryGirl.build(:project, :name => ' test_name ') } - #context 'for destroy middle node' do - # before(:each) do - # @child_project.destroy - # end + it 'ensures that validation passed' do + project.valid?.should be_true + end + + it 'ensures that name has been truncated' do + project.valid? + project.name.should == 'test_name' + end + end - # it "should set root project as a parent for orphan child" do - # Project.find(@child_child_project).ancestry == @root_project - # end - - # it "should not be delete child of the child" do - # Project.where(:id => @child_child_project).count.should == 1 - # end - #end end From 5d9a1e2586d1dcde6faabe063d534f6004d967b4 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 15 Oct 2012 13:48:25 +0400 Subject: [PATCH 6/7] #672: removed API helper --- app/controllers/api/v1/base_controller.rb | 74 +++++++++++++++++++++- app/helpers/api/v1/base_helper.rb | 76 ----------------------- 2 files changed, 73 insertions(+), 77 deletions(-) delete mode 100644 app/helpers/api/v1/base_helper.rb diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index cb2b8bcdc..b7fea5dd0 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -1,6 +1,5 @@ # -*- encoding : utf-8 -*- class Api::V1::BaseController < ApplicationController - include Api::V1::BaseHelper #respond_to :json rescue_from CanCan::AccessDenied do |exception| @@ -9,4 +8,77 @@ class Api::V1::BaseController < ApplicationController end end + protected + + def add_member_to_subject(subject) + class_name = subject.class.name.downcase + if member.present? && subject.add_member(member) + render_json_response subject, "#{member.class.to_s} '#{member.id}' has been added to #{class_name} successfully" + else + render_validation_error subject, "Member has not been added to #{class_name}" + end + end + + def remove_member_from_subject(subject) + class_name = subject.class.name.downcase + if member.present? && subject.remove_member(member) + render_json_response subject, "#{member.class.to_s} '#{member.id}' has been removed from #{class_name} successfully" + else + render_validation_error subject, "Member has not been removed from #{class_name}" + end + end + + def destroy_subject(subject) + subject.destroy # later with resque + render_json_response subject, "#{subject.class.name} has been destroyed successfully" + end + + def update_subject(subject) + class_name = subject.class.name + if subject.update_attributes(params[class_name.downcase.to_sym] || {}) + render_json_response subject, "#{class_name} has been updated successfully" + else + render_validation_error subject, "#{class_name} has not been updated" + end + end + + def paginate_params + per_page = params[:per_page].to_i + per_page = 20 if per_page < 1 + per_page = 100 if per_page >100 + {:page => params[:page], :per_page => per_page} + end + + def render_json_response(subject, message, status = 200) + id = status != 200 ? nil : subject.id + + render :json => { + subject.class.name.downcase.to_sym => { + :id => id, + :message => message + } + }.to_json, :status => status + end + + def render_validation_error(subject, message) + errors = subject.errors.full_messages.join('. ') + if errors.present? + message << '. ' << errors + end + render_json_response(subject, message, 422) + end + + private + + def member + return @member if @member + if params[:type] == 'User' + member = User + elsif params[:type] == 'Group' + member = Group + end + @member = member.where(:id => params[:member_id]).first if member + @member ||= '' + end + end diff --git a/app/helpers/api/v1/base_helper.rb b/app/helpers/api/v1/base_helper.rb deleted file mode 100644 index 0599169b8..000000000 --- a/app/helpers/api/v1/base_helper.rb +++ /dev/null @@ -1,76 +0,0 @@ -module Api::V1::BaseHelper - - protected - - def add_member_to_subject(subject) - class_name = subject.class.name.downcase - if member.present? && subject.add_member(member) - render_json_response subject, "#{member.class.to_s} '#{member.id}' has been added to #{class_name} successfully" - else - render_validation_error subject, "Member has not been added to #{class_name}" - end - end - - def remove_member_from_subject(subject) - class_name = subject.class.name.downcase - if member.present? && subject.remove_member(member) - render_json_response subject, "#{member.class.to_s} '#{member.id}' has been removed from #{class_name} successfully" - else - render_validation_error subject, "Member has not been removed from #{class_name}" - end - end - - def destroy_subject(subject) - subject.destroy # later with resque - render_json_response subject, "#{subject.class.name} has been destroyed successfully" - end - - def update_subject(subject) - class_name = subject.class.name - if subject.update_attributes(params[class_name.downcase.to_sym] || {}) - render_json_response subject, "#{class_name} has been updated successfully" - else - render_validation_error subject, "#{class_name} has not been updated" - end - end - - def paginate_params - per_page = params[:per_page].to_i - per_page = 20 if per_page < 1 - per_page = 100 if per_page >100 - {:page => params[:page], :per_page => per_page} - end - - def render_json_response(subject, message, status = 200) - id = status != 200 ? nil : subject.id - - render :json => { - subject.class.name.downcase.to_sym => { - :id => id, - :message => message - } - }.to_json, :status => status - end - - def render_validation_error(subject, message) - errors = subject.errors.full_messages.join('. ') - if errors.present? - message << '. ' << errors - end - render_json_response(subject, message, 422) - end - - private - - def member - return @member if @member - if params[:type] == 'User' - member = User - elsif params[:type] == 'Group' - member = Group - end - @member = member.where(:id => params[:member_id]).first if member - @member ||= '' - end - -end \ No newline at end of file From 9087a15627e071373b372e04b6910c0fe72f8904 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 15 Oct 2012 14:07:10 +0400 Subject: [PATCH 7/7] #672: small refactoring Api::V1::BaseController#member method --- app/controllers/api/v1/base_controller.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index b7fea5dd0..207b4ca8d 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -71,14 +71,10 @@ class Api::V1::BaseController < ApplicationController private def member - return @member if @member - if params[:type] == 'User' - member = User - elsif params[:type] == 'Group' - member = Group + if @member.blank? && %w(User Group).include?(params[:type]) + @member = params[:type].constantize.where(:id => params[:member_id]).first end - @member = member.where(:id => params[:member_id]).first if member - @member ||= '' - end + @member + end end