class CountryRegionFactory(DjangoModelFactory): class Meta: model = 'hosting.CountryRegion' class Params: short_code = factory.LazyFunction(lambda: random() < 0.20) country = Faker('random_element', elements=COUNTRIES.keys()) iso_code = Faker('pystr_format', string_format='???#', letters='ABCDEFGHJKLMNPQRSTUVWXYZ') latin_code = factory.Maybe('short_code', yes_declaration=Faker( 'pystr_format', string_format='??', letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ'), no_declaration=Faker('sentence', nb_words=3)) latin_name = factory.Maybe('short_code', yes_declaration=Faker('sentence', nb_words=3), no_declaration="") @factory.lazy_attribute def esperanto_name(self): latin_region = self.latin_name or self.latin_code replacements = [ ('Q', 'Kv'), ('q', 'kv'), ('W', 'V'), ('w', 'v'), ('X', 'Ks'), ('x', 'ks'), ('Y', 'J'), ('y ', 'i '), ('y.', 'i.'), ('y', 'j'), ('Ph', 'F'), ('ph', 'f'), ('Th', 'Z'), ('th', 'z'), ('cc', 'k'), ('ee', 'i'), ('ll', 'l'), ('tt', 't'), (' ', '-'), ('.', 'o'), ] for lat_letter, esp_letter in replacements: latin_region = latin_region.replace(lat_letter, esp_letter) return latin_region
class DimensionFactory(factory.alchemy.SQLAlchemyModelFactory): """ TODO: Needs further work around generating chart/table highcharts and source data (maybe). """ class Meta: model = Dimension sqlalchemy_session_persistence = "commit" guid = factory.Faker("uuid4") title = factory.Faker("sentence", nb_words=5) time_period = "2018/19" # questionable summary = factory.Faker("sentence", nb_words=10) created_at = factory.Faker("past_date", start_date="-30d") updated_at = factory.Faker("past_date", start_date="-7d") measure_version_id = factory.Maybe( "measure_version", factory.SelfAttribute("measure_version.id")) position = factory.Sequence(lambda x: x) chart_id = factory.Maybe("dimension_chart", factory.SelfAttribute("dimension_chart.id")) table_id = factory.Maybe("dimension_table", factory.SelfAttribute("dimension_table.id")) # scalar relationships dimension_chart = factory.SubFactory(ChartFactory) dimension_table = factory.SubFactory(TableFactory) # array-based relationships @factory.post_generation def classification_links(self, create, extracted, **kwargs): # If some classification_links were passed into the create invocation: # eg factory.create(classification_links=[classification_link1, classification_link2]) if extracted is not None: # Attach those classification_links to this newly-created instance. for classification_link in extracted: self.classification_links.append(classification_link) else: factory_method = _get_factory_generator_for_strategy( DimensionClassificationFactory, create) self.classification_links = [ factory_method(dimension=self, **kwargs) ] measure_version = None # Don't generate relationships 'towards' MeasureVersionFactory; see tests/README.md
class InvestmentProjectFactory(factory.django.DjangoModelFactory): """Investment project factory.""" created_by = factory.SubFactory(AdviserFactory) modified_by = factory.SelfAttribute('created_by') name = factory.Sequence(lambda n: f'name {n}') description = factory.Sequence(lambda n: f'desc {n}') comments = factory.Faker('text') estimated_land_date = date(2020, 1, 1) investment_type_id = InvestmentType.commitment_to_invest.value.id referral_source_activity_id = ReferralSourceActivity.cold_call.value.id investor_type_id = InvestorType.new_investor.value.id level_of_involvement_id = Involvement.no_involvement.value.id specific_programme_id = SpecificProgramme.space.value.id stage_id = InvestmentProjectStage.prospect.value.id sector_id = Sector.aerospace_assembly_aircraft.value.id investor_company = factory.SubFactory(CompanyFactory) country_investment_originates_from = factory.Maybe( factory.SelfAttribute('investor_company'), factory.SelfAttribute('investor_company.address_country'), None, ) client_relationship_manager = factory.SubFactory(AdviserFactory) referral_source_adviser = factory.SubFactory(AdviserFactory) likelihood_to_land_id = LikelihoodToLand.high.value.id archived_documents_url_path = factory.Faker('uri_path') created_on = now() @to_many_field def business_activities(self): """Add support for setting business_activities.""" return [InvestmentBusinessActivity.retail.value.id] @to_many_field def client_contacts(self): """Add support for setting client_contacts.""" return [ContactFactory().pk, ContactFactory().pk] @to_many_field def competitor_countries(self): """Add support for setting competitor_countries.""" @to_many_field def strategic_drivers(self): """Add support for setting strategic_drivers.""" @to_many_field def uk_region_locations(self): """Add support for setting uk_region_locations.""" @to_many_field def actual_uk_regions(self): """Add support for setting actual_uk_regions.""" @to_many_field def delivery_partners(self): """Add support for setting delivery_partners.""" class Meta: model = 'investment.InvestmentProject'
class GreeniOAIPMHResourceFactory(factory.django.DjangoModelFactory): class Meta: model = GreeniOAIPMHResource strategy = factory.BUILD_STRATEGY class Params: is_initial = True number = 0 resumption = None since = factory.Maybe( "is_initial", make_aware(datetime(year=1970, month=1, day=1)), make_aware( datetime(year=2020, month=2, day=10, hour=13, minute=8, second=39, microsecond=315000))) set_specification = SET_SPECIFICATION status = 200 head = {"content-type": "text/xml"} @factory.lazy_attribute def uri(self): from_param = f"from={self.since:%Y-%m-%dT%H:%M:%SZ}" identity = quote(f"{from_param}&metadataPrefix={METADATA_PREFIX}&set={self.set_specification}", safe="=&") \ if not self.resumption else f"resumptionToken={quote(self.resumption)}" return f"{ENDPOINT}?{identity}&verb=ListRecords" @factory.lazy_attribute def request(self): return { "args": [self.set_specification, f"{self.since:%Y-%m-%dT%H:%M:%SZ}"], "kwargs": {}, "method": "get", "url": "https://" + self.uri, "headers": {}, "data": {} } @factory.lazy_attribute def body(self): response_type = "initial" if self.is_initial else "delta" response_file = f"fixture.{SLUG}.{response_type}.{self.number}.xml" response_file_path = os.path.join(settings.BASE_DIR, "sources", "factories", "fixtures", response_file) with open(response_file_path, "r") as response: return response.read() @classmethod def create_common_responses(cls, include_delta=False): cls.create(is_initial=True, number=0) cls.create(is_initial=True, number=1, resumption=RESUMPTION_TOKEN) if include_delta: cls.create(is_initial=False, number=0)
class StockFactory(BaseFactory): class Meta: model = models.Stock offer = factory.SubFactory(OfferFactory) price = 10 quantity = 1000 beginningDatetime = factory.Maybe( "offer.isEvent", factory.LazyFunction(lambda: datetime.datetime.now() + datetime.timedelta(days=5)), None, ) bookingLimitDatetime = factory.Maybe( "stock.beginningDatetime and offer.isEvent", factory.LazyAttribute(lambda stock: stock.beginningDatetime - datetime.timedelta(minutes=60)), None, )
class AnatomyToolOAIPMHFactory(factory.django.DjangoModelFactory): class Meta: model = AnatomyToolOAIPMH strategy = factory.BUILD_STRATEGY class Params: is_initial = True number = 0 resumption = None since = factory.Maybe( "is_initial", make_aware(datetime(year=1970, month=1, day=1)), make_aware( datetime(year=2020, month=2, day=10, hour=13, minute=8, second=39, microsecond=315000))) set_specification = "anatomy_tool" status = 200 head = {"content-type": "text/xml"} @factory.lazy_attribute def uri(self): from_param = f"from={self.since:%Y-%m-%dT%H:%M:%SZ}" identity = quote(f"{from_param}&metadataPrefix=lom", safe="=&") \ if not self.resumption else f"resumptionToken={quote(self.resumption)}" return f"staging.edurep.kennisnet.nl/edurep/oai?{identity}&verb=ListRecords" @factory.lazy_attribute def request(self): return { "args": [self.set_specification, f"{self.since:%Y-%m-%dT%H:%M:%SZ}"], "kwargs": {}, "method": "get", "url": "https://" + self.uri, "headers": {} } @factory.lazy_attribute def body(self): response_type = "initial" if self.is_initial else "delta" response_file = f"anatomy-tool-oaipmh.{response_type}.{self.number}.xml" response_file_path = os.path.join(settings.BASE_DIR, "anatomy_tool", "fixtures", response_file) with open(response_file_path, "r") as response: return response.read() @classmethod def create_common_anatomy_tool_responses(cls, include_delta=False): cls.create(is_initial=True, number=0)
class ContractHistoryFactory(factory.django.DjangoModelFactory): class Meta: model = core.models.ContractHistory contract = factory.SubFactory(ContractFactory, is_active=False) meter = factory.SubFactory(MeterFactory) begin = factory.fuzzy.FuzzyDate( datetime.date(2000, 1, 1), datetime.date.today()) end = factory.Maybe( 'contract.is_active', yes_declaration=None, no_declaration=factory.fuzzy.FuzzyDate( datetime.date(2000, 1, 1), datetime.date.today()), )
def optional_declaration(declaration, chance=50, default=None): """ Used in DjangoModelFactories. Only sets a field value to "declaration" some of the time, otherwise sets it to "default". Useful for optional fields. """ decider = factory.LazyFunction( partial(fake.boolean, chance_of_getting_true=chance) ) return factory.Maybe( decider, yes_declaration=declaration, no_declaration=default, )
class Company(factory_trytond.TrytonFactory): class Meta: model = 'company.company' class Params: euro = factory_trytond.ModelData('currency', 'eur') party = factory.SubFactory(Party) currency = factory.Maybe( 'euro', factory.SelfAttribute('euro'), factory.SubFactory(Euro), )
class FoodFactory(factory.django.DjangoModelFactory): """Food factory.""" name = factory.LazyAttribute( lambda x: faker.sentence(nb_words=3, variable_nb_words=False)) description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10)) supermarket_category = factory.Maybe( factory.LazyAttribute(lambda x: x.has_category), yes_declaration=factory.SubFactory( SupermarketCategoryFactory, space=factory.SelfAttribute('..space')), no_declaration=None) recipe = factory.Maybe(factory.LazyAttribute(lambda x: x.has_recipe), yes_declaration=factory.SubFactory( 'cookbook.tests.factories.RecipeFactory', space=factory.SelfAttribute('..space')), no_declaration=None) space = factory.SubFactory(SpaceFactory) @factory.post_generation def users_onhand(self, create, extracted, **kwargs): if not create: return if extracted: for user in extracted: self.onhand_users.add(user) class Params: has_category = False has_recipe = False class Meta: model = 'cookbook.Food' django_get_or_create = ( 'name', 'space', )
class ProfileFactory(DjangoModelFactory): class Meta: model = 'hosting.Profile' django_get_or_create = ('user', ) exclude = ('generated_name', ) class Params: deceased = False with_email = False locale = None user = factory.SubFactory('tests.factories.UserFactory', profile=None) title = Faker('random_element', elements=["", MRS, MR]) generated_name = factory.LazyAttribute( lambda obj: LocaleFaker._get_faker(obj.locale).pystr_format( string_format='{{first_name}}//{{last_name}}')) first_name = factory.LazyAttribute( lambda obj: obj.generated_name.split('//')[0]) last_name = factory.LazyAttribute( lambda obj: obj.generated_name.split('//')[1]) names_inversed = False pronoun = Faker('random_element', elements=[ch[0] for ch in PRONOUN_CHOICES if ch[0]]) birth_date = Faker('date_between', start_date='-100y', end_date='-18y') death_date = factory.Maybe('deceased', yes_declaration=Faker('date_this_decade'), no_declaration=None) description = Faker('paragraph', nb_sentences=4) email = factory.Maybe('with_email', yes_declaration=Faker('email', safe=False), no_declaration="") @factory.post_generation def invalid_email(instance, create, value, **kwargs): instance._clean_email = instance.email if value and instance.email: instance.email = f'INVALID_{instance.email}'
class SubscriptionFactory(DjangoModelFactory): """Factory for Subscription""" user = factory.SubFactory(UserFactory) post_id = factory.Sequence(base36.dumps) comment_id = factory.Maybe( "is_comment", yes_declaration=factory.Sequence(base36.dumps), no_declaration=None, ) class Meta: model = Subscription class Params: is_comment = False
class UploadFactory(factory.alchemy.SQLAlchemyModelFactory): class Meta: model = Upload sqlalchemy_session_persistence = "commit" guid = factory.Faker("uuid4") title = factory.Faker("sentence", nb_words=5) file_name = factory.Faker("file_path", depth=3) description = factory.Faker("paragraph", nb_sentences=3) size = factory.LazyFunction(lambda: random.randint(0, 100_000)) measure_version_id = factory.Maybe( "measure_version", factory.SelfAttribute("measure_version.id")) # scalar relationships measure_version = None # Don't generate relationships 'towards' MeasureVersionFactory; see tests/README.md
class ShoppingListRecipeFactory(factory.django.DjangoModelFactory): name = factory.LazyAttribute(lambda x: faker.sentence(nb_words=5)) recipe = factory.Maybe(factory.LazyAttribute(lambda x: x.has_recipe), yes_declaration=factory.SubFactory( 'cookbook.tests.factories.RecipeFactory', space=factory.SelfAttribute('..space')), no_declaration=None) servings = factory.LazyAttribute(lambda x: faker.random_int(min=1, max=10)) mealplan = factory.SubFactory(MealPlanFactory, space=factory.SelfAttribute('..space')) space = factory.SubFactory(SpaceFactory) class Params: has_recipe = False class Meta: model = 'cookbook.ShoppingListRecipe'
class RecursiveFactory(factory.Factory): class Meta: model = RecursiveClass exclude = ('child_depth_temp', ) class Params: child_depth = 10 child_depth_temp = factory.LazyAttribute(lambda o: o.child_depth - 1) child = factory.Maybe( factory.LazyAttribute(lambda o: o.child_depth > 0), yes_declaration=factory.SubFactory( 'stock_setup_info.factory.RecursiveFactory', child_depth=factory.SelfAttribute('..child_depth_temp'), ), no_declaration=None, )
class MatomoVisitsResourceFactory(factory.django.DjangoModelFactory): class Meta: model = MatomoVisitsResource strategy = factory.BUILD_STRATEGY class Params: is_initial = True is_empty = False since = factory.Maybe( "is_initial", make_aware(datetime(year=2020, month=1, day=1)), make_aware( datetime(year=2020, month=2, day=10, hour=13, minute=8, second=39, microsecond=315000))) status = 200 head = {"content-type": "application/json"} @factory.lazy_attribute def uri(self): return f"webstats.surf.nl/?date={self.since:%Y-%m-%dT%H:%M:%SZ}%2C2021-12-12&" \ f"filter_offset=0&format=JSON&idSite=63&method=Live.getLastVisitsDetails&module=API&period=range" @factory.lazy_attribute def request(self): return { "args": [f"{self.since:%Y-%m-%d}"] if not self.is_initial else [], "kwargs": {}, "method": "get", "url": "https://" + self.uri, "headers": {}, "data": {} } @factory.lazy_attribute def body(self): if self.is_empty: return json.dumps([]) response_file_path = os.path.join(settings.BASE_DIR, "core", "fixtures", "matomo-visits.json") with open(response_file_path, "r") as response: return response.read()
class FolderFactory(factory.django.DjangoModelFactory): class Meta: model = Folder class Params: name_base = factory.Faker('word') name = factory.LazyAttributeSequence(lambda o, n: f'{o.name_base}-{n}') description = factory.Faker('paragraph') user_metadata = _metadata_faker parent = None tree = factory.Maybe( 'parent', factory.SelfAttribute('parent.tree'), # Make the new tree be created by (and use the quota of) this folder's creator factory.SubFactory(TreeFactory, creator=factory.SelfAttribute('..creator')), ) creator = factory.SubFactory(UserFactory)
class CaseFactory(factory.DjangoModelFactory): class Meta: model = Case client_name = factory.Faker('name') client_email = factory.LazyAttribute(lambda o: ( '*****@*****.**' % o.client_name).lower().replace(' ', '-')) client_phone = factory.fuzzy.FuzzyAttribute(fuzzer=phone_number_fuzzer) client_SID = factory.Faker('isbn10', separator="") incident_description = factory.LazyFunction( lambda: '<p>' + factory.Faker('paragraph').generate({}) + '</p>') open_date = factory.Faker('past_date', start_date="-1y") close_date = factory.Maybe('is_open', yes_declaration=None, no_declaration=factory.Faker('future_date', end_date="+180d")) divisions = factory.fuzzy.FuzzyAttribute(fuzzer=divisions_fuzzer) is_open = factory.fuzzy.FuzzyAttribute( fuzzer=lambda: bool(random.randint(0, 1))) @factory.post_generation def caseworkers(self, create, extracted, **kwargs): if extracted: caseworkers_by_division = defaultdict(lambda: []) for caseworker in extracted: caseworkers_by_division[caseworker.division].append(caseworker) for div in self.divisions: self.caseworkers.add( random.choice(caseworkers_by_division[div])) else: self.caseworkers.set( [PersonFactory.create(division=div) for div in self.divisions]) @factory.post_generation def intake_caseworker(self, create, extracted, **kwargs): if extracted: self.intake_caseworker = random.choice(extracted) @factory.post_generation def case_update_set(self, create, extracted, **kwargs): self.caseupdate_set.set( CaseUpdateFactory.create_batch(random.randint(1, 5), case=self))
class ShoppingListEntryFactory(factory.django.DjangoModelFactory): """ShoppingListEntry factory.""" list_recipe = factory.Maybe( factory.LazyAttribute(lambda x: x.has_mealplan), yes_declaration=factory.SubFactory( ShoppingListRecipeFactory, space=factory.SelfAttribute('..space')), no_declaration=None) food = factory.SubFactory(FoodFactory, space=factory.SelfAttribute('..space')) unit = factory.SubFactory(UnitFactory, space=factory.SelfAttribute('..space')) # # ingredient = factory.SubFactory(IngredientFactory) amount = factory.LazyAttribute( lambda x: Decimal(faker.random_int(min=1, max=100)) / 10) order = factory.Sequence(int) checked = False created_by = factory.SubFactory(UserFactory, space=factory.SelfAttribute('..space')) created_at = factory.LazyAttribute(lambda x: faker.past_date()) completed_at = None delay_until = None space = factory.SubFactory(SpaceFactory) @classmethod def _create( cls, target_class, *args, **kwargs ): # override create to prevent auto_add_now from changing the created_at date created_at = kwargs.pop('created_at', None) obj = super(ShoppingListEntryFactory, cls)._create(target_class, *args, **kwargs) if created_at is not None: obj.created_at = created_at obj.save() return obj class Params: has_mealplan = False class Meta: model = 'cookbook.ShoppingListEntry'
class UserFactory(factory.Factory): class Meta: model = User class Params: # Allow us to quickly enable staff/superuser flags superuser = factory.Trait( is_superuser=True, is_staff=True, ) # Meta parameter handling all 'enabled'-related fields enabled = True # Classic fields username = factory.Faker('user_name') full_name = factory.Faker('name') creation_date = factory.fuzzy.FuzzyDateTime( datetime.datetime(2000, 1, 1, tzinfo=UTC), datetime.datetime(2015, 12, 31, 20, tzinfo=UTC)) # Conditional flags is_active = factory.SelfAttribute('enabled') deactivation_date = factory.Maybe( 'enabled', None, factory.fuzzy.FuzzyDateTime( # factory.SelfAttribute('creation_date'), datetime.datetime.now().replace(tzinfo=UTC) - datetime.timedelta(days=10), datetime.datetime.now().replace(tzinfo=UTC) - datetime.timedelta(days=1), ), ) # Related logs creation_log = factory.RelatedFactory( UserLogFactory, 'user', action='create', timestamp=factory.SelfAttribute('user.creation_date'), )
class RoleFactory(ODPModelFactory): class Meta: model = Role exclude = ('is_collection_role', ) id = factory.Sequence(lambda n: id_from_fake('job', n)) is_collection_role = False collection = factory.Maybe( 'is_collection_role', yes_declaration=factory.SubFactory(CollectionFactory), no_declaration=None, ) @factory.post_generation def scopes(obj, create, scopes): if scopes: for scope in scopes: obj.scopes.append(scope) if create: Session.commit()
class EventFactory(factory.django.DjangoModelFactory): class Meta: model = "events.Event" class Params: has_store = factory.LazyAttribute( lambda o: o.event_type in EVENT_TYPES_ABOUT_STORE) event_type = factory.Faker( "random_element", elements=[choice[0] for choice in EVENT_TYPE_CHOICES]) description = factory.Sequence(lambda n: f"event_{n}") store = factory.Maybe( "has_store", yes_declaration=factory.SubFactory(StoreFactory), no_declaration=None, ) inventory_changes = factory.RelatedFactoryList( InventoryChangeFactory, factory_related_name="event", )
class MealPlanFactory(factory.django.DjangoModelFactory): recipe = factory.Maybe(factory.LazyAttribute(lambda x: x.has_recipe), yes_declaration=factory.SubFactory( 'cookbook.tests.factories.RecipeFactory', space=factory.SelfAttribute('..space')), no_declaration=None) servings = factory.LazyAttribute( lambda x: Decimal(faker.random_int(min=1, max=1000) / 100)) title = factory.LazyAttribute(lambda x: faker.sentence(nb_words=5)) created_by = factory.SubFactory(UserFactory, space=factory.SelfAttribute('..space')) meal_type = factory.SubFactory(MealTypeFactory, space=factory.SelfAttribute('..space')) note = factory.LazyAttribute(lambda x: faker.paragraph()) date = factory.LazyAttribute(lambda x: faker.future_date()) space = factory.SubFactory(SpaceFactory) class Params: has_recipe = True class Meta: model = 'cookbook.MealPlan'
class StructureTypeFactory(factory.DjangoModelFactory): structure_type_name = faker.text(max_nb_chars=10, ext_word_list=None) description = faker.sentence(100) is_active = faker.boolean(chance_of_getting_true=50) parent = factory.SubFactory( 'stock_setup_info.factory.StructureTypeFactory') class Meta: model = StructureType exclude = ('child_depth_temp', ) class Params: child_depth = 10 child_depth_temp = factory.LazyAttribute(lambda o: o.child_depth - 1) parent = factory.Maybe( factory.LazyAttribute(lambda o: o.child_depth > 0), yes_declaration=factory.SubFactory( 'stock_setup_info.factory.StructureTypeFactory', child_depth=factory.SelfAttribute('..child_depth_temp'), ), no_declaration=None, )
class PostFactory(ModerationObjectFactory): class Meta: model = 'blog.Post' django_get_or_create = ('title',) user = factory.Faker('random_element', elements=USER_MODEL.objects.filter(is_superuser=False)) category = factory.LazyAttribute(lambda o: CategoryTypes.get_random_choices()[0]) title = factory.Faker('sentence') feed_cover = factory.django.FileField( filename=factory.LazyAttribute( lambda o: f'{Post.feed_cover.field.name}_{randint(1000000, 9999999)}.jpg'), data=factory.LazyAttribute( lambda o: get_image_data(min_width=360, min_height=250, max_width=1024))) feed_article_preview = factory.Maybe( factory.LazyFunction(lambda: randrange(10) > 0), yes_declaration=factory.Faker('text', max_nb_chars=factory.LazyAttribute(lambda o: randint(200, 500))), no_declaration='') text = factory.LazyFunction(get_post_text) @classmethod def _after_postgeneration(cls, instance, create, results=None): if create: instance.tags.add(*get_tags(instance.category)) super()._after_postgeneration(instance, create, results)
class MetadataFactory(factory.django.DjangoModelFactory): name = factory.Faker('word') verbose_name = factory.Faker('word') description = factory.Maybe(factory.Faker('paragraph')) type = factory.Faker('random_element', elements=[ 'name', 'address' 'email', 'text', ]) @factory.post_generation def alternatives(self, create, extracted, **kwargs): if not create: return if extracted is not None: if extracted == []: return assert not extracted and not kwargs AlternativeFactory.create_batch(4, metadata=self) class Meta: model = Metadata
class PostFactory(DjangoModelFactory): """Factory for a channels.models.Post object""" author = SubFactory(UserFactory) channel = SubFactory(ChannelFactory) link_meta = factory.Maybe( factory.LazyAttribute(lambda post: post.post_type == LINK_TYPE_LINK), yes_declaration=SubFactory(LinkMetaFactory), no_declaration=None, ) post_id = factory.Sequence(base36.dumps) post_type = FuzzyChoice(VALID_EXTENDED_POST_TYPES) title = factory.Faker("text", max_nb_chars=50) text = factory.Maybe( factory.LazyAttribute(lambda post: post.post_type == LINK_TYPE_SELF), yes_declaration=factory.Faker("text", max_nb_chars=100), no_declaration=None, ) url = factory.Maybe( factory.LazyAttribute(lambda post: post.post_type == LINK_TYPE_LINK), yes_declaration=factory.Faker("url"), no_declaration=None, ) article = factory.Maybe( factory.LazyAttribute( lambda post: post.post_type == EXTENDED_POST_TYPE_ARTICLE ), yes_declaration=factory.RelatedFactory( "channels.factories.models.ArticleFactory", "post", # special case to support nullable author only on Post author=factory.LazyAttribute( lambda article: article.factory_parent.author or UserFactory.create() ), ), no_declaration=None, ) edited = False removed = False deleted = False num_comments = 0 class Meta: model = Post class Params: # this trait denotes what a comment that hasn't had data populated from reddit looks like unpopulated = factory.Trait( title=None, url=None, text=None, author=None, edited=None, removed=None, deleted=None, ) is_link = factory.Trait(post_type=LINK_TYPE_LINK) is_text = factory.Trait(post_type=LINK_TYPE_SELF) is_article = factory.Trait(post_type=EXTENDED_POST_TYPE_ARTICLE)
class MeasureVersionFactory(factory.alchemy.SQLAlchemyModelFactory): class Meta: model = MeasureVersion sqlalchemy_session_persistence = "flush" exclude = {"_creator", "_published", "_publisher", "_is_major_version"} # Underscored attributes are helpers that assist in the creation of a valid (business-logic-wise) measure version. _creator = factory.SubFactory(UserFactory) _published = factory.LazyAttribute(lambda o: o.status == "APPROVED") _publisher = factory.SubFactory(UserFactory) _is_major_version = factory.LazyAttribute( lambda o: o.version.endswith(".0")) # columns id = factory.Sequence(lambda x: x) measure_id = factory.SelfAttribute("measure.id") version = factory.LazyFunction(lambda: "1.0") latest = True # TODO: Add smarter logic review_token = factory.LazyAttribute( lambda o: generate_review_token(o.id) if publish_status[ o.status] >= publish_status["DEPARTMENT_REVIEW"] else None) description = factory.Faker("paragraph", nb_sentences=3) status = factory.LazyFunction( lambda: random.choice([status for status in publish_status.keys()])) created_at = factory.Faker("date_between", start_date="-30d", end_date="-7d") created_by = factory.SelfAttribute("_creator.email") updated_at = factory.Faker("past_date", start_date="-7d") last_updated_by = factory.SelfAttribute("_creator.email") published_at = factory.Maybe("_published", yes_declaration=factory.Faker( "past_date", start_date="-7d")) published_by = factory.Maybe( "_published", yes_declaration=factory.SelfAttribute("_publisher.email")) # We probably don't want to fake this attribute, as it is tied into a system that SQLAlchemy manages for us, # providing automatic version counting when UPDATE statements are issued against the row. If you try to set it # to anything other than `1` when creating an instance through the factory, SQLAlchemy resets it to 1 anyway. # So allowing it to be faked will probably be more confusing than useful. # db_version_id = factory.Sequence(lambda x: x) title = factory.Faker("sentence", nb_words=6) summary = factory.Faker("sentence", nb_words=10) need_to_know = factory.Faker("paragraph", nb_sentences=3) measure_summary = factory.Faker("paragraph", nb_sentences=3) ethnicity_definition_summary = factory.Faker("paragraph", nb_sentences=3) area_covered = factory.LazyFunction(lambda: _random_combination(UKCountry)) time_covered = factory.Faker("paragraph", nb_sentences=3) external_edit_summary = factory.Maybe("_is_major_version", yes_declaration="", no_declaration=factory.Faker( "sentence", nb_words=10)) internal_edit_summary = factory.Maybe("_is_major_version", yes_declaration="", no_declaration=factory.Faker( "sentence", nb_words=10)) update_corrects_data_mistake = factory.Maybe("_is_major_version", yes_declaration=False, no_declaration=random.choice( (True, False))) update_corrects_measure_version = None # Needs to be manually assigned if `update_corrects_data_mistake` is True lowest_level_of_geography_id = factory.SelfAttribute( "lowest_level_of_geography.name") methodology = factory.Faker("paragraph", nb_sentences=3) suppression_and_disclosure = factory.Faker("paragraph", nb_sentences=3) estimation = factory.Faker("paragraph", nb_sentences=3) related_publications = factory.Faker("paragraph", nb_sentences=3) qmi_url = factory.Faker("paragraph", nb_sentences=3) further_technical_information = factory.Faker("paragraph", nb_sentences=3) # scalar relationships measure = factory.SubFactory(MeasureFactory) lowest_level_of_geography = factory.SubFactory( LowestLevelOfGeographyFactory) # one-to-many relationships @factory.post_generation def uploads(self, create, extracted, **kwargs): # If some uploads were passed into the create invocation: eg factory.create(uploads=[upload1, upload2]) if extracted is not None: # Attach those uploads to this newly-created instance. for upload in extracted: self.uploads.append(upload) else: factory_method = _get_factory_generator_for_strategy( UploadFactory, create) factory_method(measure_version=self, **kwargs) @factory.post_generation def data_sources(self, create, extracted, **kwargs): # If some uploads were passed into the create invocation: eg factory.create(data_sources=[data_source1]) if extracted is not None: # Attach those uploads to this newly-created instance. for data_source in extracted: self.data_sources.append(data_source) else: factory_method = _get_factory_generator_for_strategy( DataSourceFactory, create) factory_method(measure_versions=[self], **kwargs) # By default, do not create any dimensions. See alternative factory, `MeasureVersionWithDimensionFactory` dimensions = factory.LazyFunction(lambda: [])
class SharekitMetadataHarvestFactory(factory.django.DjangoModelFactory): class Meta: model = SharekitMetadataHarvest strategy = factory.BUILD_STRATEGY class Params: set = "edusources" is_initial = True is_empty = False number = 0 is_restricted = False since = factory.Maybe( "is_initial", make_aware(datetime(year=1970, month=1, day=1)), make_aware( datetime(year=2020, month=2, day=10, hour=13, minute=8, second=39, microsecond=315000))) set_specification = "edusources" status = 200 head = {"content-type": "application/json"} @factory.lazy_attribute def set_specification(self): return "edusourcesprivate" if self.is_restricted else "edusources" @factory.lazy_attribute def uri(self): base = f"api.acc.surfsharekit.nl/api/jsonapi/channel/v1/{self.set_specification}/repoItems?" modified_parameter = quote( f"filter[modified][GE]={self.since:%Y-%m-%dT%H:%M:%SZ}", safe="=") page_size_parameter = quote("page[size]=25", safe="=") page_number_parameter = quote(f"page[number]={self.number+1}", safe="=") if self.number > 0: params = [ modified_parameter, page_number_parameter, page_size_parameter ] else: params = [modified_parameter, page_size_parameter] return base + "&".join(params) @factory.lazy_attribute def request(self): return { "args": [self.set_specification, f"{self.since:%Y-%m-%dT%H:%M:%SZ}"], "kwargs": {}, "method": "get", "url": "https://" + self.uri, "headers": {}, "data": {} } @factory.lazy_attribute def body(self): if self.is_empty: response_sequence = self.number response_type = "empty" elif self.is_initial: response_sequence = self.number response_type = "initial" else: response_sequence = 0 response_type = "delta" response_file = f"sharekit-api.{response_type}.{response_sequence}.json" response_file_path = os.path.join(settings.BASE_DIR, "sharekit", "fixtures", response_file) with open(response_file_path, "r") as response: response_string = response.read() # We modify the reference to the own link to indicate the link has restricted materials if necessary if self.is_restricted: return response_string.replace("/edusources/", "/edusourcesprivate/") return response_string @classmethod def create_common_sharekit_responses(cls, include_delta=False, is_restricted=False): cls.create(is_initial=True, number=0, is_restricted=is_restricted) cls.create(is_initial=True, number=1, is_restricted=is_restricted) if include_delta: cls.create(is_initial=False, number=0, is_restricted=is_restricted)