# Path: extrapypi/extensions.py

# 
# Path: extrapypi/app.py
# def configure_app(app, testing, config):
#     """Set configuration for application
# 
#     Configuration will be loaded in the following order:
# 
#     * test_config if testing is True
#     * else if config parameter is not None we load it
#     * else if env variable for config is set we use it
#     """
#     app.config.from_object('extrapypi.config')
# 
#     env_config = os.environ.get('EXTRAPYPI_CONFIG', None)
# 
#     if testing is True:
#         app.config.from_object('extrapypi.test_config')
#     elif config is not None:
#         app.config.from_pyfile(config)
#     elif env_config is not None:
#         app.config.from_pyfile(env_config)
# 
# Path: extrapypi/commons/filters.py
# def tohtml(s):
#     """Convert rst string to raw html
# 
#     Used for display long description of releases
#     """
#     return publish_parts(s, writer_name='html')['body']
# 
# Path: extrapypi/commons/login.py
# def user_loader(user_id):
#     """Default user handler, from Flask-Login documentation
#     """
#     return User.query.get(user_id)
# 
# Path: extrapypi/commons/packages.py
# def get_store(name, params):
#     """Utility function to get correct storage class based
#     on its name
# 
#     :param str name: name of the storage
#     :param dict params: storage params from application config
#     :return: Correct storage class instance, passing params to constructor
#     :rtype: BaseStorage
#     :raises: AttributeError
#     """
#     storage_classes = [getattr(storage, c) for c in storage.__all__]
#     storage_classes = list(filter(lambda x: issubclass(x, BaseStorage),
#                                   storage_classes))
# 
#     store = next((c for c in storage_classes if c.NAME == name), None)
#     if store is None:
#         log.error("Storage {} does not exists".format(name))
#         raise AttributeError("Storage {} does not exists".format(name))
#     return store(**params)
# 
# def create_package(name, summary, store):
#     """Create a package for a given release
#     if the package don't exists already
# 
#     .. note::
#         Maintainer and installer cannot create packages
# 
#     :param dict data: request data to use to create package
#     :param extrapypi.storage.BaseStorage storage: storage object to use
#     :raises: PermissionDenied
#     """
#     dev_permission.test()
#     p = Package(
#         name=name,
#         summary=summary
#     )
# 
#     if store.create_package(p) is False:
#         log.error(
#             "Cannot create storage for package {0.name} using {1.NAME}"
#             .format(p, store)
#         )
#         raise RuntimeError("Storage missconfigured")
# 
#     db.session.add(p)
#     db.session.commit()
#     return p
# 
# def create_release_from_source(metadata, user):
#     """Create a new release from a raw file. Used for import of existing packages into database
# 
#     .. warning::
# 
#         This function does not check any permissions since it's never called from web ui
# 
#     If a release already exists, it does nothing
# 
#     :param dict metadata: metadata of the package
#     :param extrapypi.models.User user: user to use as maintainer
#     """
#     try:
#         package = Package.query.filter_by(name=metadata['name']).one()
#     except NoResultFound:
#         package = Package(
#             name=metadata['name'],
#             summary=metadata.get('summary', 'UNKNOWN')
#         )
#         db.session.add(package)
# 
#     release = Release.query.filter_by(version=metadata['version'], package=package)\
#                            .first()
# 
#     if release is None:
#         release = Release(
#             description=metadata.get('description', 'UNKNOWN'),
#             download_url=metadata.get('download_url', 'UNKNOW'),
#             home_page=metadata.get('home_page', 'UNKNOWN'),
#             version=metadata['version'],
#             keywords=metadata.get('keywords'),
#             package=package
#         )
#         db.session.add(release)
# 
#     if user not in package.maintainers:
#         package.maintainers.append(user)
# 
#     try:
#         db.session.commit()
#     except Exception:
#         db.session.rollback()
#         raise
# 
#     return release


import os
import pytest
import pkginfo
from flask import Flask
from flask_principal import Permission
from extrapypi.extensions import db
from extrapypi.app import configure_app
from extrapypi.commons.filters import tohtml
from extrapypi.commons.login import user_loader
from extrapypi.commons.packages import get_store, create_package, create_release_from_source
def test_get_store_errors():
    with pytest.raises(AttributeError):
        get_store('BadStore', {})


def test_create_package_errors(app, client, badstore, monkeypatch):
    def pass_permission(obj):
        return True
    monkeypatch.setattr(Permission, 'test', pass_permission)
    with pytest.raises(RuntimeError):
        create_package("test", "test", badstore)


def test_create_release_from_source(admin_user, packages, tmpdir, monkeypatch):
    metadata = {
        'version': '0.1',
        'description': 'test',
        'name': 'unknow-package',
        'summary': 'test',
        'md5_digest': 'test'
    }

    # unknown package
    r = create_release_from_source(metadata, admin_user)
    assert r.version == '0.1'
    assert r.description == 'test'
    assert r.download_url == 'UNKNOW'

    # known package
    metadata['name'] = packages[0].name

# Path: extrapypi/extensions.py

