gitweb: tests: Convert functional tests to non-BDD python format

Signed-off-by: Veiko Aasa <veiko17@disroot.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
Veiko Aasa 2021-09-17 21:21:53 +03:00 committed by Sunil Mohan Adapa
parent e2c27a794c
commit 00be64036a
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
2 changed files with 176 additions and 323 deletions

View File

@ -1,113 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @gitweb @sso
Feature: gitweb Simple Git Hosting
Git web interface.
Background:
Given I'm a logged in user
And the gitweb application is installed
Scenario: Enable gitweb application
Given the gitweb application is disabled
When I enable the gitweb application
Then the gitweb site should be available
Scenario: Create public repository
Given the gitweb application is enabled
And a public repository that doesn't exist
When I create the repository
Then the repository should be listed as a public
And the repository should be listed on gitweb
Scenario: Create private repository
Given the gitweb application is enabled
And a private repository that doesn't exist
When I create the repository
Then the repository should be listed as a private
And the repository should be listed on gitweb
@backups
Scenario: Backup and restore gitweb
Given the gitweb application is enabled
And a repository
When I create a backup of the gitweb app data with name test_gitweb
And I delete the repository
And I restore the gitweb app data backup with name test_gitweb
Then the repository should be restored
And the gitweb site should be available
Scenario: Public gitweb site shows only public repositories
Given the gitweb application is enabled
And both public and private repositories exist
When I log out
Then the public repository should be listed on gitweb
And the private repository should not be listed on gitweb
Scenario: Gitweb is not public if there are only private repositories
Given the gitweb application is enabled
And at least one repository exists
And all repositories are private
When I log out
And I access gitweb application
Then I should be prompted for login
And gitweb app should not be visible on the front page
Scenario: Edit repository metadata
Given the gitweb application is enabled
And a public repository that doesn't exist
And a repository metadata:
description: Test Description
owner: Test Owner
access: private
When I create the repository
And I set the metadata of the repository
Then the metadata of the repository should be as set
Scenario: Edit default branch of the repository
Given the gitweb application is enabled
And a repository with the branch branch1
When I set branch1 as a default branch
Then the gitweb site should show branch1 as a default repo branch
Scenario: Access public repository with git client
Given the gitweb application is enabled
And a public repository
When using a git client
Then the repository should be publicly readable
And the repository should not be publicly writable
And the repository should be privately writable
Scenario: Access private repository with git client
Given the gitweb application is enabled
And a private repository
When using a git client
Then the repository should not be publicly readable
And the repository should not be publicly writable
And the repository should be privately readable
And the repository should be privately writable
Scenario: User of git-access group can access gitweb site
Given the gitweb application is enabled
And all repositories are private
And the user gituser in group git-access exists
When I'm logged in as the user gituser
Then the gitweb site should be available
Scenario: User not of git-access group can't access gitweb site
Given the gitweb application is enabled
And all repositories are private
And the user nogroupuser exists
When I'm logged in as the user nogroupuser
Then the gitweb site should not be available
Scenario: Delete repository
Given the gitweb application is enabled
And a repository
When I delete the repository
Then the repository should not be listed
Scenario: Disable gitweb application
Given the gitweb application is enabled
When I disable the gitweb application
Then the gitweb site should not be available

View File

