# Copyright (c) 2015 Perforce Software, Inc. All rights reserved. if ENV['ENABLE_GIT_FUSION'] == 'true' require 'rspec' require 'helix_web_services_client' require 'tempfile' require_relative './test_config' RSpec.describe 'HelixWebServicesClient git-fusion repositories' do it 'should not fail when listing repositories' do client_as_jdoe do |client| client.list_repos end end it 'should not submit a config for a mis-configured repo' do client_as_jdoe do |client| config = { ' description' => 'Bad description' } error_message = /JSON configuration is not valid/ expect { client.submit_config('testing_repo_name', config) }.to raise_error(Errors::BadRequest, error_message) end end it 'should not submit a config for a a different repo' do client_as_jdoe do |client| config = { ' description' => 'Bad description', 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo/...', 'client_path' => '...', }, 'prep' => { 'depot_path' => '//depot/testing_repo/...', 'client_path' => '...', } } } error_message = /configuration does not point to the chosen repository/ expect { client.submit_config('testing_repo_name', config) }.to raise_error(Errors::BadRequest, error_message) end end it 'should not submit an incomplete config' do client_as_jdoe do |client| config = { ' description' => 'Description', 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo_name/...', }, } } error_message = /JSON configuration is not valid/ expect { client.submit_config('testing_repo_name', config) }.to raise_error(Errors::BadRequest, error_message) end end it 'should submit a config for an uninitialized repo' do client_as_jdoe do |client| config = { 'description' => 'Testing repo description', 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo_name/...', 'client_path' => '...', } } } client.submit_config('testing_repo_name', config) expect(client.list_repos).to include({'id' => 'testing_repo_name', 'name' => 'testing_repo_name'}) end end it 'should submit a config for an uninitialized repo with special characters' do client_as_jdoe do |client| config = { 'description' => 'Another repo description', 'branches' => { 'master' => { 'depot_path' => '//depot/testing/reponame/...', 'client_path' => '...', } } } repo_name = 'testing/reponame' client.submit_config(repo_name, config) id = GitFusionStrings.encode(repo_name) expect(client.list_repos).to include({'id' => id, 'name' => repo_name}) end end it 'should return 404 when fetching by invalid repo_name' do client_as_jdoe do |client| expect { client.repo('invalid_repo_name') }.to raise_error(Errors::ResourceNotFound) end end it 'should return config when fetching by valid repo_name' do client_as_jdoe do |client| valid_repo_config = client.repo('testing_repo_name') expect(valid_repo_config).not_to be_empty expect(valid_repo_config['description']).to eq('Testing repo description') end end it 'should replace a config for an already initialized repo' do client_as_jdoe do |client| config = { 'description' => 'Testing repo new description update', 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo_name/...', 'client_path' => '...', } } } client.submit_config('testing_repo_name', config) expect(client.repo('testing_repo_name')['description']).to include('Testing repo new description update') end end it 'should replace a config for an already initialized repo with special characters' do client_as_jdoe do |client| repo_name = 'testing/reponame' old_config = client.repo(repo_name) config = { 'description' => 'Testing repo new description second update', 'branches' => { 'master' => { 'depot_path' => '//depot/testing/reponame/...', 'client_path' => '...', 'read-only' => 'Yes' } } } client.submit_config(repo_name, config) new_config = client.repo(repo_name) expect(new_config).not_to eq(old_config) end end it 'should not replace config for a valid repo with invalid values' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') config = { 'description' => 'Testing repo new description second update', 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo_name/...', 'read-only' => 'Yes' } } } error_message = /JSON configuration is not valid/ expect { client.submit_config('testing_repo_name', config) }.to raise_error(Errors::BadRequest, error_message) expect(client.repo('testing_repo_name')).to eq(old_config) end end it 'should not replace part of configuration with additional parameters' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') new_config = { 'description' => 'Description update', 'branches' => { 'prep' => { 'depot_path' => '//depot/test/...', 'client_path' => '...' } } } error_message = /does not have all of the specified parameters/ expect { client.update_config('testing_repo_name', new_config) }.to raise_error(Errors::BadRequest, error_message) expect(client.repo('testing_repo_name')).to eq(old_config) end end it 'should not replace part of configuration with bad data' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') config = { 'description' => 'Bad data patch update', 'branches' => { 'master' => { 'depot_path' => '...', } } } error_message = /invalid configuration file/ expect { client.update_config('testing_repo_name', config) }.to raise_error(Errors::BadRequest, error_message) expect(client.repo('testing_repo_name')).to eq(old_config) end end it 'should replace part of configuration for a valid repo' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') new_config = { 'description' => 'Description updated', } client.update_config('testing_repo_name', new_config) expect(client.repo('testing_repo_name')).not_to eq(old_config) expect(client.repo('testing_repo_name')['description']).to eq('Description updated') expect(client.repo('testing_repo_name')['description']).not_to include('Testing repo new description update') end end it 'should replace part of branch configuration for a valid repo' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') new_config = { 'branches' => { 'master' => { 'depot_path' => '//depot/testing_repo_name/subdir/...', 'client_path' => '...', } } } client.update_config('testing_repo_name', new_config) expect(client.repo('testing_repo_name')).not_to eq(old_config) expect(client.repo('testing_repo_name')['branches']['master']['depot_path']).to eq('//depot/testing_repo_name/subdir/...') end end it 'should replace branch name for a valid repo' do client_as_jdoe do |client| old_config = client.repo('testing_repo_name') config = { 'description' => 'Description updated', 'branches' => { 'master' => {'git-branch-name' => 'prep'} } } client.update_config('testing_repo_name', config) new_config = client.repo('testing_repo_name') expect(new_config).not_to eq(old_config) expect(new_config['description']).to eq('Description updated') expect(new_config['branches'].keys).to include('prep') expect(new_config['branches'].keys).not_to include('master') end end it 'should delete a repository configuration' do client_as_jdoe do |client| client.delete_repo('testing_repo_name') new_repo_list = client.list_repos expect(new_repo_list).not_to include({'id' => 'testing_repo_name', 'name' => 'testing_repo_name'}) end end it 'should delete non existent repository' do client_as_jdoe do |client| client.delete_repo('testing_repo_name2') new_repo_list = client.list_repos expect(new_repo_list).not_to include({'id' => 'testing_repo_name2', 'name' => 'testing_repo_name2'}) end end it 'should delete a repository configuration with special characters' do client_as_jdoe do |client| repo_name = 'testing/reponame' repo_id = GitFusionStrings.encode(repo_name) client.delete_repo(repo_name) new_repo_list = client.list_repos expect(new_repo_list).not_to include({'id' => repo_id, 'name' => repo_name}) end end end RSpec.describe 'HelixWebServicesClient git-fusion SSH keys' do it 'should not fail when listing keys for a user' do client_as_jdoe do |client| username = client.encode_component('jdoe') client.keys(username) end end it 'should fail when listing keys for a different user' do client_as_jdoe do |client| username = client.encode_component('test_user') error_message = /not authorised to view the requested data/ expect { client.keys(username) }.to raise_error(Errors::BadRequest, error_message) end end it 'should fail when listing keys for a different user with special characters' do client_as_jdoe do |client| username = client.encode_component('test/user') error_message = /not authorised to view the requested data/ expect { client.keys(username) }.to raise_error(Errors::BadRequest, error_message) end end it 'should add a key for a user' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test_key') client.add_key(username, key_name, key) expect(client.keys(username)).to include({'key' => key, 'key_name' => key_name, 'user' => username}) end end it 'should add a key with special characters for a user' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- UDJfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test?key.pub') client.add_key(username, key_name, key) expect(client.keys(username)).to include({'key' => key, 'key_name' => 'test?key.pub', 'user' => username}) end end it 'should add a key with other special characters for a user' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- UAJfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test/key.pub') client.add_key(username, key_name, key) expect(client.keys(username)).to include({'key' => key, 'key_name' => 'test/key.pub', 'user' => username}) end end it 'should fail while adding a key for a different user ' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- WIEHFOIW3242943U39G394G344GHEHOOWRHGG9034U9GU39GU9WJGJWGJ934U9U349GU94GJHG349 -----END PUBLIC KEY-----" EOK username = client.encode_component('test/user2') key_name = client.encode_component('test_key') error_message = /not authorised to view the requested data/ expect { client.add_key(username, key_name, key) }.to raise_error(Errors::BadRequest, error_message) end end it 'should exit with success if the same key is under the same name' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK key_name = client.encode_component('test_key') username = client.encode_component('jdoe') client.add_key(username, key_name, key) expect(client.keys(username)).to include({'key' => key, 'key_name' => key_name, 'user' => 'jdoe'}) end end it 'should not re-add the same key for the same user under a different name' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK key_name = client.encode_component('test_key2') username = client.encode_component('jdoe') error_message = "Key already assigned to user #{username} under name test_key" expect { client.add_key(username, key_name, key) }.to raise_error(Errors::BadRequest, error_message) end end it 'should not save different key under the same name' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- 834HREBEREU=JERIREIERERJREJREJWQIFWOEJFEW5T038Y4398034YY84G03WPEPWFEOFOEFJOE -----END PUBLIC KEY-----" EOK key_name = client.encode_component('test_key') username = client.encode_component('jdoe') error_message = 'Key under this name already uploaded, choose a different name' expect { client.add_key(username, key_name, key) }.to raise_error(Errors::BadRequest, error_message) end end it 'should remove the key by key_name' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test_key') client.delete_key(username, key_name) new_user_keys = client.keys('jdoe') expect(new_user_keys).not_to include({'key' => key}) end end it 'should remove the key by key_name with special characters' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test?key.pub') client.delete_key(username, key_name) new_user_keys = client.keys(username) expect(new_user_keys).not_to include({'key' => key}) end end it 'should not fail removing a non-existent key by key_name' do client_as_jdoe do |client| key = <<-EOK.gsub(/^ {6}/, '') "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 -----END PUBLIC KEY-----" EOK username = client.encode_component('jdoe') key_name = client.encode_component('test_key10000') client.delete_key(username, key_name) new_user_keys = client.keys(username) expect(new_user_keys).not_to include({'key' => key}) end end it 'should remove all keys for a user' do client_as_jdoe do |client| username = client.encode_component('jdoe') client.delete_keys(username) new_user_keys = client.keys(username) expect(new_user_keys).to be_empty end end it 'should not remove all keys for a different user' do client_as_jdoe do |client| username = client.encode_component('test_user') error_message = /not authorised to view the requested data/ expect { client.delete_keys(username) }.to raise_error(Errors::BadRequest, error_message) end end it 'should not fail while removing keys for user with no keys' do client_as_jdoe do |client| username = client.encode_component('jdoe') client.delete_keys(username) new_user_keys = client.keys(username) expect(new_user_keys).to be_empty end end end end