# 
# Path: extrapypi/app.py
# def configure_app(app, testing, config):
#     """Set configuration for application
# 
#     Configuration will be loaded in the following order:
# 
#     * test_config if testing is True
#     * else if config parameter is not None we load it
#     * else if env variable for config is set we use it
#     """
#     app.config.from_object('extrapypi.config')
# 
#     env_config = os.environ.get('EXTRAPYPI_CONFIG', None)
# 
#     if testing is True:
#         app.config.from_object('extrapypi.test_config')
#     elif config is not None:
#         app.config.from_pyfile(config)
#     elif env_config is not None:
#         app.config.from_pyfile(env_config)
# 
# Path: extrapypi/commons/filters.py
# def tohtml(s):
#     """Convert rst string to raw html
# 
#     Used for display long description of releases
#     """
#     return publish_parts(s, writer_name='html')['body']
# 
# Path: extrapypi/commons/login.py
# def user_loader(user_id):
#     """Default user handler, from Flask-Login documentation
#     """
#     return User.query.get(user_id)
# 
# Path: extrapypi/commons/packages.py
# def get_store(name, params):
#     """Utility function to get correct storage class based
#     on its name
# 
#     :param str name: name of the storage
#     :param dict params: storage params from application config
#     :return: Correct storage class instance, passing params to constructor
#     :rtype: BaseStorage
#     :raises: AttributeError
#     """
#     storage_classes = [getattr(storage, c) for c in storage.__all__]
#     storage_classes = list(filter(lambda x: issubclass(x, BaseStorage),
#                                   storage_classes))
# 
#     store = next((c for c in storage_classes if c.NAME == name), None)
#     if store is None:
#         log.error("Storage {} does not exists".format(name))
#         raise AttributeError("Storage {} does not exists".format(name))
#     return store(**params)
# 
# def create_package(name, summary, store):
#     """Create a package for a given release
#     if the package don't exists already
# 
#     .. note::
#         Maintainer and installer cannot create packages
# 
#     :param dict data: request data to use to create package
#     :param extrapypi.storage.BaseStorage storage: storage object to use
#     :raises: PermissionDenied
#     """
#     dev_permission.test()
#     p = Package(
#         name=name,
#         summary=summary
#     )
# 
#     if store.create_package(p) is False:
#         log.error(
#             "Cannot create storage for package {0.name} using {1.NAME}"
#             .format(p, store)
#         )
#         raise RuntimeError("Storage missconfigured")
# 
#     db.session.add(p)
#     db.session.commit()
#     return p
# 
# def create_release_from_source(metadata, user):
#     """Create a new release from a raw file. Used for import of existing packages into database
# 
#     .. warning::
# 
#         This function does not check any permissions since it's never called from web ui
# 
#     If a release already exists, it does nothing
# 
#     :param dict metadata: metadata of the package
#     :param extrapypi.models.User user: user to use as maintainer
#     """
#     try:
#         package = Package.query.filter_by(name=metadata['name']).one()
#     except NoResultFound:
#         package = Package(
#             name=metadata['name'],
#             summary=metadata.get('summary', 'UNKNOWN')
#         )
#         db.session.add(package)
# 
#     release = Release.query.filter_by(version=metadata['version'], package=package)\
#                            .first()
# 
#     if release is None:
#         release = Release(
#             description=metadata.get('description', 'UNKNOWN'),
#             download_url=metadata.get('download_url', 'UNKNOW'),
#             home_page=metadata.get('home_page', 'UNKNOWN'),
#             version=metadata['version'],
#             keywords=metadata.get('keywords'),
#             package=package
#         )
#         db.session.add(release)
# 
#     if user not in package.maintainers:
#         package.maintainers.append(user)
# 
#     try:
#         db.session.commit()
#     except Exception:
#         db.session.rollback()
#         raise
# 
#     return release


# Path: tests/test_commons.py
import os
import pytest
import pkginfo
from flask import Flask
from flask_principal import Permission
from extrapypi.extensions import db
from extrapypi.app import configure_app
from extrapypi.commons.filters import tohtml
from extrapypi.commons.login import user_loader
from extrapypi.commons.packages import get_store, create_package, create_release_from_source

def test_get_store_errors():
    with pytest.raises(AttributeError):
        get_store('BadStore', {})


def test_create_package_errors(app, client, badstore, monkeypatch):
    def pass_permission(obj):
        return True
    monkeypatch.setattr(Permission, 'test', pass_permission)
    with pytest.raises(RuntimeError):
        create_package("test", "test", badstore)


def test_create_release_from_source(admin_user, packages, tmpdir, monkeypatch):
    metadata = {
        'version': '0.1',
        'description': 'test',
        'name': 'unknow-package',
        'summary': 'test',
        'md5_digest': 'test'
    }

    # unknown package
    r = create_release_from_source(metadata, admin_user)
    assert r.version == '0.1'
    assert r.description == 'test'
    assert r.download_url == 'UNKNOW'

    # known package
    metadata['name'] = packages[0].name

    r = create_release_from_source(metadata, admin_user)