@ -2,185 +2,136 @@
"""
Functional, browser based tests for gitweb app.
"""
import contextlib
import os
import shutil
import subprocess
import tempfile
from pytest_bdd import given, parsers, scenarios, then, when
import pytest
from plinth.tests import functional
scenarios('gitweb.feature')
pytestmark = [pytest.mark.apps, pytest.mark.gitweb]
_default_url = functional.config['DEFAULT']['url']
@given('a public repository')
@given('a repository')
@given('at least one repository exists')
def gitweb_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'public', True)
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'gitweb')
functional.app_enable(session_browser, 'gitweb')
yield
functional.login(session_browser)
functional.app_disable(session_browser, 'gitweb')
@given('a private repository')
def gitweb_private_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'private', True)
@pytest.fixture(autouse=True)
def fixture_login(session_browser):
"""Login fixture."""
functional.login(session_browser)
functional.app_enable(session_browser, 'gitweb')
yield
@given(parsers.parse('a repository with the branch {branch:w}'))
def _create_repo_with_branch(session_browser, branch):
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
_create_repo(session_browser, 'Test-repo', 'public')
_create_branch('Test-repo', branch)
@given('both public and private repositories exist')
def gitweb_public_and_private_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'public', True)
_create_repo(session_browser, 'Test-repo2', 'private', True)
@given(parsers.parse("a {access:w} repository that doesn't exist"))
def gitweb_nonexistent_repo(session_browser, access):
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
return dict(access=access)
@given('all repositories are private')
def gitweb_all_repositories_private(session_browser):
def test_all_repos_private(session_browser):
"""Test repo accessability when all repos are private."""
_create_repo(session_browser, 'Test-repo', 'private', ok_if_exists=True)
_set_all_repos_private(session_browser)
if not functional.user_exists(session_browser, 'gitweb_user'):
functional.create_user(session_browser, 'gitweb_user',
groups=['git-access'])
if not functional.user_exists(session_browser, 'nogroupuser'):
functional.create_user(session_browser, 'nogroupuser', groups=[])
functional.login_with_account(session_browser, functional.base_url,
'gitweb_user')
assert functional.is_available(session_browser, 'gitweb')
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 1
functional.login_with_account(session_browser, functional.base_url,
'nogroupuser')
assert not functional.is_available(session_browser, 'gitweb')
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 0
functional.logout(session_browser)
functional.access_url(session_browser, 'gitweb')
assert functional.is_login_prompt(session_browser)
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 0
@given(parsers.parse('a repository metadata:\n{metadata}'),
target_fixture='gitweb_repo_metadata')
def gitweb_repo_metadata(session_browser, metadata):
metadata_dict = {}
for item in metadata.split('\n'):
item = item.split(': ')
metadata_dict[item[0]] = item[1]
return metadata_dict
@when('I create the repository')
def gitweb_create_repo(session_browser, access):
_create_repo(session_browser, 'Test-repo', access)
@when('I delete the repository')
def gitweb_delete_repo(session_browser):
@pytest.mark.backups
def test_backup(session_browser):
"""Test backing up and restoring."""
_create_repo(session_browser, 'Test-repo', ok_if_exists=True)
functional.backup_create(session_browser, 'gitweb', 'test_gitweb')
_delete_repo(session_browser, 'Test-repo')
functional.backup_restore(session_browser, 'gitweb', 'test_gitweb')
assert _repo_exists(session_browser, 'Test-repo')
assert functional.is_available(session_browser, 'gitweb')
@when(parsers.parse('I set {branch:w} as a default branch'))
def gitweb_set_default_branch(session_browser, branch):
_set_default_branch(session_browser, 'Test-repo', branch)
@pytest.mark.parametrize('access', ['public', 'private'])
@pytest.mark.parametrize('repo_name', ['Test-repo', 'Test-repo.git'])
def test_create_delete_repo(session_browser, access, repo_name):
"""Test creating and deleting a repo and accessing with a git client."""
_delete_repo(session_browser, repo_name, ignore_missing=True)
_create_repo(session_browser, repo_name, access)
assert _repo_exists(session_browser, repo_name, access)
assert _site_repo_exists(session_browser, repo_name)
if access == "public":
assert _repo_is_readable(repo_name)
else:
assert not _repo_is_readable(repo_name)
assert not _repo_is_writable(repo_name)
assert _repo_is_readable(repo_name, with_auth=True)
assert _repo_is_writable(repo_name, with_auth=True)
_delete_repo(session_browser, repo_name)
assert not _repo_exists(session_browser, repo_name)
@when('I set the metadata of the repository')
def gitweb_edit_repo_metadata(session_browser, gitweb_repo_metadata):
_edit_repo_metadata(session_browser, 'Test-repo', gitweb_repo_metadata)
def test_both_private_and_public_repo_exist(session_browser):
"""Tests when both private and public repo exist."""
_create_repo(session_browser, 'Test-repo', 'public', True)
_create_repo(session_browser, 'Test-repo-private', 'private', True)
@when('using a git client')
def gitweb_using_git_client():
pass
@then(
parsers.parse(
'the gitweb site should show {branch:w} as a default repo branch'))
def gitweb_site_check_default_repo_branch(session_browser, branch):
assert _get_gitweb_site_default_repo_branch(session_browser,
'Test-repo') == branch
@then('the repository should be restored')
@then('the repository should be listed as a public')
def gitweb_repo_should_exists(session_browser):
assert _repo_exists(session_browser, 'Test-repo', access='public')
@then('the repository should be listed as a private')
def gitweb_private_repo_should_exists(session_browser):
assert _repo_exists(session_browser, 'Test-repo', 'private')
@then('the repository should not be listed')
def gitweb_repo_should_not_exist(session_browser):
assert not _repo_exists(session_browser, 'Test-repo')
@then('the public repository should be listed on gitweb')
@then('the repository should be listed on gitweb')
def gitweb_repo_should_exist_on_gitweb(session_browser):
functional.logout(session_browser)
assert _site_repo_exists(session_browser, 'Test-repo')
assert not _site_repo_exists(session_browser, 'Test-repo-private')
@then('the private repository should not be listed on gitweb')
def gitweb_private_repo_should_exists_on_gitweb(session_browser):
assert not _site_repo_exists(session_browser, 'Test-repo2')
def test_edit_repo_metadata(session_browser):
"""Test edit repo metadata."""
_create_repo(session_browser, 'Test-repo2', 'public', ok_if_exists=True)
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
repo_metadata = {
'name': 'Test-repo',
'description': 'Test Description',
'owner': 'Test Owner',
'access': 'private',
}
_edit_repo_metadata(session_browser, 'Test-repo2', repo_metadata)
assert _get_repo_metadata(session_browser, "Test-repo") == repo_metadata
_create_branch('Test-repo', 'branch1')
_set_default_branch(session_browser, 'Test-repo', 'branch1')
assert _get_gitweb_site_default_repo_branch(session_browser,
'Test-repo') == 'branch1'
@then('the metadata of the repository should be as set')
def gitweb_repo_metadata_should_match(session_browser, gitweb_repo_metadata):
actual_metadata = _get_repo_metadata(session_browser, 'Test-repo')
assert all(item in actual_metadata.items()
for item in gitweb_repo_metadata.items())
def test_enable_disable(session_browser):
"""Test enabling and disabling the app."""
functional.app_disable(session_browser, 'gitweb')
assert not functional.is_available(session_browser, 'gitweb')
@then('the repository should be publicly readable')
def gitweb_repo_publicly_readable():
assert _repo_is_readable('Test-repo')
assert _repo_is_readable('Test-repo', url_git_extension=True)
@then('the repository should not be publicly readable')
def gitweb_repo_not_publicly_readable():
assert not _repo_is_readable('Test-repo')
assert not _repo_is_readable('Test-repo', url_git_extension=True)
@then('the repository should not be publicly writable')
def gitweb_repo_not_publicly_writable():
assert not _repo_is_writable('Test-repo')
assert not _repo_is_writable('Test-repo', url_git_extension=True)
@then('the repository should be privately readable')
def gitweb_repo_privately_readable():
assert _repo_is_readable('Test-repo', with_auth=True)
assert _repo_is_readable('Test-repo', with_auth=True,
url_git_extension=True)
@then('the repository should be privately writable')
def gitweb_repo_privately_writable():
assert _repo_is_writable('Test-repo', with_auth=True)
assert _repo_is_writable('Test-repo', with_auth=True,
url_git_extension=True)
def _create_branch(repo, branch):
"""Create a branch on the remote repository."""
repo_url = _get_repo_url(repo, with_auth=True)
with _gitweb_temp_directory() as temp_directory:
repo_path = os.path.join(temp_directory, repo)
_create_local_repo(repo_path)
add_branch_commands = [['git', 'checkout', '-q', '-b', branch],
[
'git', '-c', 'user.name=Tester', '-c',
'user.email=tester', 'commit', '-q',
'--allow-empty', '-m', 'test_branch1'
],
['git', 'push', '-q', '-f', repo_url, branch]]
for command in add_branch_commands:
subprocess.check_call(command, cwd=repo_path)
functional.app_enable(session_browser, 'gitweb')
assert functional.is_available(session_browser, 'gitweb')
def _create_local_repo(path):
@ -200,7 +151,7 @@ def _create_repo(browser, repo, access=None, ok_if_exists=False):
"""Create repository."""
if not _repo_exists(browser, repo, access):
_delete_repo(browser, repo, ignore_missing=True)
browser.find_link_by_href('/plinth/apps/gitweb/create/').first.click()
browser.links.find_by_href('/plinth/apps/gitweb/create/').first.click()
browser.find_by_id('id_gitweb-name').fill(repo)
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
@ -211,10 +162,32 @@ def _create_repo(browser, repo, access=None, ok_if_exists=False):
assert False, 'Repo already exists.'
def _create_branch(repo, branch):
"""Add a branch to the repo."""
repo_url = _get_repo_url(repo, with_auth=True)
with _gitweb_temp_directory() as temp_directory:
repo_path = os.path.join(temp_directory, repo)
_create_local_repo(repo_path)
add_branch_commands = [['git', 'checkout', '-q', '-b', branch],
[
'git', '-c', 'user.name=Tester', '-c',
'user.email=tester', 'commit', '-q',
'--allow-empty', '-m', 'test_branch1'
],
['git', 'push', '-q', '-f', repo_url, branch]]
for command in add_branch_commands:
subprocess.check_call(command, cwd=repo_path)
def _delete_repo(browser, repo, ignore_missing=False):
"""Delete repository."""
functional.nav_to_module(browser, 'gitweb')
delete_link = browser.find_link_by_href(
if repo.endswith('.git'):
repo = repo[:-4]
delete_link = browser.links.find_by_href(
'/plinth/apps/gitweb/{}/delete/'.format(repo))
if delete_link or not ignore_missing:
delete_link.first.click()
@ -224,20 +197,15 @@ def _delete_repo(browser, repo, ignore_missing=False):
def _edit_repo_metadata(browser, repo, metadata):
"""Set repository metadata."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if 'name' in metadata:
browser.find_by_id('id_gitweb-name').fill(metadata['name'])
if 'description' in metadata:
browser.find_by_id('id_gitweb-description').fill(
metadata['description'])
if 'owner' in metadata:
browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
if 'access' in metadata:
if metadata['access'] == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
browser.find_by_id('id_gitweb-name').fill(metadata['name'])
browser.find_by_id('id_gitweb-description').fill(metadata['description'])
browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
if metadata['access'] == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
@ -251,7 +219,7 @@ def _get_gitweb_site_default_repo_branch(browser, repo):
def _get_repo_metadata(browser, repo):
"""Get repository metadata."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
metadata = {}
for item in ['name', 'description', 'owner']:
@ -278,6 +246,22 @@ def _get_repo_url(repo, with_auth):
scheme, functional.config['DEFAULT']['username'], password, url, repo)
def _gitweb_git_command_is_successful(command, cwd):
"""Check if a command runs successfully or gives authentication error"""
# Tell OS not to translate command return messages
env = os.environ.copy()
env['LC_ALL'] = 'C'
process = subprocess.run(command, capture_output=True, cwd=cwd, env=env,
check=False)
if process.returncode != 0:
if 'Authentication failed' in process.stderr.decode():
return False
print(process.stdout.decode())
process.check_returncode() # Raise exception
return True
@contextlib.contextmanager
def _gitweb_temp_directory():
"""Create temporary directory"""
@ -286,26 +270,12 @@ def _gitweb_temp_directory():
shutil.rmtree(name)
def _gitweb_git_command_is_successful(command, cwd):
"""Check if a command runs successfully or gives authentication error"""
# Tell OS not to translate command return messages
env = os.environ.copy()
env['LC_ALL'] = 'C'
process = subprocess.run(command, capture_output=True, cwd=cwd, env=env)
if process.returncode != 0:
if 'Authentication failed' in process.stderr.decode():
return False
print(process.stdout.decode())
# raise exception
process.check_returncode()
return True
def _repo_exists(browser, repo, access=None):
"""Check whether the repository exists."""
functional.nav_to_module(browser, 'gitweb')
links_found = browser.find_link_by_href('/gitweb/{}.git'.format(repo))
if not repo.endswith('.git'):
repo = repo + ".git"
links_found = browser.links.find_by_href('/gitweb/{}'.format(repo))
access_matches = True
if links_found and access:
parent = links_found.first.find_by_xpath('..').first
@ -317,53 +287,26 @@ def _repo_exists(browser, repo, access=None):
return bool(links_found) and access_matches
def _repo_is_readable(repo, with_auth=False, url_git_extension=False):
def _repo_is_readable(repo, with_auth=False):
"""Check if a git repo is readable with git client."""
url = _get_repo_url(repo, with_auth)
if url_git_extension:
url = url + '.git'
git_command = ['git', 'clone', '-c', 'http.sslverify=false', url]
with _gitweb_temp_directory() as cwd:
return _gitweb_git_command_is_successful(git_command, cwd)
def _repo_is_writable(repo, with_auth=False, url_git_extension=False):
def _repo_is_writable(repo, with_auth=False):
"""Check if a git repo is writable with git client."""
url = _get_repo_url(repo, with_auth)
if url_git_extension:
url = url + '.git'
with _gitweb_temp_directory() as temp_directory:
repo_directory = os.path.join(temp_directory, 'test-project')
_create_local_repo(repo_directory)
git_push_command = ['git', 'push', '-qf', url, 'master']
return _gitweb_git_command_is_successful(git_push_command,
repo_directory)
def _set_default_branch(browser, repo, branch):
"""Set default branch of the repository."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-default_branch').select(branch)
functional.submit(browser)
def _set_repo_access(browser, repo, access):
"""Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
def _set_all_repos_private(browser):
"""Set all repositories private"""
functional.nav_to_module(browser, 'gitweb')
@ -376,7 +319,30 @@ def _set_all_repos_private(browser):
_set_repo_access(browser, repo, 'private')
def _set_default_branch(browser, repo, branch):
"""Set default branch of the repository."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-default_branch').select(branch)
functional.submit(browser)
def _set_repo_access(browser, repo, access):
"""Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
def _site_repo_exists(browser, repo):
"""Check whether the repository exists on Gitweb site."""
browser.visit('{}/gitweb'.format(_default_url))
return browser.find_by_css('a[href="/gitweb/{0}.git"]'.format(repo))
if not repo.endswith('.git'):
repo = repo + ".git"
return bool(browser.find_by_css('a[href="/gitweb/{0}"]'.format(repo)))