First pass at new automated QA API test for #52703
Checks that archives of two different user projects with the same name aren't the same via checksum. I.E. a user can't download the archive of another's project by mistake. To enable the test some enhancements were made. Namely updating the client module to handle more than one API instance and the creation a custom rest call method that downloads to tmp.
This commit is contained in:
parent
58f3a56154
commit
eecd85d461
|
@ -13,6 +13,8 @@ module QA
|
|||
ResourceURLMissingError = Class.new(RuntimeError)
|
||||
|
||||
attr_reader :api_resource, :api_response
|
||||
attr_writer :api_client
|
||||
attr_accessor :user
|
||||
|
||||
def api_support?
|
||||
respond_to?(:api_get_path) &&
|
||||
|
@ -29,9 +31,12 @@ module QA
|
|||
end
|
||||
|
||||
def eager_load_api_client!
|
||||
return unless api_client.nil?
|
||||
|
||||
api_client.tap do |client|
|
||||
# Eager-load the API client so that the personal token creation isn't
|
||||
# taken in account in the actual resource creation timing.
|
||||
client.user = user
|
||||
client.personal_access_token
|
||||
end
|
||||
end
|
||||
|
@ -76,7 +81,7 @@ module QA
|
|||
|
||||
def api_client
|
||||
@api_client ||= begin
|
||||
Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'))
|
||||
Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'), user: user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ module QA
|
|||
def fabricate!
|
||||
populate(:push)
|
||||
|
||||
fork.visit!
|
||||
fork.project.visit!
|
||||
|
||||
Page::Project::Show.perform(&:new_merge_request)
|
||||
Page::MergeRequest::New.perform(&:create_merge_request)
|
||||
|
|
|
@ -11,7 +11,9 @@ module QA
|
|||
|
||||
attribute :id
|
||||
attribute :name
|
||||
attribute :add_name_uuid
|
||||
attribute :description
|
||||
attribute :standalone
|
||||
|
||||
attribute :group do
|
||||
Group.fabricate!
|
||||
|
@ -38,18 +40,21 @@ module QA
|
|||
end
|
||||
|
||||
def initialize
|
||||
@add_name_uuid = true
|
||||
@standalone = false
|
||||
@description = 'My awesome project'
|
||||
@initialize_with_readme = false
|
||||
end
|
||||
|
||||
def name=(raw_name)
|
||||
@name = "#{raw_name}-#{SecureRandom.hex(8)}"
|
||||
@name = @add_name_uuid ? "#{raw_name}-#{SecureRandom.hex(8)}" : raw_name
|
||||
end
|
||||
|
||||
def fabricate!
|
||||
group.visit!
|
||||
|
||||
Page::Group::Show.perform(&:go_to_new_project)
|
||||
unless @standalone
|
||||
group.visit!
|
||||
Page::Group::Show.perform(&:go_to_new_project)
|
||||
end
|
||||
|
||||
Page::Project::New.perform do |page|
|
||||
page.choose_test_namespace
|
||||
|
@ -71,19 +76,28 @@ module QA
|
|||
"/projects/#{CGI.escape(path_with_namespace)}"
|
||||
end
|
||||
|
||||
def api_get_archive_path(type = 'tar.gz')
|
||||
"#{api_get_path}/repository/archive.#{type}"
|
||||
end
|
||||
|
||||
def api_post_path
|
||||
'/projects'
|
||||
end
|
||||
|
||||
def api_post_body
|
||||
{
|
||||
namespace_id: group.id,
|
||||
path: name,
|
||||
post_body = {
|
||||
name: name,
|
||||
description: description,
|
||||
visibility: 'public',
|
||||
initialize_with_readme: @initialize_with_readme
|
||||
}
|
||||
|
||||
unless @standalone
|
||||
post_body[:namespace_id] = group.id
|
||||
post_body[:path] = name
|
||||
end
|
||||
|
||||
post_body
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -88,7 +88,7 @@ module QA
|
|||
}.merge(ldap_post_body)
|
||||
end
|
||||
|
||||
def self.fabricate_or_use(username, password)
|
||||
def self.fabricate_or_use(username = nil, password = nil)
|
||||
if Runtime::Env.signup_disabled?
|
||||
self.new.tap do |user|
|
||||
user.username = username
|
||||
|
|
|
@ -6,31 +6,34 @@ module QA
|
|||
module Runtime
|
||||
module API
|
||||
class Client
|
||||
attr_reader :address
|
||||
attr_reader :address, :user
|
||||
|
||||
def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true)
|
||||
def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil)
|
||||
@address = address
|
||||
@personal_access_token = personal_access_token
|
||||
@is_new_session = is_new_session
|
||||
@user = user
|
||||
end
|
||||
|
||||
def personal_access_token
|
||||
@personal_access_token ||= begin
|
||||
# you can set the environment variable GITLAB_QA_ACCESS_TOKEN
|
||||
# to use a specific access token rather than create one from the UI
|
||||
Runtime::Env.personal_access_token ||= create_personal_access_token
|
||||
# unless a specific user has been passed
|
||||
@user.nil? ? Runtime::Env.personal_access_token ||= create_personal_access_token : create_personal_access_token
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_personal_access_token
|
||||
Runtime::Browser.visit(@address, Page::Main::Login) if @is_new_session
|
||||
do_create_personal_access_token
|
||||
end
|
||||
Page::Main::Menu.perform(&:sign_out) if @is_new_session && Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
|
||||
|
||||
unless Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
|
||||
Runtime::Browser.visit(@address, Page::Main::Login)
|
||||
Page::Main::Login.perform { |login| login.sign_in_using_credentials(@user) }
|
||||
end
|
||||
|
||||
def do_create_personal_access_token
|
||||
Page::Main::Login.perform(&:sign_in_using_credentials)
|
||||
Resource::PersonalAccessToken.fabricate!.access_token
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'securerandom'
|
||||
require 'digest'
|
||||
|
||||
module QA
|
||||
context 'Create' do
|
||||
describe 'Compare archives of different user projects with the same name and check they\'re different' do
|
||||
include Support::Api
|
||||
|
||||
before(:all) do
|
||||
@project_name = "project-archive-download-#{SecureRandom.hex(8)}"
|
||||
@archive_types = %w(tar.gz tar.bz2 tar zip)
|
||||
@users = {
|
||||
user1: { username: Runtime::Env.gitlab_qa_username_1, password: Runtime::Env.gitlab_qa_password_1 },
|
||||
user2: { username: Runtime::Env.gitlab_qa_username_2, password: Runtime::Env.gitlab_qa_password_2 }
|
||||
}
|
||||
|
||||
@users.each do |_, user_info|
|
||||
user_info[:user] = Resource::User.fabricate_or_use(user_info[:username], user_info[:password])
|
||||
user_info[:api_client] = Runtime::API::Client.new(:gitlab, user: user_info[:user])
|
||||
user_info[:api_client].personal_access_token
|
||||
user_info[:project] = create_project(user_info[:user], user_info[:api_client], @project_name)
|
||||
Page::Main::Menu.perform(&:sign_out)
|
||||
end
|
||||
end
|
||||
|
||||
it 'download archives of each user project then check they are different' do
|
||||
archive_checksums = {}
|
||||
|
||||
@users.each do |user_key, user_info|
|
||||
archive_checksums[user_key] = {}
|
||||
|
||||
@archive_types.each do |type|
|
||||
archive_path = download_project_archive_via_api(user_info[:api_client], user_info[:project], type).path
|
||||
archive_checksums[user_key][type] = Digest::MD5.hexdigest(File.read(archive_path))
|
||||
end
|
||||
end
|
||||
|
||||
QA::Runtime::Logger.debug("Archive checksums are #{archive_checksums}")
|
||||
|
||||
expect(archive_checksums[:user1]).not_to include(archive_checksums[:user2])
|
||||
end
|
||||
|
||||
def create_project(user, api_client, project_name)
|
||||
project = Resource::Project.fabricate! do |project|
|
||||
project.standalone = true
|
||||
project.add_name_uuid = false
|
||||
project.name = project_name
|
||||
project.path_with_namespace = "#{user.name}/#{project_name}"
|
||||
project.user = user
|
||||
project.api_client = api_client
|
||||
end
|
||||
|
||||
Resource::Repository::ProjectPush.fabricate! do |push|
|
||||
push.project = project
|
||||
push.file_name = 'README.md'
|
||||
push.file_content = '# This is a test project'
|
||||
push.commit_message = 'Add README.md'
|
||||
push.user = user
|
||||
end
|
||||
|
||||
project
|
||||
end
|
||||
|
||||
def download_project_archive_via_api(api_client, project, type = 'tar.gz')
|
||||
get_project_archive_zip = Runtime::API::Request.new(api_client, project.api_get_archive_path(type))
|
||||
project_archive_download = get(get_project_archive_zip.url, raw_response: true)
|
||||
expect(project_archive_download.code).to eq(200)
|
||||
|
||||
project_archive_download.file
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,11 +16,12 @@ module QA
|
|||
e.response
|
||||
end
|
||||
|
||||
def get(url)
|
||||
def get(url, raw_response: false)
|
||||
RestClient::Request.execute(
|
||||
method: :get,
|
||||
url: url,
|
||||
verify_ssl: false)
|
||||
verify_ssl: false,
|
||||
raw_response: raw_response)
|
||||
rescue RestClient::ExceptionWithResponse => e
|
||||
e.response
|
||||
end
|
||||
|
|
|
@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do
|
|||
end
|
||||
|
||||
describe '#personal_access_token' do
|
||||
context 'when QA::Runtime::Env.personal_access_token is present' do
|
||||
context 'when user is nil and QA::Runtime::Env.personal_access_token is present' do
|
||||
before do
|
||||
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token')
|
||||
end
|
||||
|
||||
it 'returns specified token from env' do
|
||||
expect(described_class.new.personal_access_token).to eq 'a_token'
|
||||
expect(subject.personal_access_token).to eq 'a_token'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when QA::Runtime::Env.personal_access_token is nil' do
|
||||
context 'when user is present and QA::Runtime::Env.personal_access_token is nil' do
|
||||
before do
|
||||
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil)
|
||||
end
|
||||
|
||||
it 'returns a created token' do
|
||||
subject { described_class.new(user: { username: 'foo' }) }
|
||||
|
||||
expect(subject).to receive(:create_personal_access_token).and_return('created_token')
|
||||
|
||||
expect(subject.personal_access_token).to eq 'created_token'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is nil and QA::Runtime::Env.personal_access_token is nil' do
|
||||
before do
|
||||
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil)
|
||||
end
|
||||
|
||||
it 'returns a created token' do
|
||||
client = described_class.new
|
||||
|
||||
expect(client).to receive(:create_personal_access_token).and_return('created_token')
|
||||
|
||||
expect(client.personal_access_token).to eq 'created_token'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is present and QA::Runtime::Env.personal_access_token is present' do
|
||||
before do
|
||||
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token')
|
||||
end
|
||||
|
||||
it 'returns a created token' do
|
||||
client = described_class.new(user: { username: 'foo' })
|
||||
|
||||
expect(client).to receive(:create_personal_access_token).and_return('created_token')
|
||||
|
||||
expect(client.personal_access_token).to eq 'created_token'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue