<commit_before># -*- coding: utf-8 -*-
"""Factories for the OSF models, including an abstract ModularOdmFactory.

Example usage: ::

    >>> from tests.factories import UserFactory
    >>> user1 = UserFactory()
    >>> user1.username
    <EMAIL>
    >>> user2 = UserFactory()
    <EMAIL>

Factory boy docs: http://factoryboy.readthedocs.org/

"""
import datetime
from factory import base, Sequence, SubFactory, post_generation, LazyAttribute

from framework.mongo import StoredObject
from framework.auth import User, Auth
from framework.auth.utils import impute_names_model
from website.oauth.models import ExternalAccount
from website.oauth.models import ExternalProvider
from website.project.model import (
    ApiKey, Node, NodeLog, WatchConfig, Tag, Pointer, Comment, PrivateLink,
)
from website.notifications.model import NotificationSubscription, NotificationDigest

from website.addons.wiki.model import NodeWikiPage
from tests.base import fake


# TODO: This is a hack. Check whether FactoryBoy can do this better
def save_kwargs(**kwargs):
    for value in kwargs.itervalues():
        if isinstance(value, StoredObject) and not value._is_loaded:
            value.save()


def FakerAttribute(provider, **kwargs):
    """Attribute that lazily generates a value using the Faker library.
    Example: ::

        class UserFactory(ModularOdmFactory):
            name = FakerAttribute('name')
    """
    fake_gen = getattr(fake, provider)
    if not fake_gen:
        raise ValueError('{0!r} is not a valid faker provider.'.format(provider))
    return LazyAttribute(lambda x: fake_gen(**kwargs))


class ModularOdmFactory(base.Factory):
    """Base factory for modular-odm objects.
    """

    ABSTRACT_FACTORY = True

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        """Build an object without saving it."""
        save_kwargs(**kwargs)
        return target_class(*args, **kwargs)

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        save_kwargs(**kwargs)
        instance = target_class(*args, **kwargs)
        instance.save()
        return instance


class UserFactory(ModularOdmFactory):
    FACTORY_FOR = User

    username = Sequence(lambda n: "<EMAIL>(n))
    # Don't use post generation call to set_password because
    # It slows down the tests dramatically
    password = "password"
    fullname = Sequence(lambda n: "<NAME>{0}".format(n))
    is_registered = True
    is_claimed = True
    api_keys = []
    date_confirmed = datetime.datetime(2014, 2, 21)
    merged_by = None
    email_verification = {}
    verification_key = None

    @post_generation
    def set_names(self, create, extracted):<commit_msg>correct the attribute name<commit_after># -*- coding: utf-8 -*-
"""Factories for the OSF models, including an abstract ModularOdmFactory.

Example usage: ::

    >>> from tests.factories import UserFactory
    >>> user1 = UserFactory()
    >>> user1.username
    <EMAIL>
    >>> user2 = UserFactory()
    <EMAIL>

Factory boy docs: http://factoryboy.readthedocs.org/

"""
import datetime
from factory import base, Sequence, SubFactory, post_generation, LazyAttribute

from framework.mongo import StoredObject
from framework.auth import User, Auth
from framework.auth.utils import impute_names_model
from website.oauth.models import ExternalAccount
from website.oauth.models import ExternalProvider
from website.project.model import (
    ApiKey, Node, NodeLog, WatchConfig, Tag, Pointer, Comment, PrivateLink,
)
from website.notifications.model import NotificationSubscription, NotificationDigest

from website.addons.wiki.model import NodeWikiPage
from tests.base import fake


# TODO: This is a hack. Check whether FactoryBoy can do this better
def save_kwargs(**kwargs):
    for value in kwargs.itervalues():
        if isinstance(value, StoredObject) and not value._is_loaded:
            value.save()


def FakerAttribute(provider, **kwargs):
    """Attribute that lazily generates a value using the Faker library.
    Example: ::

        class UserFactory(ModularOdmFactory):
            name = FakerAttribute('name')
    """
    fake_gen = getattr(fake, provider)
    if not fake_gen:
        raise ValueError('{0!r} is not a valid faker provider.'.format(provider))
    return LazyAttribute(lambda x: fake_gen(**kwargs))


class ModularOdmFactory(base.Factory):
    """Base factory for modular-odm objects.
    """

    ABSTRACT_FACTORY = True

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        """Build an object without saving it."""
        save_kwargs(**kwargs)
        return target_class(*args, **kwargs)

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        save_kwargs(**kwargs)
        instance = target_class(*args, **kwargs)
        instance.save()
        return instance


class UserFactory(ModularOdmFactory):
    FACTORY_FOR = User

    username = Sequence(lambda n: "<EMAIL>".<EMAIL>(n))
    # Don't use post generation call to set_password because
    # It slows down the tests dramatically
    password = "password"
    fullname = Sequence(lambda n: "<NAME>{0}".format(n))
    is_registered = True
    is_claimed = True
    api_keys = []
    date_confirmed = datetime.datetime(2014, 2, 21)
    merged_by = None
    email_verifications = {}
    verification_key = None

    @post_generation
    def set_names(self, create, extracted):
{'fraction_non_alphanumeric': 0.10109239029809294, 'fraction_numerical': 0.004813923347528236, 'mean_word_length': 3.677056277056277, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3174045', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1516, 'n_words': 462}